Theming Views In Drupal 6.x

Practical tips for theming views in Drupal 6

Photo of Greg Harvey
Wed, 2008-09-03 23:48By greg

Who remembers good ol' Views 1.x in Drupal 5.x? Lovely, wasn't it? With that theming wizard. Giving you all the phptemplate functions you needed for fine-grained theming, ready to paste in to template.php in your theme and fiddle with until everything looks perfect.

Well, that was then. Many of you, like me, may have been looking at the latest version, 6.x-2.0, and scratching your heads when it comes to theming. Sure, the new Views UI is fantastic. And for basic (or non-developer) theming the new view tpl files are a great idea. In fact, theming with Views templates is not even basic. You can do nearly anything.

HOWEVER...

...for very complex theming tasks the chances are you'll need to create a tpl file for your view and *every* *field*. The system is fantastic if you want to maybe theme the overall view and a couple of fields, and most people will never need anything else, but any more than that in terms of theming requirements and it starts to become unweildy. Still perfectly workable, but unweildy nevertheless. I'm working on a project at the moment which makes me yearn for the old ways. I have dozens of views, each one needing fine-tuned bespoke theming, which means dozens and dozens of tpl files, potentially.

I really didn't like the idea of that, even though you can apparently order tpl files in sub-folders in Drupal 6.x without there being any performance overhead (caching cleverness there). So I started picking the Views code apart for an alternative, largely because I stubbornly refused to believe the Views developers would have removed such a handy way of theming and replaced it with nothing. And they haven't. But they won't talk about it (and with good reason - read on).

The first thing of interest I discovered was a function called _views_theme_functions() in the theme.inc file that ships with Views 2.x. This function appeared to provide a bunch of dynamically generated theme functions which can be over-ridden in template.php. Armed with that possibility, my colleague Graham started searching the Internet for a solution, and came up with this: http://www.agileapproach.com/blog-entry/theming-views-drupal-6

It's not wholly accurate (see my post here) but it's a great starting point. In fact, I pitched in a feature request asking for it to be added to the documentation.

Which is when the Views maintainer, 'merlinofchaos', jumped in and said "No!" - firmly, but politely. He makes several valid points and suggestions in afforementioned feature request which are well worth reading, and guided me in the direction of better understanding the Drupal 6.x theming system before hacking too far in to the Views module.

Enter preprocess functions. While that page explains them to a degree, it rather implies that modules and/or themes effectively create the environment for tpl files to exist. This is true to an extent, but a tpl file does not have to have a preprocess function shadowing it. A subtlety I had missed until now.

The Views module is an excellent example of this. There are several preprocess functions within the Views module which are generic but have specific purposes. One is called template_preprocess_views_view() and it is responsible for generating *all* view tpl files with filename in the form views-view--my-view-name.tpl.php. Another, template_preprocess_views_view_list(), acts upon all variations of views-view-list--my-view-name.tpl.php, etc. You get the idea.

Usually, given the documentation about preprocess functions, a tpl file with a name in the form of views-view--my-view-name.tpl.php would mean you might expect to find, in a module somewhere, a preprocess function called template_preprocess_views_view__my_view_name(), but with Views you won't find one, because the function handling that tpl file is the generic one, template_preprocess_views_view(). So if there's no default preprocess function to add variables to, that means you can't add variables via a preprocess hook in your theme, right?

Wrong! You can still define a preprocess function in template.php which can still add variables to a view tpl file, because it is the tpl file that must exist for this to work, not the default preprocess function. (Note, work is underway to make neither an absolute requirement.) If there is a tpl file, there can be a preprocess function (hook) to add variables to it in your theme, even if the module initially facilitating the tpl file does not have such a default function.

So with that in mind, first I need to create my tpl file. If I have a view called 'my_view' then I need to create a tpl file in my theme called views-view--my-view.tpl.php (you can get the list of valid tpl names for any view from the Views UI and you would copy the appropriate stub template from the 'theme' directory in the Views module installation directory).

Now my tpl file exists, if we are using the Garland theme I can put this in template.php:

function garland_preprocess_views_view__my_view(&$variables) {
$variables['foo'] = 'some text';
}
?>

And in the tpl file I now have a $foo variable available, as you would expect having read the preprocess function page. So in the tpl file you can do this:

if ($foo) {
print $foo;
}
?>

Now in $variables *all* your view data is available, so with your preprocess function you can expose anything you like as a variable. You could also load additional stuff and pass it in, but I'm sure I can leave you to work all that out.

In short: a combination of tpl files and preprocess functions effectively replace phptemplate theme override functions for Views, allowing you to pass any additional variables you might need to the basic view template for any view, meaning I can customise the available variables within template.php and make sure I only need one tpl file for each view, which suits my purposes perfectly. And this is much better than the old system, because there is now a true separation of data from mark-up, where template.php becomes pure logic, passing variables to be placed in the mark-up provided by the tpl files.

You can see my original thread with 'merlinofchaos' here, and he makes a good point about symlinks in Linux there as well as other theming tips too, so also well worth a read. Ignore my 'preprocessor' typo. =)