HOWTO: Use Different Node Templates by Node Variables (nid, type, view)

Profile picture

Tags: drupal, howto

With node template files you are often limited to something like node.tpl.php and node-blog.tpl.php. Often times it'd be nice to make a different template for just one specific node or a different template for teaser/list view and full node view.

Using the PHP code below, Drupal will look for these template files, split by page or no page view. This gives more fine grained control over your node tpl.php files.

Page view:

1) node-[nid]-page.tpl.php
   Node by itself on a page, specific NID
2) node-[type]-page.tpl.php
   Node by itself on a page, specific type
3) node-default-page.tpl.php
  Node by itself on a page, default

Listing/Teaser view:

4) node-[nid].tpl.php
   Node in list/teaser, specific NID
5) node-[type].tpl.php
   Node in list/teaser, specific type
6) node.tpl.php
   Node in list/teaser, default.

*UPDATE* Earl Miles has shown this can be done much simpler than what I had previously. Revised code below.

Place this code in your template.php file in your theme's directory.

<?php
function _phptemplate_variables($hook, $vars = array()) {
  switch (
$hook) {
    case
'node':
     
// Here is the way to switch to a different node-<something> template based on node properties.
     
if ($vars['page']) {
       
// This is LIFO (Last In First Out) so put them in reverse order, i.e
        // most important last.
       
$vars['template_files'] = array('node-default-page', 'node-'. $vars['node']->type .'-page', 'node-'. $vars['node']->nid .'-page');
      }
      else {
       
$vars['template_files'] = array('node-'. $vars['node']->nid);
      }
      break;
  }

  return
$vars;
}
?>

Comments

Here's the Drupal 6 version, with a preprocess function:

/**
* Override or insert variables into the node templates.
*
* @param $vars
*   An array of variables to pass to the theme template.
* @param $hook
*   The name of the template being rendered ("node" in this case.)
*/
function pokeronline_preprocess_node(&$vars, $hook) {
  switch ($hook) {
    case 'node':
      // Here is the way to switch to a different node- template based on node properties.
      if ($vars['page']) {
        // This is LIFO (Last In First Out) so put them in reverse order, i.e
        // most important last.
        $vars['template_files'] = array('node-default-page', 'node-'. $vars['node']->type .'-page', 'node-'. $vars['node']->nid .'-page');
      }
      else {
        $vars['template_files'] = array('node-'. $vars['node']->nid);
      }
    break;
  }
}

hi ,

I used the above function phptemplate_preprocess_page for my drupal6 site and found that the .template page runs and when i print

print ' ghfghgf';
print htmlspecialchars(print_r(get_defined_vars(), TRUE), ENT_QUOTES);
print ''; in .tpl.php page

,the variables i added did not appear in my html page ,
is it because the function is not overwriting the default variables or am i using the wrong variables

please guide me

Thank you.

Nice explanation.

Very similar things can be done with blocks, regions ...
See http://drupal.org/node/104319

I also changed the fallback for the page view to node-default-page.tpl.php since node-page.tpl.php overlaps with the "page" node style.

Thanks Earl! I didn't know $vars['template_files'] was available for the node case. I've updated the main post.

While I haven't tested this directly, something along these lines should do the trick just as well and be even easier.

<?php
function _phptemplate_variables($hook, $vars = array()) {
  switch (
$hook) {
    case
'node':
     
// Here is the way to switch to a different node-<something> template based on node properties.
     
if ($vars['page']) {
       
// This is LIFO (Last In First Out) so put them in reverse order, i.e
        // most important last.
       
vars['template_files'] = array('node-page', 'node-'. $vars['node']->type .'-page', 'node-'. $vars['node']->nid .'-page');
      }
      else {
       
vars['template_files'] = array('node-'. $vars['node']->nid);
      }
      break;
  }

  return
$vars;
}
?>

Add comment

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <br> <br/> <br /> <p> <img> <blockquote> <i> <b> <u>
  • Lines and paragraphs break automatically.
  • You may post code using <code>...</code> (generic) or <?php ... ?> (highlighted PHP) tags.
  • Web page addresses and e-mail addresses turn into links automatically.

More information about formatting options