Beginners guide to overriding themable output

Last modified: August 24, 2009 - 23:19

When you are setting up a Drupal site, you will sometimes find that there is some HTML output coming from Drupal, a core module, or a contributed module on your site, you don't like it for some reason, and you have decided that you want it to differ from the default on your site. Most HTML output from Drupal and its core and contributed modules is overrideable, which means that instead of having to modify the module to change the output (which you don't want to do, because it will make upgrades difficult later), you can modify it by adding functions or files to your theme. The functions or files will take precedence over the module's choice for how to produce the HTML.

There are many ways to override themable output, as you can see from the other pages in this section. This page presents a simple overview of the most common methods of overriding themable output, for the beginning themer.

Avoiding having to override at all

Before you decide that you need to modify the output coming from Drupal or one of the modules on your site, check the following possibilities -- you may be able to avoid the whole process:

  • Can you just change a setting? For instance, you can click on a "Configure" link for any block, and it will allow you to change the text of the block title, or even remove the title completely (you can also move any block to a different region of the page on the blocks configuration screen). Other modules will let you change aspects of their output through settings too (labels for text fields, order of output, etc.). To find settings pages, click on Administer, and then By module, and check out all the settings pages offered by your module. Some settings are also on your theme's configuration page, and some are in various tabs of your content types' settings pages (under Content management >> Content types).
  • Can you accomplish your goal through CSS? Nearly all output in Drupal is enclosed in DIV elements with specific classes or IDs, so you can easily customize a particular piece of output. CSS will let you change fonts, sizes, placement, background images, etc. To override the CSS provided by Drupal or a module, just add to one of your theme's CSS files.

If neither of these options lets you change what you want to customize, then you do actually need to customize the HTML output of Drupal or one of your modules -- read on.

Finding where the themable output is coming from

The first step in overriding Drupal's HTML output is to figure out where the HTML output you want to modify is coming from. What you are looking for is either a theme function (a PHP function called "theme_xyz", such as "theme_search" or "theme_aggregator_block_item"), a template preprocess function (a PHP function called "template_preprocess_xyz"), or a theme file (a PHP file whose name ends in .tpl.php, such as "views-more.tpl.php").

To find the right file or function, start by finding the module directory for the module that is producing the output (under "modules", "sites/all/modules", or "sites/your_sub_dir/modules"). Theme files will generally be in either the top-level module directory, a sub-module directory underneath, or a directory called "theme" underneath. Theme and template preprocess functions will generally be in either a module file (ending in .module) or an include file (usually ending in .inc); the file will be located in the module directory or a sub-directory. A good way to find the right function or file is to search for a specific CSS ID or class on the HTML element you are trying to modify, or some other unique text that the module is producing.

Another method of finding the function to override is to use the Devel module's theme developer functionality.

Some modules also will honor theme file suggestions. For instance, in Views 2, you can get theme information when you are editing a View -- it tells you which theme files will be used to produce the view, and the first one in each list is a theme file that is located in the "themes" sub-directory of your views module; this is the theme file you will want to override. The other names in the list are possibilities for what you will want to name the file when you put it into your theme, depending on how specific you want your override to be (e.g., do you want to override how all views are displayed, or just your specific view?).

You can also use suggestions to override core Drupal module theming. For instance, if you want to override how a particular node content type is displayed, you can use the node.tpl.php file from your theme (or Drupal core) as the overrideable file, and rename the copy node-content_type_name.tpl.php. There is more information about the core module files and suggestion file names you can use on the Core templates and suggestions page.

Once you have found the right function or file to override, follow the directions in one of the next two sections to override it.

However, if you find what is producing the HTML output you want to override, and it is not inside a theme function, template preprocess function, or theme file, then you will probably not be able to modify the output with theme functions alone. You may need to check the support forums or contact the module developer to find out how to modify the output.

Overriding a theme or template preprocess function

If the HTML output you want to override is in a theme function or a template preprocess function, here are the steps to follow to override it:

  1. Open your theme's template.php file in a plain text editor.
  2. Copy the theme or template function you found into your template.php file. (One way of finding the function is searching for the function name at http://api.drupal.org. There is also a Function reference in the menu provided by the Devel module.)
  3. Rename the function you copied in (see note below). If your theme's base prefix is "wonderful", and the theme function you are trying to override is called "theme_xyz", then you need to rename the function "wonderful_xyz". If you are overriding "template_preprocess_xyz", then the new name should be "wonderful_preprocess_xyz".
  4. Modify the function so that it does what you want it to do.
  5. Upload the template.php file to your web site, in your theme directory.
  6. Refresh the theme cache (see http://drupal.org/node/173880#theme-registry).

Note: To change a function name, e.g. from "theme_xyz" to "wonderful_xyz", find a line that looks something like this:

function theme_xyz( $a, $b, $c) {

and change it to:
function wonderful_xyz( $a, $b, $c) {

Make sure you leave the part inside the parentheses unchanged!

Overriding a theme file

If the HTML output you want to override is in a theme file, here are the steps to follow to override it:

  1. Copy the theme file to your theme directory, if your theme directory does not already have a file by that name.
  2. If you are implementing a suggestion, rename the file to the suggestion name it should have. Note that some suggestion files will not be recognized unless their base file is also present -- for instance, if you want to make a node content type suggestion file for your content type, you need to have node.tpl.php present in your theme directory order for your node-my_content_type.tpl.php file to be recognized. However, suggestions for Views do not require that the base Views template file be present in your template directory.
  3. Modify the file so it does what you want it to do.
  4. Upload the file to your web site, including the new base theme file if necessary, into your theme's directory.
  5. Refresh the theme cache (see http://drupal.org/node/173880#theme-registry)

Preprocessors don't actually get overridden

tbartels - August 29, 2009 - 03:13

While in many cases the expected functionality of "Overriding a theme or template preprocess function" will work out how you expect, it is not the case that by creating a themeName_preprocess_hoook you are actually overriding any functionality. Preprocessors are actually added to a queue and all registered preprocessors are run. For a list of preprocessors and which order they get run in see http://drupal.org/node/223430.

If you do "cut and paste" the preprocessor code for a specific hook you are actually duplicating the functionality and technically working with variables that have already been processed by the code you cut and pasted.

 
 

Drupal is a registered trademark of Dries Buytaert.