I am trying to create a Drupal module. I've been able to setup the configuration form on the admin section - it runs fine: I can add the component and set configurations and save.
However, nothing appears on the front end of the site. There are no errors. I'm not sure why and, as I am new to Drupal, I'm not sure where to look.
My hook_theme in my .module file looks like:
function gallery_grid_theme($existing, $type, $theme, $path) {
return array(
'gallery_grid' => array(
'template' => 'gallery-grid',
'path' => 'plugins/content_types/gallery_grid/templates',
'type' => 'theme',
'variables' => [],
)
);
}
The .tpl file is intact and has no markup errors.
Would anyone know what file I should be looking at?
EDIT:
I've tried clearing the cache and rebuilding the registry as well as disabling and re-enabling the module, to no affect.
The module is added to a page panel as a component (gear icon, Add Content).
For some reasons this needed an absolute path:
'path' => drupal_get_path('module', 'gallery_grid') . '/plugins/content_types/gallery_grid/templates',
Related
What I'm looking to do is create a very basic plugin for Wordpress. I've followed countless tutorials and examples, but haven't found anything close to what I'm looking for.
I'm trying to create something simple where it has a link on the admin nav bar, and just shows some static html on the right side of the page. The public wouldn't see anything at all.
This sounds like a simple task, but so far, has been everything but simple. Any help or pointing in the right direction would be appreciated. :)
Create a folder named helloworld in your plugins folder and add a file called helloworld.php. In your PHP file, use a hook to add the link to the admin menu.
<?php
/*
Plugin Name: Hello World
*/
add_action('admin_bar_menu', 'add_navbar_item', 100);
function add_navbar_item($admin_bar){
$admin_bar->add_menu( array(
'id' => 'my-item',
'title' => 'My Item',
'href' => '#',
'meta' => array(
'title' => __('My Item'),
),
));
}
I have a custom Drupal 7 module which is hooking into the media module and I'm having trouble with adding some js into its render.
The module is defining a theme like this:
function media_flash_theme($existing, $type, $theme, $path) {
return array(
'media_flash_video' => array(
'variables' => array('uri' => NULL, 'options' => array()),
'file' => 'media_flash.theme.inc',
'path' => $path . '/includes/themes',
'template' => 'media-flash',
)
);
}
And my formatter (view) is returning my element like so:
$element = array(
'#theme' => 'media_flash_video',
'#uri' => $file->uri,
'#options' => array(),
);
return $element;
Now, I have a preprocess function which adds some js:
function media_flash_preprocess_media_flash_video(&$variables) {
$path = libraries_get_path('swfobject');
drupal_add_js($path . '/swfobject.js');
...
}
And also a drupal add js in my template file:
/**
* #file media_flash/includes/themes/media-flash.tpl.php
*/
$javascript = '
(function ($) {
...
})(jQuery);
';
drupal_add_js($javascript, 'inline');
The issue is weird. When I'm logged in then everything works fine, all the time. However, when I am using it as an anonymous user it all works fine the first load (after cache clear) but then the two javascripts arent added anymore.
I have tried to change my preprocess function so it adds the javascript with this $variables['scripts'] = drupal_get_js(); but this also has the same behaviour.
Ive googled around a bit and found some suggestions but nothing's worked thus far. Any help is appreciated.
Thanks,
EDIT: So I looked into this a bit more and the code is being executed through the filter module. It seems as though the first time it gets executed it gets cached and then it is just recieved from the cache each time after that, so the drupal_add_js code isn't run again.
Is there a way around this caching or do I need to remove my js from this part all together?
You can always add the js in the page level "hook_page_alter(&$page)"
I am using the Meta Box plugin for Wordpress. I can successfully create fields in the cms for users to upload images. I would like to extend this in two ways:
First, I would like a delete confirmation when users remove an image from the image gallery
Here is the code:
$meta_boxes[] = array(
'id' => 'project_media',
'title' => 'Project Media',
'pages' => array( 'project' ),
'context' => 'normal',
'priority' => 'high',
'fields' => array(
array(
'name' => 'Media Gallery',
'desc' => 'Images should be sized to 983px x 661px',
'id' => $prefix . 'project_media_gallery',
'type' => 'image'
)
);
This creates upload functionality in the custom post type where users can add images to a slideshow. The problem is if the user accidentally clicks the delete button, there is no confirmation to make sure it is deleted. Can I somehow extend the plugin through functions and call an alert when this button is clicked? Something that does not involve editing the WP core?
Second, the base functionality requires the user to upload an image from their local machine. Is there a way to tap into the Media Library for this?
No idea how to even start tackling this one.
To answer the first question
First, I would like a delete confirmation when users remove an image from the image gallery
You can do that by calling a custom script file from the functions.php.
function alert_delete() {
if(is_admin()){
wp_register_script( 'alert_delete', get_bloginfo('template_url'). '/js/alert_delete.js', array('jquery'));
wp_enqueue_script('alert_delete');
}
}
and create a file named alert_delete.js in the js directory of your theme.
alert_delete.js:
// admin delete check
jQuery(document).ready(function(){
jQuery(".rwmb-delete-file").click(function() {
if (!confirm("Are you sure? This process cannot be undone.")){
return false;
}
});
});
In response to the second question...
Second, the base functionality requires the user to upload an image
from their local machine. Is there a way to tap into the Media Library
for this?
Get the latest version of the Meta Box Plugin first.
then change
'type' => 'image'
to
'type' => 'image_advanced'
which will allow you to upload from the existing Media Gallery or a new file from your computer.
I am having a hard time understanding what hook_theme() does.
My understanding is that it has something to do with making it possible to override templates.
I was looking at:
$theme_hooks = array(
'poll_vote' => array(
'template' => 'poll-vote',
'render element' => 'form',
),
'poll_choices' => array(
'render element' => 'form',
),
'poll_results' => array(
'template' => 'poll-results',
'variables' => array('raw_title' => NULL, 'results' => NULL, 'votes' => NULL, 'raw_links' => NULL, 'block' => NULL, 'nid' => NULL, 'vote' => NULL),
),
'poll_bar' => array(
'template' => 'poll-bar',
'variables' => array('title' => NULL, 'votes' => NULL, 'total_votes' => NULL, 'vote' => NULL, 'block' => NULL),
),
);
Could you provide an example of how it works?
It provides a place for a module to define its themes, which can then be overridden by any other module/theme. It will also provide the opportunity for any module to use a hook such as mymodule_preprocess_theme_name to change the variables passed to the eventual theme function or template file.
There are basically two ways to initialise a theme function:
theme('poll_results', array('raw_title' => 'title', 'results' => $results, etc...));
and
$build = array(
'#theme' => 'poll_results',
'#raw_title' => 'title',
'#results' => $results,
etc...
); // Note the '#' at the beginning of the argument name, this tells Drupal's `render` function that this is an argument, not a child element that needs to be rendered.
$content = render($build); // Exact equivalent of calling the previous example now that you have a render array.
Please keep in mind, you should avoid calling theme() directly (per the documentation in theme.inc) since it:
Circumvents caching.
Circumvents defaults of types defined in hook_element_info(), including attached assets
Circumvents the pre_render and post_render stages.
Circumvents JavaScript states information.
In Drupal 8, theme() is a private function, _theme(). For more detail, please see www.drupal.org/node/2173655.
When you compare the two of these to the poll_results element in the example you give above you can probably work out what's happening...since PHP is not a strongly typed language Drupal is providing 'named arguments' through either a keyed array passed to the theme function, or as hashed keys in a render array.
As far as 'render element' is concerned, this basically tells the theme system that this theme function will be called using a render array, with one named argument (in this case form). The code would look something like this:
$build = array(
'#theme' => 'poll_choices',
'#form' => $form
);
This will pass whatever's in the $form variable to the theme function as it's sole argument.
Regarding the template key:
'poll_vote' => array(
'template' => 'poll-vote',
'render element' => 'form',
)
defines a theme called poll_vote which uses a template file (hence the template key) with a name of 'poll-vote.tpl.php' (this is by convention). The path to that template file will be found by using the path to the module that implements it (e.g. modules/poll/poll-vote.tpl.php), so it's fine to put template files in sub-folders of the main module folder.
There are two ways to actually return the output for a theme function, by implementing the physical function name (in this case it would be theme_poll_vote) or by using a template file. If the template key is empty Drupal will assume you've implemented a physical function and will try to call it.
Template files are preferable if you have a fair bit of HTML to output for a theme, or you simply don't like writing HTML in strings inside PHP (personally I don't). In either case though, the variables passed when you call the theme (either using theme() or a render array as described above) are themselves passed through to the template file or theme function. So:
function theme_poll_results(&$vars) {
$raw_title = $vars['raw_title'];
$results = $vars['results'];
// etc...
}
If you were using a template file instead for the same method the variables would be available as $raw_title, $results, etc, as Drupal runs extract on the $vars before parsing the template file.
I'm sure there's a lot I've missed out here but if you have any more specific questions ask away and I'll try to help out.
Drupal 6
I was stuck all day with this and now successfully implemented, so sharing my finding here, may it will help understand hook_theme.
There are 3 steps involved:
hook_theme
function YOURMODULENAME_theme() {
return array(
'xxx_xxx' => array(
'template' => 'xxx-xxx', // define xxx-xxx.tpl.php inside module
'arguments' => array('xxx' => null), //define $xxx so it will available in your xxx-xxx.tpl.php
),
);
}
echo/return the theme in your .tpl or any .module
$output = theme('xxx_xxx', $xxx);
Now variable are magically available in you xxx-xxx.tpl.php.
<?php echo $xxx ?>
Note: you can pass $xxx as array,object or anything :)
There is yet another way: (can be found in Bartik theme)
The scenario here is that we have created our own module and want to override the default output for let's say a node with title 'zzz' only.We don't know and don't really care how the default output is generated. All we need is to tell Drupal to use our own custom template file (node--custom--name.tpl.php) to render that specific node.
These are the steps:
Tell Drupal where our template file lives. (Keep in mind that this function will take effect only once and after clearing Drupal's cache):
// Implements hook_theme()
function mymodulename_theme() {
$theme = array();
$theme['node__custom__name'] = array(
'render element' => 'node',
'template' => 'path_from_mymodule_root/node__custom__name',
);
return $theme;
}
Tell Drupal where and when to use it
//Implements hook_preprocess_node()
function mymodulename_preprocess_node($vars) {
if($vars['node']->title == 'zzzz') {
$vars['theme_hook_suggestions'][] = 'node__custom__name';
... your other code ...
}
}
Now Drupal will use our template file for that specific case only, provided that 'node--custom--name.tpl.php' file is in the declared path, otherwise it will keep searching according to the suggestions naming conventions for a fallback template.
Drupal 7 hook_menu() is confusing me; I have tried everything and I can't seem to get this to work.
What I need: In a custom module, I'd like to create a new menu, and add about four links to that menu. It sounds simple, but I am struggling. I've been able to create the menu itself using the $menu array in the .install file, but adding items to that menu doesn't make sense.
Code that is working:
$menu = array(
'menu_name' => 'project-menu',
'title' => $t('Project Menu'),
'description' => 'Project Menu',
);
menu_save($menu);
Code that isn't working:
$items = array();
$items['project-menu/%'] = array(
'title' => 'Test Link',
'page callback' => 'dc_project_page',
'page arguments' => array(1),
'access callback' => TRUE,
'type' => MENU_LOCAL_TASK,
);
return $items;
This is all in the dc_project.install file under the dc_project_menu() function. Hopefully I'm just doing something stupid, any and all help is extremely appreciated. Even just pointing to me to a module that does this cleanly as an example, thanks. I did look at the example project, haven't been able to get anything as far as adding links to my new menu working.
Passing to menu_save() the content of $items doesn't work because menu_save() accepts only an array containing menu_name, title, and description.
What you use in $items is an array describing the menu callbacks implemented by a module, and the definitions of the menu callbacks implemented by all the modules are not saved in "menu_custom" (the table used from menu_save()) but are cached in a Drupal cache table.
If you are trying to change the menu callbacks defined by another module, then you should implement hook_menu_alter(); otherwise, if you just want do define the menu callbacks of your module, you should implement hook_menu().
Both the hooks implementations (hook_menu() and hook_menu_alter()) must be in the module file (in your case, in dc_project.module), not in dc_project.install. Drupal doesn't load the installation file when it normally loads the enabled modules; it loads the installation file when a module is being updated (or installed), but it doesn't load it in other cases.
The code that saves the menu with menu_save() can be in the installation file, in the implementation of hook_install() or hook_update_N(). It could also be put in the implementation of hook_enable(); in that case, the code (which is executed when the module is enabled) should first verify the menu has not been already added. (hook_enable() and hook_disable() should be placed in the installation file.)