Community Documentation

Setting up variables for use in a template (preprocess and process functions)

Last updated March 31, 2013. Created by ultimateboy on February 18, 2008.
Edited by chrisjlee, inventlogic, drupalshrek, Delfio2d2. Log in to edit this page.

The main role of the preprocessor is to set up variables to be placed within the template (.tpl.php) files. From Drupal 7 they apply to templates and functions, whereas in Drupal 6 preprocess functions only apply to theming hooks implemented as templates. Plain theme functions do not interact with preprocessors.

Notes:

  • Preprocessors are also used for providing template suggestions.
  • In versions 5 and below, the function _phptemplate_variables served the same purpose. It has been deprecated in 6.
  • Prior to Drupal 6.7, for your theme to have its preprocessors recognized, the template associated with the hook had to exist inside the theme. When a default template exists, copy it to your theme and clear the registry (or you should really be upgrading to a later version of Drupal anyway for security reasons, at which point you don't have to worry about this).

There can be numerous preprocessors for each theming hook. Every layer from core, modules, engines and themes can have one, each progressively building upon the variables before being rendered through template files. This keeps the markup clean and easy to work with inside templates by placing most of the logic inside these preprocessors.

Here are the expected preprocessors. They are run in this order when they exist:

  1. template_preprocess Drupal 6
    template_preprocess Drupal 7
    This is supplied by core and always added. The variables generated here are used for every templated hook.
  2. template_preprocess_hook
    The module or core file that implements the theming hook supplies this. The initial generation of all the variables specific to the hook is usually done here.
  3. moduleName_preprocess
    Do not confuse this with the preprocessor before it. This allows modules that did not originally implement the hook to influence the variables. Applies to all hooks.
  4. moduleName_preprocess_hook
    Same idea as the previous preprocessor but for specific hooks.
  5. engineName_engine_preprocess
    - The preprocessor for theming engines. Applies to all hooks.
  6. engineName_engine_preprocess_hook
    Another preprocessor for theming engines but specific to a single hook.
  7. engineName_preprocess
    NOT RECOMMENDED. This is the first preprocessor that can be used inside the theme. It can be named after the theme engine the theme is running under. Applies to all hooks.
  8. engineName_preprocess_hook
    NOT RECOMMENDED. Another preprocessor named after the engine but specific to a single hook.
  9. themeName_preprocess
    This one is named after the theme itself. Applies to all hooks.
  10. themeName_preprocess_hook
    Same as the previous preprocessor but for a specific hook.

There are many possibilities here for modifying the variables. In most cases, it is only the first two preprocessors that exist. The first adds the default baseline variables and the second adds a set specific to the theming hook. Contributed modules taking advantage of the preprocessor slots (3 & 4) should document their behavior. It will not be covered extensively here.

While it is possible, the default PHPTemplate does not inject itself to this list. (5 & 6)

Themes can start adding their preprocessors seventh in the list. The preprocess function should be added to the theme's template.php file. However, due to the problems listed below, it is recommended that themes use their own names as the prefix (9 & 10). It is possible to grow this list beyond the ten shown above by having sub-themes add preprocessors strictly through their theme name as it is shown in the last two examples.

A few notes:

  • There is an unfortunate design flaw/bug in the theme system when a theme is part of a base theme/sub-theme hierarchy. Any preprocess functions prefixed with engineName_preprocess will be run multiple times (once for each theme in the hierarchy) instead of just once. Not only is this wasting resources, it can also cause difficult-to-debug errors.
  • The theme name (9 & 10) should always be used for themes. This minimizes any chance of a sub-theme redeclaring a function with an engineName_preprocess prefix and causing fatal PHP errors due to duplicate functions.

Note that nothing should be returned from these functions and the variables have to be passed by reference indicated by the ampersand before variables, e.g., &$variables.

Since the variables set early on are run through all the latter preprocessors due to references, be careful that you do not inadvertently reset any added before your theme. It is fine to reset them, but doing so accidentally can keep you guessing on what went wrong.

Example set from a module implementing the hook of "foo":

<?php
function template_preprocess_foo(&$variables) {
 
$variables['foo_list'] = array(
   
'list item 1',
   
'list item 2',
   
'list item 3',
  );
}
?>

And the preprocessor created from the theme to add to the variable set above:

<?php
function drop_preprocess_foo(&$variables) {
 
// Do not do this unless you mean to:
 
$variables['foo_list'] = array('list item 4');
 
 
// Instead do this:
 
$variables['foo_list'][] = 'list item 4';
}
?>

The variables that end up in the template file are the keys set within $variables. So, with the above example, the variable in the template would result in $foo_list.

When using a preprocessor not specific to a theming hook, a second parameter can be used which always passes the current hook. Using a more specialized preprocess function like the one shown above is easier to maintain but if there will be shared code for multiple theming hooks, you may want to opt for this instead.

<?php
function drop_preprocess(&$variables, $hook) {

 
// Shared between the 'foo' and 'bar' theming hooks.
 
if ($hook == 'foo' || $hook == 'bar') {
   
$variables['foobar_item'] = 'foobar item';
  }

 
// Specific to 'foo'.
 
if ($hook == 'foo') {
   
$variables['foo_item'] = 'foo item';
  }
 
// Specific to 'bar'.
 
elseif ($hook == 'bar') {
   
$variables['bar_items'] = 'bar item';
  }
}
?>

In Drupal 7, there are two sets of variable process functions. The first is the existing "preprocess" functions. The second is "process" functions which are run after preprocessors. All the various prefixes and suffixes apply to this second phase in the exact same way. This is useful when certain variables need to be worked on in two phases. For example, adding classes into an array for the "preprocess" phase then flattening them into a string in the "process" phase, so it's ready to print within a template.

Related HowTos and code snippets:

Comments

Process function signature

A preprocess functions signature needs to be

[yourModuleName|yourThemeName]_preprocess_[themeFunctionName](&$variables)

The following is useful
http://stackoverflow.com/questions/2383865/how-do-i-use-theme-preprocess...

I have been asked in the irc

I have been asked in the irc to leave comments about the documentation and tutorial.
I am goin through the documentation one by one, started from overview of the themes.
in this page starts talking about hooks.
questions in my head is now:
what is hook? where it should be placed? where can i find them and override it if i should.
where should I find preprocessors for each module??
it might be explained somewhere, somehow but it is not clear... I think it is better to revise the order of the topics.
this is personal opinion as a new drupal developer.

I was in IRC with shv_rk and

I was in IRC with shv_rk and user23 discussing the information on this page. Shv_rk wanted to create a variable to use in a template file and landed on this page. The information on this page was very confusing to her. She was not able to find the needed information and did not know how to make a preprocess function after reading it.

  • The topic needs a clear introduction on preprocess hooks. The current introduction already assumes knowledge of preprocess hooks. What does a preprocess function do? What is this useful for?
  • The information that is really important to themers is buried deep in the page. Like the fact that the functions need to be added to template.php - this is somewhere half way down the page in the middle of a paragraph
  • Provide a real example, using a real existing hook, and an existing theme (Garland), step by step. This is the most important thing for a new user. From the template.php to the .tpl.php. For example: template_preprocess_user_profile
  • The talk about 'foo' hooks is confusing because this is an abstraction, it's better to use existing hooks in the examples.
  • All the grisly details about the order in which preprocess functions are handled should be more towards the bottom of the page. The most important thing is get the user up and running.
  • Provide links to the theme hook documentation.
  • Explain that the caches need to be cleared after making changes to template.php.

not new to drupal but still confused

Hello, i've been using drupal now for a year and made some great sites with it, but this whole hooks and preprocessor thing still gets me confused. And i can't seem to really find any documentation to help. This is the "best" article i can find, but it still leaves me more confused than helped.

Here are some of my questions that I am still left with:

* are function hooks used in modules the same as theme hooks used in the theme?

* if a contrib module uses a "hook" is this something i can over-ride or extend in my theme?

* if a contrib module uses a hook, say: hook_block() can I then hook the hook to change the module's output?

example:

inside the contribmodule.module file:

contribmodule_block() { $variables['foobar_item'] = 'foobar item'; }

can this be overriden by the following in the template.php file?

contribmodule_preprocess_block() { $variables['foobar_item'] = 'new item'; }

* where is the documentation on preprocess? or on module hooks? i can't find it and i can't seem to search for it. Is there a guide for all the fundamental concepts? All i can find is the API for hooks, but that says really nothing at all about it other than giving a list of available hooks; zero theory there.

* if a contrib module has a function which I can NOT override with a hook onto a hook, then how do i change what the contrib module does for my theme? am i forced to hack the code of the contrib module?

* intuitively it feels like changing a contrib module is not part of theming, but more of module extending / modifying, but it is also theme-specific, so it's confusing to know if this topic is indeed related to the above or not.

* what is really missing in the documentation is the fundamental concepts explained from start-to-finish NOT broken down per area of interest [admin, theming, developing] but just rather how this whole system ties together so that if i want to understand anything about it, i know where to go and i can find it. The api should be more for code snippets AND examples of using the code [which are severely lacking in the API docs as they generally have zero examples]. I should be able to understand how a page is built step-by-step from the documentation and each step should point me to a page that describes that part in further detail.

* it is very hard to search documentation because your search only searches ALL documentation, rather than sections. If your guides used a standard URL structure like:

drupal.org/guides/development/[title]
drupal.org/guides/theming/[titile]

then I could search in specific guides very easily like this:

google query:

site:http://drupal.org/guides/development hooks
or
site:http://drupal.org/guides/theming hooks

but as such I have to search all of google as many of your pages are still node/[NID] or content/[title]

If someone replies to this, thank you for your help in providing clarification and considering my suggestions for the documentation.

p.s. it should be standard practice to always write which file a snippet of code comes from, all too often I see some code but no mention if it is an example that goes into template.php, tpl.php, modulename.module or some other file... that makes understanding examples extra complicated for beginners.

Merging Technology with Creativity
Fountain City Productions
http://fountain-city.com

Hello, Your article helped me

Hello,

Your article helped me a lot, but there was something incomplete.

Actually, what gave me a headache was that following your example, all I got was "Array" displayed on my page.

The good syntax I used in Drupal 6 was :

<?php
function template_preprocess_foo(&$vars) {
 
// populate $var_to_fill
 
$vars['foo_item'] = $var_to_fill;
}
?>

$vars['foo_item'][] = $var_to_fill or $vars['foo_item'] = array($var_to_fill) just gave me the message "Array".

But $vars['foo_item'] = $var_to_fill works like a charm.

Fairly new to Drupal and am really confused...

Hello guys,

I am using the Omega theme framework and I would really like to create a custom date format. my question and confusion is where do I write this? and where does this live? is it a php file with function writing between

<?php

?>
?

Thanks any help would be much appreciated.

Thank you,

Matt

create a custom date format.

You can create easily custom date formate using php.

<?php
function ago($timestamp) {

   
$difference = time() - $timestamp;

 
$periods = array("second", "minute", "hour", "day", "week", "month", "years", "decade");

 
$lengths = array("60", "60", "24", "7", "4.35", "12", "10");

  for(
$j = 0; $difference >= $lengths[$j]; $j++)

   
$difference /= $lengths[$j];

      
$difference = round($difference);

       if (
$difference != 1)

        
$periods[$j].= "s";

      
$text = "$difference $periods[$j] ago";

  return
$text;

}
?>

There are $timestamp is a variable where u pass you date-time in unix formate or use php date formate.

For reference:
http://php.net/manual/en/function.date.php

Dilip Singh
Sr. Software Professional
(Web Developer)
Mobile No. +919212881307
New Delhi - 110001

preparing variables for printing in templates

If in the preprocess or process function, you have $variables['name']='some html string', then in the template file, print $name will result in the string being inserted. I think you could also do print $variables['name'] to get the same result.

How can one see which hooks

How can one see which hooks are there? For instance, a list per page what hooks get called in correct order. Is that possible?

Simplest change doesn't work

I'm trying to define a new variable that I can display in my node.tpl.php . I'm using theme scaccarium and Drupal 6 (which still has better i18n support than 7).

I opened that theme's template.php . I didn't find a scaccarium_preprocess_node function, so I created one. This function is very simple, for test purposes.

function scaccarium_preprocess_node(&$vars) {
  $vars['test'] = "Testing";
  $vars['node']['test'] = "Testing";
}

In the template's node.tpl.php I have added

<span class="test"><?php print $test ?></span>

This gives an empty span. How the heck am I supposed to define variables???

Clear the cache.

Clear the cache.

Try like

Try like this:

<?php
$vars
['node']->test = "Testing";
?>
nobody click here