Switching Drupal tpl.php files at will: Old Switchy McTipplefep's Trick

10.03.2009


One of the first lessons they teach you at the School of Drupal Arts, Arcane Sciences and Sorcery is that a tpl.php can have dynamically generated wildcards or "suggestions". You can see this every day drupal themes: you can simply use the "node.tpl.php" file if you want only one style for a node. Where as if you want different styles for three node types: blog, story & page, you create the following files:

  • node-page.tpl.php
  • node-story.tpl.php
  • node-blog.tpl.php

Obviously, this pattern exists far beyond nodes. For page.tpl.php, user/register can have its own tpl.php file:

  • page-user-register.tpl.php

Where as user/1/edit will be (yes -- these suggestions will remove numbers... i think... i was hung over that day in class):

  • page-user-edit.tpl.php

This may be fine and dandy if your agenda is either to build a simple drupal theme with a few exceptions, or to build manly Texas sized drupal themes with enough tpl.php files, and duplicate html code to choke a donkey.

Old Switchy McTipplefep's trick is for anyone who:

  • wants 3 styles that are shared by 20 blocks
  • wants 4 possible layouts for dozens of pages in a site
  • has 12 node types, but wants them to share 3 styles

The magic happens in your theme's $theme_name . '_preprocess_' . $theme function. Below are examples for how a theme named "example" would do it.

function example_preprocess_node(&$vars) {
  $node = $vars['node'];
 // only switch for story type
  switch($node->type) {
    case 'story':
      $vars['template_files'][] = 'node-batman';
      break;
  }
}

function example_preprocess_block(&$vars) {
  // sure why not -- we'll pass our node.tpl.php file to our block
  // That's how tpl pimpin works sometimes
  $vars['template_files'][] = 'node-batman';
}

Comments

Sweet! I've used this to

Sweet! I've used this to create a pseudo-skinner, allowing someone creating a node to select what design template they'd like to have applied to their node with a simple cck select list, and then doing a node_load in the above function to load the value of that field and use that to load the specified template.

so THAT's why you were

so THAT's why you were searching google images for "old hillbilly" :P

The example is indeed not

The example is indeed not perfect. This should work:

<?php
function example_preprocess_node(&$vars) {
 
$node = $vars['node'];
// only switch for story type
 
switch($node->type) {
    case
'story':
     
$vars['template_files'][] = 'node-batman';
      break;
  }
}

function example_preprocess_block(&$vars) {
 
// sure why not -- we'll pass our node.tpl.php file to our block
  // That's how tpl pimpin works sometimes
 
$vars['template_files'][] = 'node-batman';
}
?>

I just changed the switch statement.

sorry, i don't see the

sorry, i don't see the difference.

Goes to show me that i

Goes to show me that i shouldn't write example code without testing it.

Just curious. What is

Just curious. What is animal/thing the man in picture holding? Any pointer where you got that picture?

Actually don't know where it

Actually don't know where it was found. A twitter reader sent it to me in response to this: http://twitter.com/nicklewisatx/status/4569729290

I think it's a snapping

I think it's a snapping turtle, but it's got a lot of stuff on its shell that makes it look like a very dirty ball of twine.

Should be switch($node->type)

Should be switch($node->type) I believe.

It's in the example (or was

It's in the example (or was edited in, heh) --

<?php
$node
= $vars['node'];
?>

Lately, I've been trying to

Lately, I've been trying to create different CSS rules, according to specific pages. For example, I'd like the navigation tabs for a page titled "About Us" to have a different color than tabs on a page titled "Contact Us."

I thought I might do this by creating separate tpl.php files, according to the title of the page; for example, page-about-us.tpl.php. Alas, I've not been able to figure this out, nor find info on it. Does anyone happen to know how to do this? Nick?

Cheers.

You don't need to go as deep

You don't need to go as deep as the .tpl.php files for this. You can use body classes to do this, so in your example the about us page should (or could depending on your base theme) have a style called 'page-about-us'. See Zen for a theme that does this out of the box.

Once you have pages which you can target specifically you can write styles which do what you are talking about. e.g.

body.page-about-us ul.tabs li { color: red; }
body.page-contact-us ul.tabs li { color: green; }

Thanks a lot, fellow "passing

Thanks a lot, fellow "passing drifter," this method worked great. Go here for the details--updated for D6:

http://drupal.org/node/32077

There are some problems in

There are some problems in your example. In example_preprocess_node, $vars is the only local variable. Where does $node come from?

$vars['node']

$vars['node']

Post new 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>
  • You may post code using <code>...</code> (generic) or <?php ... ?> (highlighted PHP) tags.
  • Lines and paragraphs break automatically.
  • Web page addresses and e-mail addresses turn into links automatically.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.