Separating _phptemplate_variables()

Recently there was a post on the [development] mailing list about dealing with _phptemplate_variables() and in order to get it all straight in my head, I thought it prudent to report on it here for my and your benefit.

The thread started out somewhat unrelated, but perked my attention when HowTo: merge multiple _phptemplate_variables functions was mentioned by Anton. The title is pretty self explanatory, so I won't go into detail, but it reminded me of how we're dealing with massive amounts of conditional $vars[] within our _phptemplate_variables() function on Musicbox.

I'd also be remiss if I didn't mention HowTo: Emulate "preprocess" theme functions in Drupal 5. Though I don't yet know the specifics of Drupal 6's preprocessing of theme functions, I plan to read up and post about that as a follow-up to this topic. This article was definitely more akin to the technique Nate Haug came up with for us on Musicbox.

At first our _phptemplate_variables() function switched on the $hook argument that is passed into the function and we had a case for page, node, user-profile, comment and block. The node case was further checked by $vars['node']->type in order to have separate variables for the each content type. As you can imagine, this became very long and very tedious to scroll down through and to find where to put any new logically created variables.

So Nate came up with the ingenious solution to separate the vars, much like the tpl files are separated. He took about 300 lines of code inside of template.php down to less than 30 with the following technique:

<?php
function _phptemplate_variables($hook, $vars = array()) {
  global
$user;

 
// Setup some 'global' theme variables.
 
$vars['user'] = $user;
 
$vars['path'] = base_path() . path_to_theme() .'/';
 
$vars['admin'] = $user->roles[3] || $user->uid == 1 ? TRUE : FALSE;
 
$vars['moderator'] = $user->roles[4] ? TRUE : FALSE;
 
$vars['editor'] = $user->roles[5] ? TRUE : FALSE;
 
$vars['authenticated'] = $user->uid ? TRUE : FALSE;
 
$vars['theme'] = 'myplay_theme';

 
// Include broad variables for each hook.
 
if (file_exists($vars['directory'] .'/'. $hook .'.vars.php')) {
    include_once
$vars['directory'] .'/'. $hook .'.vars.php';
   
$function = $vars['theme'] .'_variables_'. str_replace('-', '_', $hook);
   
$vars = $function($vars);
  }

 
// Specific variables for node types.
 
if ($hook == 'node') {
    if (
file_exists($vars['directory'] .'/node-'. $vars['node']->type .'.vars.php')) {
      include_once
$vars['directory'] .'/node-'. $vars['node']->type .'.vars.php';
     
$function = $vars['theme'] .'_variables_node_'. $vars['node']->type;
     
$vars = $function($vars);
    }
  }

  return
$vars;
}
?>

So while we still have our regular template files (node-story.tpl.php) we also have our vars files (node-story.vars.php) which house the specific variable logic for that particular type. Inside of these vars files, the variable logic is defined within a function called function [your_theme]_variables_[hook]($vars) for hooks like "page" (i.e. page.vars.php has a function called myplay_theme_variables_page($vars) within it) and function [your_theme]_variables_node_[type]($vars) for the specific content types.

Comments

good work

good work

Great Post

This code doesn't work for me

Brilliant!

I dealt with it before simply by breaking it up into more functions, but this dynamic variable including is really elegant.

Great Info

You've got some great information all over your site, thanks much for post! Will be back...

Post new comment

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options