Using Theme Override Functions

Many resources for and about Drupal will tell you that the road to true customization lies through overriding theme functions in order to create exactly the kind of output you desire. Doing so is extremely powerful, though it can require a little PHP knowledge to pull off, since you need to create a function. However, there are many snippets and examples to choose from, and many of these are cut and paste with just a little bit of modification necessary to get them to work.

Which File to Use

In order to use theme overrides, the first thing you need is a place to put them. Exactly where you put them depends upon which theme engine you are using. The default theme engine in Drupal 4.6 was XTemplate; however, XTemplate proved problematic when paired with PHP5, so Drupal 4.7 and higher now use PHPTemplate as the default theming engine.

The file you need will live in themes/MYTHEMENAME.

Plain PHP Theme
If using a plain PHP Theme, such as Marvin or Chameleon, the file you place your overrides in is
THEMENAME.theme
XTemplate
XTemplate does not allow theme function overriding.
PHPTemplate
PHPTemplates keep their theme overrides in template.php.
SmartyTemplates
SmartyTemplates use the file smartytemplate.php.
wgSmarty
wgSmarty uses template.php but as of this writing that code is commented out; it may not be possible to do theme overrides in wgSmarty.
phptal
PHPTAL uses template.php, and is very similar to PHPTemplate.

If your theme does not come with a template.php file inside it, you will have to create one. Save a new blank file called template.php, and make sure the first line contains a <?php statement at the top, or you might cause your site to crash with a White Screen Of Death. There's no need to have a closing php tag.

How to Name your Override Function

When overriding a theme function, module documentation will usually inform you to use or override something along the lines of theme_SOME_FUNCTION_NAME. In order to override this, you need to name it something slightly different from this, since PHP requires all function names to be unique.

The example function we're going to look at for this is theme_item_list, which is used whenever Drupal wants to display a list of items, and is used almost everywhere you see the <li> tag in Drupal, except in the menu structure.
This function is defined as:

<?php
 
function theme_item_list($items = array(), $title = NULL, $type = 'ul') {
?>

Overrides can be named in two ways, unless you're using a plain PHP theme. First, all theme overrides can be named by replacing the 'theme_' at the beginning of the function with 'MYTHEMENAME_'. So if you're using the chameleon template, in your chamelon.theme file you, to override the function theme_item_list as:

<?php
 
function chameleon_item_list($items = array(), $title = NULL, $type = 'ul') {
?>

This is not actually the preferred method of overriding, however, but it is the one that always works. Most themes, however, are derived from one of the Template Engines. They can override these functions by using the name of the template engine instead of the theme name. This is preferred, because it makes it very easy to share these functions with other users who might be using a different theme. Or even share a single file of functions with several themes on the same site!

Some examples:

<?php
 
function phptemplate_item_list($items = array(), $title = NULL, $type = 'ul')
  function
smarty_item_list($items = array(), $title = NULL, $type = 'ul')
?>

override for all themes?

vegeneric - December 10, 2007 - 18:39

"Or even share a single file of functions with several themes on the same site!" --> more info, please!

how exactly can a single function override all my themes at once, without having to copy my template.php file into each theme's folder? if i create a function phptemplate_so_on_so_forth and put it in a theme's template.php file, it still only overrides for that single theme.

Sharing functions

zeta ζ - January 29, 2008 - 20:40

The point is that you won’t have to rename the functions, as you would if they were theme_function(). Yes, the file needs to be copied (or linked), but will only require the same theme engine.

Modularisation

kingandy - March 14, 2008 - 15:30

One option would be to create a shared module - for example a module called myglobaltheme.module (with the concordant myglobaltheme.info file), which declares some functions called phptemplate_so_on_so_forth(). If that module were placed in the sites/all/modules folder, it could then be activated on a site-by-site basis simply by visiting the modules page and switching it on as though it were a normal module. It's sneaky but it works ;)

Alternatively - if you want to avoid modules - you could create a PHP file elsewhere on the site (say, in sites/all), and include it in each of your sites by use of the PHP include_once() function in the template.php.

--Andy
Developing Drupal websites for Livelink New Media

 
 

Drupal is a registered trademark of Dries Buytaert.