Archive for December, 2007

Contextual node templates

Dec 24 2007 Published by Inferis under drupal

For a site I’m developing in Drupal, I have a specially made content type to present some news items. That works fine, but I needed a way to represent those items differently. A newsitem is represented by node of type “news”.

There’s also a view defined on the newsnodes, which displays the correct news items (the site uses the Multidomain module, but that is beyond the scope of what I’m getting to).

Now, I wanted to display a list of items with just the title and the date on the homepage, I also wanted a little more elaborate list on /last-minutes and finally a full fledged page with all info (for each item).

At first glance, I didn’t find a way to do it properly. I didn’t want to make more views, as I didn’t want to update all 3 of them (ALL 3 OF THEM, teh horrors), and also I found that the table/list views you can create were a bit too little flexible to my taste.

The solution is actually pretty simple: you can have different template sources by setting the $vars[’template_files’] in your template.php file. By hooking into the node vars, you can create “contextual” template files:

function _phptemplate_variables($hook, $vars) {
  $css = drupal_add_css();
  unset($css['all']['module']['modules/system/system.css']);
  unset($css['all']['module']['modules/system/defaults.css']);
  unset($css['all']['module']['modules/node/node.css']);
  unset($css['all']['module']['modules/user/user.css']);
  unset($css['all']['module']['modules/cck/fieldgroup.css']);
  unset($css['all']['module']['modules/cck/content.css']);
  $vars['styles'] = drupal_get_css($css);

  switch ($hook) {
    case 'node':
    	if (!isset($vars['path']) || drupal_lookup_path('alias', $_GET['q']) != $vars['path']) {
    		if ($_SERVER['REQUEST_URI'] == '/') {
    			$context = '-front';
    		}
    		else {
    			$context = str_replace('/', '-', str_ireplace('.php', '', $_SERVER['REQUEST_URI']));
    		}
	        $vars['template_files'] = array('node-'. $vars['type'] . '-in' . $context);
    	}
    	break;
  }

  return $vars;
}

As you can see, that’s not very hard. If the node were observing has no path or the path is different from the page path (in other words, we’re viewing the node as it’s embedded in a view), we then figure out the context (which is the path name of the page). Slashes are replaced by hypens, of course. For the index page, the “front” context is used as a special case.

And so I can have 3 different template files for a news node:

  • node-news-in-front.tpl.php renders my list of newsitems on the homepage
  • node-news-in-lastminutes.tpl.php renders the more elaborate list in the /lastminutes page
  • node-news.tpl.php renders the normal node view

Spiffy, isn’t it?

iTunes » Kadril & AlumeaUterus

No responses yet