Different page templates depending on node type
The list of "template suggestions" for a template can be modified in your template.php file. The following snippet will add page template suggestions for node type for the current page. That allows you to, for example, define a page-nodetype-news.tpl.php template which would apply to every page that displays a "news" node type.
<?php
// Add additional template suggestions
function _phptemplate_variables($hook, $vars) {
switch ($hook) {
case 'page':
// Add page template suggestions based on node type, if we aren't editing the node.
if ($vars['node'] && arg(2) != 'edit') {
$vars['template_files'][] = 'page-nodetype-'. $vars['node']->type;
}
break;
}
return $vars;
}
?>If you are using the Zen theme, look in your sub-theme’s template.php file and uncomment the SUBTHEME_preprocess_page() function and add the following code (without the <?php and ?> tags):
<?php
// Add page template suggestions based on node type, if we aren't editing the node.
if ($vars['node'] && arg(2) != 'edit') {
$vars['template_files'][] = 'page-nodetype-'. $vars['node']->type;
}
?>Additions
- Working with template suggestions
- Preprocess functions
For a drupal 6 equivalent, see:
- The snippet below (to be inserted in template.php) should be able to theme your templates by nodetype (page-nodetype.tpl.php)
page by nodetype in Drupal 6
function phptemplate_preprocess_page(&$variables) {
if ($node = menu_get_object()) {
$variables['node'] = $node;
$suggestions = array();
$template_filename = 'page';
$template_filename = $template_filename . '-' . $variables['node']->type;
$suggestions[] = $template_filename;
$variables['template_files'] = $suggestions;
}
}IMPORTANT NOTE: If this is not working be sure to clear the theme registry. To access: http://yoursite.com/admin/settings/performance/
"Clear Cached Data" button at bottom of page (Drupal 6).
Added the note in this awesome snippet below:
function phptemplate_preprocess_page(&$variables) {
// IF THIS IS NOT WORKING BE SURE TO CLEAR THE THEME REGISTRY.
// FAILURE TO DO SO WILL NOT ALLOW THIS FUNCTION TO BE CALLED.
if($node = menu_get_object()) {
$variables['node'] = $node;
$suggestions = array();
$template_filename = 'page';
$template_filename = $template_filename . '-' . $variables['node']->type;
$suggestions[] = $template_filename;
$variables['template_files'] = $suggestions;
}
}Special thanks to Aaron of In the Loft Studios.

This didn't work for me
There are some problems with the function given above:
1)
$variables['node'] = $node;sets the value of $variables['node'] to 1. As a result, there is nothing in $variables['node']->type.2)
$variables['template_files'] = $suggestions;resets the $variables['template_files'] array, thereby hosing any suggestions already provided by core.3) If your homepage happens to be set, for example, to a particular node of type 'abc,' the suggestion to use page-abc.tpl.php overrides the page-front.tpl.php suggestion, which can be problematic.
This function does work for me, though:
function phptemplate_preprocess_page(&$variables) {if ($variables['is_front'] != 1) {
$variables['template_files'][] = 'page-' . $variables['node']->type;
}
}
This handbook isn't correct I
This handbook isn't correct I think....
$variables['template_files']Is none-existent in my setup....
$vars['template_files']...is though!
Cheers
________________
Live fast die young
That's a difference between
That's a difference between D5 and D6.
:-( Doesn't seem to work for me either
Though new to Drupal (D6), I understand what is trying to be achieved here.
I want to up a page into regions differently, depending on the node type.
So I thought, great this is exactly what I want.
But when I implement this I don't get it processing my suggested template .
I even tried fixing the template name such that eveything would use 1 temmplate, just not page.tpl.php.
It just carrys on regardless to the default/generic .tpl's
Help !?
Am I using the wring product, I want a relatively simple, hierarchic site, that lists children as the sub-menu.
With a couple of 2 3 or 4 col pages for the content (some are plainly candidates for 'views').
I can't help but think this seems to be like pulling teeth !
D6.14
Improving my skills with every page-turn
It works... Read the
It works...
Read the instructions CAREFULLY.
It didn't work for me for a while until I realised the filenaming is different for D6 and D5. (I have D5 and D6 sites using this)
marcopolo ---
Blog Marco | Best Designed Drupal Websites
it messes page-node-edit?
zbricoleur, i follow your code, but i've got a problem, and I don't know if its related to your saying "hosing any suggestions already provided by core", since i manage to have my template for a specific content type, "page-contentype.tpl.php" , but then it overrides "page-node-edit.tpl.php"... any clue?
Try this...
Change this
if ($variables['is_front'] != 1) {to this
if ($variables['is_front'] != 1 && arg(2) != 'edit') {Sorry I don't have time to test it, but that should work...
This snippet ist not working
Hi there,
the snippet provided here is not working for me on Drupal 6.
But the old method for Drupal 5 described here http://drupal.org/node/17565 does exactly what this function tries to and works on Drupal 6!
Correct code for drupal 6
In drupal 6, you can add a template file with the preprocess_page function. (See http://drupal.org/node/223440 for details on how to correctly use $variables['template_files'], the code used for this documentation page is both excessively complex and incorrect.)
<?php
function phptemplate_preprocess_page(&$variables) {
$variables['template_files'][] = 'page-'. $variables['node']->type;
}
?>
Unfortunately this places the page-nodetype suggestion before the individual page selection, so I added just a little bit more code to fix this:
<?php$template_files = array();
foreach ($variables['template_files'] as $file) {
$template_files[] = $file;
if ($file == 'page-node') {
$template_files[] = 'page-'. $variables['node']->type;
}
}
$variables['template_files'] = $template_files;
?>
re: Correct code for drupal 6 -- location?
hi,
> so I added just a little bit more code to fix this
where exactly does this second snippet go in templates.php? particularly wrt the 1st snippet?
also, given this naming convention ... since I'm already using an alternate frontpage template, "page-front.tpl.php", will there be any conflict with that existing, Drupal-default filename?
thanks!