Adding a custom themable variable in theme_preprocess_page - drupal

I have read the docs over and over trying to wrap my head around this seemingly simple task. Basically, I have a template with a 'skip navigation' div hard-coded in html.tpl.php that I do not want on front-page.
My idea was to set a $vars['skiplink'] variable in theme_preprocess_page. Since this variable contains a few lines of html markup, I was aiming for something as seen in garland theme:
function garland_preprocess_page(&$vars) {
// Move secondary tabs into a separate variable.
$vars['tabs2'] = array(
'#theme' => 'menu_local_tasks',
'#secondary' => $vars['tabs']['#secondary'],
);
<snip>
I would like to have the html in a themable function or even a template, but I cannot even get this snippet to work:
/**
* Override or insert variables into the page template.
*/
function morin_preprocess_page(&$vars) {
// add skiplink markup
$vars['skiplink'] = 'hello world';
}
This generates a notice:
Notice : Undefined variable: skiplink in include() (ligne 14 in /var/dev/morin/www/sites/all/themes/morin/templates/html.tpl.php).
Can anyone slap me with a clue? I would really like to understand how to do this with both methods, ( template & function ). I'm also wondering if this should be done in a module?
I realise there are probably 10 ways to skin this cat, so any insights on pros/cons of methods used are welcome.
Ok I figured out I was using the wrong preprocess function, setting $vars['skiplink'] in preprocess_html is the way to go for top-level variables.I still have yet to figure out in a clear way how to associate this variable to a template file.

The preprocess hooks follow this pattern:
<theme name>_preprocess_<template name>
So if you want to modify the variables for "html.tpl.php" you want to use this hook:
<theme name>_preprocess_html(&$variables)

You are using preprocess_page but you are inserting the variable in the html.tpl.php.
You should either insert it in the page.tpl.php or rename your preprocess function, to add the variable to the html.tpl.php
And remember to clear cache if you didn't have the preprocess function defined already.
Update:
You seem to be missing a key point. Preprocess functions (along with the actual theme call) is how you make variables accessible in templates. Different preprocess functions are called for different templates, (..._page for page.tpl.php etc.)
Do you still have problems after using the correct preprocess function and clearing cache?

Related

Buddypress plugin Group Hierarchy

Buddypress has a group functionality in which I combined with the plugin BP Group Hierarchy so that I can create an hierarchy of groups based on user role.
However, the plugin used an method as taught by Buddpress in group-extension-api> link.
The group steps are registered using the function bp_register_group_extension and add_action are called. I tried to remove the action by with no success. Because I not really understand how the array works i.e. array( &$extension, \'_register\' ), so I go search out and found this post.
There's a line stating that
The new format for the above object referenced method callbacks are always: class name, followed immediately by the method name, followed by the amount of previously added (classname+methodname). For classes, this allows you to add as many object referenced classes and add methods which don’t override each other.
However I can't seems to be able to remove the action.
I tried to remove the action by putting following lines of code in function.php
function remove_bp_hierarchy(){
if (has_action('bp_actions')) {
echo $extension = new BP_Groups_Hierarchy_Extension;
remove_action('bp_actions', array( &$extension, '_register' ), 999);
} else {
}
add_action('bp_init','remove_bp_hierarchy', 999);
Is it something wrong with my remove_action or I use wrong method? Thanks and regards.
## Update
Found a page in which let we see a list of hooks and also hooked function in the page. I see that there's a function with the name _register which is the function I'm looking for. However, class address always change. I was thinking using the function found to do a preg_match on it and remove it when it found. this is super heavy. So is there other way of removing it? Thanks and Regards.
CodingBabyDotCom -
Long story short: you will have to traverse the $wp_filter array to remove the action.
You need a reference to the SAME instance that was used to create the action in order to remove it with the remove_action function. So the function you posted doesn't work because it is using a new instance.
Unfortunately bp_register_group_extension() creates only a temporary instance, so it can't be referenced by later functions.
The code in your comment will remove ALL actions at level 8, which means all group extensions. To remove only the one you want, iterate over each filter and check its type with:
is_a( $wp_filter['bp_actions'][8][$key], 'BP_Groups_Hierarchy_Extension' )

Drupal 7 preprocess_views not working

I have the following code in my Drupal 7 template.php file:
function mytheme_preprocess_views_view__videos__videos(&$vars) {
drupal_add_css(drupal_get_path('theme', 'mytheme') . "/css/qwembed-jquery-1.0.css");
drupal_add_js(drupal_get_path('theme', 'mytheme').'/js/jquery.swfobject.1-1-1.min.js', array('type' => 'file', 'scope' => 'footer'));
drupal_add_js(drupal_get_path('theme', 'mytheme').'/js/qwembed-jquery-1.0.js', array('type' => 'file', 'scope' => 'footer'));
}
I need to load these css and js file only when this view is displayed.
the view display name is: Videos
the view Machine Name is: videos
and the override files are:
views-view--videos--videos.tpl.php
views-view-unformatted--videos--videos.tpl.php
views-view-fields--videos--videos.tpl.php
any ideas why this is not working?
The problem is likely that you try to implement a preprocess function based on the same naming pattern as used for template overrides. But preprocess functions are a bit different in that by default, they can only be implemented based on the name of the 'base' template, and do not have the same mechanism for 'specific' versions based on template suggestions. See my answer to a more generic question for details.
So you'd need to fall back to implementing the 'base' preprocess function, and check if it gets called for the desired view (and optionally display) within that function, roughly like so:
function [yourThemeName]_preprocess_views_view(&$vars) {
$view = $vars['view'];
if ('videos' == $view->name) {
// Add desired manipulations for all 'videos' views
if ('videos' == $view->current_display) {
// Add desired manipulations for the 'videos' display only
}
}
}
You could also add the behavior you expected by implementing a generic preprocess function that tries to call specific versions by checking for functions with the proper name - see the end of this article for an example - but this introduces quite some processing overhead and would only make sense, if you need specific preprocess functions for many views.
There are more 'base' preprocess functions per view type that you can implement directly - see the list of template_preprocess_views_view_* in 'views/theme/theme.inc' for the available options.
As a base rule, whenever there is a template_preprocess_* function for a template, you can implement a corresponding yourThemeOrModuleName_preprocess_* function as well. If you need to manipulate for templates based on template name suggestions, you need to find the 'base' preprocess function name, implement that and check for your specific case in that function (like for the specific view as in the example above).

module_invoke_all not returning all modules

I'm creating a module wich provides a separate node overview page for each content type.
My problem lies in trying to recreate the node operations dropdown.
In the node module this is done by calling the module_invoke_all function with the 'node_operations' hook.
This returns an array of all modules that implement the 'node_operations' hook.
In my case the following two modules: 'node' and 'nodewords'.
When I call module_invoke_all('node_operations') in my module, it returns only the 'nodewords' module, not the 'node' module.
This is because the 'node_node_operations' function does not exist.
Can anyone explain this behavior?
It looks like the hook is in node.admin.inc, which is not automatically included. See http://api.drupal.org/api/drupal/modules--node--node.admin.inc/function/node_node_operations/7
This is imho a bug, you should look if there already is an issue and if not, create a new one.
Anyway, as a workaround, you can include the node.admin.inc file like this before calling the hook:
<?php
module_load_include('inc', 'node', 'node.admin');
?>
(Yeah, weird syntax ;))

Confused about theme function calls

I've created a content type that has a CCK text field.
When I select the text field using the Drupal Themer widget it tells me the last function called was
theme_text_formatter_default() , which I found in the CCK text.module
It also tells me that it's parents were;
content-field.tpl.php < theme_markup < theme_markup < node.tpl.php < page.tpl.php
So I assumed that somewhere in the content-field.tpl.php was the function call to theme('text_formatter_default',$element) but it wasn't in there. Just print $item['view'] used to display the content.
I searched all the project files for theme('text_formatter_default',$element) and it doesn't exist. I know it's being called by the theme function as I override it in my template.php and it used my overridden function, which would only happen if was using the theme_hook$. Wouldn't it?
So how is it being called? It's not that I need to override it. I'm just learning how drupal works and thought I had it sussed until this. Something must be calling it.
Also, the function theme_text_formatter_default exists in the theme registry and it's overridable (if that's a word) as I did so in my template.php and it displayed. It's all quite confusing.
Any help would be much appreciated
It's CCK that calls the theming function.
When you create a CCK field you select a widget. The widget corresponds to a theming function that is called. That's the short explaination.
To understand the entire mechanics will be a bit difficult as creating a cck field is a complex subject lacking good documentation.
To really understand what, how and why, you would need to understand how the CCK module works internally. Probably to the point where you could write patches for it. Something very few people could help you with.
Edit:
I don't know the CCK module in depth, I have only created my own field formatters. Anyways, I looked though the db and found that the table content_node_field_instance holds info about each CCK field, one of the columns is widget which it seems, is where CCK stores which theming function to call. It knows what function to call because if the naming convention that is used and through the implementation of hook_field_formatter_info, which is what other modules uses when they want to tell CCK about how to theme a field.
The function is defined in text.module. the theme function that matches the entry text_formatter_default returned from the implementation of hook_theme()istheme_text_formatter_default()`.
/**
* Theme function for 'default' text field formatter.
*/
function theme_text_formatter_default($element) {
return ($allowed =_text_allowed_values($element)) ? $allowed : $element['#item']['safe'];
}

How do I use theme preprocessor functions for my own templates?

I have several .tpl.php files for nodes, CCK fields, and Views theming. These template files have a lot of logic in them to move things around, strip links, create new links, etc. I understand that this is bad development and not "The Drupal Way".
If I understand correctly, "The Drupal Way" is to use preprocessor functions in your template.php file to manipulate variables and add new variables. A few questions about that:
Is there a naming convention for creating a preprocessor function for a specific theme? For example, if I have a CCK field template called content-field-field_transmission_make_model.tpl, how would I name the preprocessor function?
Can I use template preprocessor functions for node templates, CCK field templates, and Views templates? Do they have different methods of modifying template variables or adding new ones?
For a general overview, you should read up on manipulating variables within preprocess functions.
Concerning the naming convention, this is normally pretty simple, but there is a catch for your current example (see below):
A preprocess functions signature needs to be
[yourModuleName|yourThemeName]_preprocess_[themeFunctionName](&$variables)
so implementing one for the page template within a themes template.php file would result in
themeName_preprocess_page(&$variables)
Most of the time the name of the theme function will be the name of the *.tpl.php file, without the .tpl.php ending and with underscores instead of the hyphens. But there is a catch if the template file gets selected on the base of template suggestions, as the preprocess function can only be implemented for the base name, not for the additional suggestions! (The suggestions for alternate template files are added in preprocess functions themselves.)
Your current example is one of those cases, as content-field-field_transmission_make_model.tpl.php is such a suggestion, with the base name being content-field.tpl.php, and the corresponding theme function being content_field. So you would have to implement a preprocess function named yourThemeName_preprocess_content_field(&$variables), and within that inspect the available entries in the $variables array to check if you are actually called for the 'field_transmission_make_model', and not for a completely different CCK field, e.g.:
function yourThemeName_preprocess_content_field(&$variables) {
// Are we called for the right field?
if ('field_transmission_make_model' == $variables['field_name']) {
// Yes, add/manipulate entries within the variables array
$variables['new_entry'] = 'A useless new variable';
$variables['label'] = 'A useless change of the existing label variable';
}
}
(Note: Untested code, beware of typos)
After this, there should be a new variable $new_entry being available in your template file, and the content of the $label variable should have changed (all top level entries within the $variables array will be turned into separate variables for the template file, named after the array index).
As for your second question, the basic usage of preprocess functions is the same for all template files, but be aware:
Preprocess functions are only available for theme calls that use *.tpl.php files, not for theme functions
The content of the $variables array varies heavily, depending on what gets themed
Other modules might implement the preprocess functions as well, and they will be called one after another, so if you want to change something that gets added by another module, you can only do so if your implementation gets called after that (which will be no problem in your case, as implementations within a theme are called after all implementations within modules - just wanted to mention that there can be many implementations at once)
In order to figure out what our preprocessing function should be named, we need to know what template file or theme function some output comes from, and one great way to do this is by using the theme developer module.
Here is a video which explains it in detail - http://buildamodule.com/video/drupal-theming-essentials-template-files-theme-function-overrides-and-preprocessing-functions-how-to-use-simple-preprocessing-functions

Resources