HOWTO: Utilize Drupal 6-style Theme Architecture in Drupal 5

3

August 16, 2008 - 1:11am

Tags :

Once of the biggest advances "under the hood" in Drupal 6 is the addition of the preprocess architecture to the theme layer. This is part and parcel with the deeper embedding of template files, and together they render Drupal 6 the most flexible and powerful release yet in terms of theme and design. For those of us who still do a fair amount of work with the 5.x branch, it's easy to be envious of those lucky enough to have these new tools at their disposal. But resist that cardinal sin! This quick HOWTO explains how to quickly turn your theme into a node-preprocessing machine, which has great benefits in terms of elegant architecture, and also future-proofing your work for the eventual Drupal 6.0 migration.

Bulding off _phptemplate_vars()
Possibly the most powerful programmatic tool in the Drupal themer's toolkit in 5.0 is the _phptemplate_vars() function. We've talked before about to use this to use different template files under different circumstances. Overall, this function is a great way to make all those minor changes that are needed so that a site can have truly top-notch appearance and user-interface.

However, once your theme gets to be very complex, this function can easily become an overloaded beast of logical branches. Each new node type or special case creating new complexity, and maintaining that as your site grows can quickly become untenable. Fear not, though. You can also use this function to implement a simple preprocessing architecture that will help you customize the data in all your node types without creating a mass of template files, and set the table for 6.0. Here's how:

<span style="color: #000000"><span style="color: #0000BB"><?php<br /></span><span style="color: #007700">function </span><span style="color: #0000BB">_phptemplate_variables</span><span style="color: #007700">(</span><span style="color: #0000BB">$hook</span><span style="color: #007700">, </span><span style="color: #0000BB">$vars </span><span style="color: #007700">= array()) {<br />  switch (</span><span style="color: #0000BB">$hook</span><span style="color: #007700">) {<br />    case </span><span style="color: #DD0000">'node'</span><span style="color: #007700">:<br />      </span><span style="color: #0000BB">$node </span><span style="color: #007700">= </span><span style="color: #0000BB">$vars</span><span style="color: #007700">[</span><span style="color: #DD0000">'node'</span><span style="color: #007700">]; </span><span style="color: #FF8000">// handy shorthand<br />      </span><span style="color: #0000BB">$preprocess </span><span style="color: #007700">= </span><span style="color: #DD0000">'phptemplate_'</span><span style="color: #007700">. </span><span style="color: #0000BB">$node</span><span style="color: #007700">-></span><span style="color: #0000BB">type </span><span style="color: #007700">.</span><span style="color: #DD0000">'_node_vars'</span><span style="color: #007700">;<br />      if (</span><span style="color: #0000BB">function_exists</span><span style="color: #007700">(</span><span style="color: #0000BB">$preprocess</span><span style="color: #007700">)) {<br />        </span><span style="color: #0000BB">call_user_func</span><span style="color: #007700">(</span><span style="color: #0000BB">$preprocess</span><span style="color: #007700">, </span><span style="color: #0000BB">$vars</span><span style="color: #007700">);<br />      }<br />      break;<br />    case </span><span style="color: #DD0000">'page'</span><span style="color: #007700">:<br />     ...<br />  }<br />}<br /><br />function </span><span style="color: #0000BB">phptemplate_blog_node_vars</span><span style="color: #007700">(&</span><span style="color: #0000BB">$vars</span><span style="color: #007700">) {<br />  </span><span style="color: #FF8000">// your custom preprocessing here<br />  </span><span style="color: #0000BB">$node </span><span style="color: #007700">= </span><span style="color: #0000BB">$vars</span><span style="color: #007700">[</span><span style="color: #DD0000">'node'</span><span style="color: #007700">]; </span><span style="color: #FF8000">// handy shorthand<br />  </span><span style="color: #0000BB">drupal_add_css</span><span style="color: #007700">(</span><span style="color: #0000BB">$vars</span><span style="color: #007700">[</span><span style="color: #DD0000">'directory'</span><span style="color: #007700">]. </span><span style="color: #DD0000">'/custom_blog_style.css'</span><span style="color: #007700">);  <br />  </span><span style="color: #0000BB">$vars</span><span style="color: #007700">[</span><span style="color: #DD0000">'submitted'</span><span style="color: #007700">] = </span><span style="color: #0000BB">t</span><span style="color: #007700">(</span><span style="color: #DD0000">'Blogged by !name on !date'</span><span style="color: #007700">, array(</span><span style="color: #DD0000">'!name' </span><span style="color: #007700">=> </span><span style="color: #0000BB">l</span><span style="color: #007700">(</span><span style="color: #0000BB">$node</span><span style="color: #007700">-></span><span style="color: #0000BB">name</span><span style="color: #007700">, </span><span style="color: #DD0000">'user/'</span><span style="color: #007700">. </span><span style="color: #0000BB">$node</span><span style="color: #007700">-></span><span style="color: #0000BB">uid</span><span style="color: #007700">), </span><span style="color: #DD0000">'!date' </span><span style="color: #007700">=> </span><span style="color: #0000BB">format_date</span><span style="color: #007700">(</span><span style="color: #0000BB">$node</span><span style="color: #007700">-></span><span style="color: #0000BB">created</span><span style="color: #007700">, </span><span style="color: #DD0000">'custom'</span><span style="color: #007700">, </span><span style="color: #DD0000">'m-d-Y'</span><span style="color: #007700">)));<br />}<br /></span><span style="color: #0000BB">?></span></span>

Note that you don't need to use phptemplate_ as the prefix here; indeed it may be advisable to use your theme_name.

What this function does is quickly check for the existence of a node-specific preprocessing function, and if it exists passes through the $vars array by reference. In this case we detect that a blog node is being rendered, and take the opportunity to include a final custom stylesheet form our theme, as well as altering the standard $submitted var.

The possibilities here are endless, and in "enterprise theming" situations where you may be dealing with upwards of 25 (or even 100!) node types, having this kind of programatic structure in your theme is invaluable for keeping things clean, elegant and extensible. Good luck, and happy drupal theming!

Comments

Here's another approach from the handbook (not by me): http://drupal.org/node/201587

Your way is nice if you have a lot of different variables on a per type basis, though.

Michelle

That's a nice link though, as it will set you up with exactly the same function names you want.

My code isn't really a faithful implementation of the default preprocess functions from D6, but more like an inspiration based on dealing with a lot of node types and needing to keep template.php sane. ;)

FYI, the Zen theme for D5 supports preprocessors natively for D5. No funky code required. See http://drupal.org/node/193318. The documentation is outstanding.

Post a comment

To prevent automated spam submissions leave this field empty.
CAPTCHA
Let us know you're human by typing in this code. The code is case sensitive.
Image CAPTCHA
Enter the characters shown in the image.