Overriding themable output
The following only applies when the default markup needs changes. This section can be skipped if the presentation is handled only through style sheets.
There are three aspects to overriding the themed output. The first is knowing where the source originates, the second is providing the override and third is understanding its type.
Note that Drupal maintains cached theming data through the theme registry. It must be cleared when setting up overrides.
- 1. Finding the source:
-
Finding the source can be difficult to track down due to the hierarchy of theming calls whose source can be spread throughout the whole system.

Links to 520KB PDF. Provided for illustration only.Most of the page elements are typically pulled with theme('page') and placed inside the page.tpl.php template after rendering navigation bits, the bits within the navigation bits, block regions, the blocks within the block regions, etc. Each chunk of themed data is often referred to as a theming "hook".
Note: Theming functions and templates will now be referred to as theming hooks. There are many hooks unrelated to theming throughout the system. Any mention of it here only relates to theming.
Getting to the source of any specific chunk of markup can now be tracked with the devel module. It includes a theming tool to easily visualize the source of any output, its type and tons of other theming data. See the screencast for a demonstration. This is not available for Drupal versions less than 6 due to technical limitations.
- 2. System of overrides:
-
The system of overrides has a specific cascading order with few exceptions. Drupal core and modules provide a reasonable default for its markup handled by the theming hook. If it does not suit the requirements of the theme, then an alternate can be provided preventing the defaults from being used. This way, the defaults are left alone and all the theme specific changes are localized to the theme. Never hack on files outside your theme.

If you need more control beyond this convention of overrides, the theme registry can be manipulated for more control.
Note: Although it is still possible, PHPTemplate.engine in Drupal 6 no longer overrides theme functions. In 5, that is what allowed templates to be used for a handful of the theming hooks. It is no longer necessary.
- 3. Functions vs. templates:
-
There are two ways or "types" as it was mentioned above in implementing any given hook. Normal "functions" or "templates". Depending on the nature of the themed element, one may be better suited than the other. Core and modules can construct the output in either type. The upper theming layers can carry over the same type or change it.

Links to PDF. Flow map for 5 also available for comparison.Theming hooks implemented as functions provide speed. It is about five times faster than templates but they are difficult for designers who may be more familiar with working directly in xHTML. Generally, this should not be a concern as it depends on the nature of the hook and the number of times it is called on a page.
Note: In versions before 6, core and modules could only work as functions for the theming hooks. Implementing through templates was done by PHPTemplate by overriding the hooks and doing the conversion on the engine layer.
Here are two examples on overriding with the help of devel themer.
- Overriding functions:
-
The theme function theme_menu_local_tasks is a simple function for outputting both primary and secondary tabs. The theming hook in this case is "menu_local_tasks". To override, the "theme" prefix in the function name can be changed to the name of your theme or the theme engine the theme is running under. Using the theme name is recommended due to potential name collisions with sub-themes.

The example shows Garland is using the name of the theme engine for the override. If you were to create a sub-theme based on Garland, then using the name of your theme is mandatory.
Placing the following inside the theme's template.php file will override the default after clearing the theme registry. Change "drop" to the name of your theme.
<?php
function drop_menu_local_tasks() {
$output = '';
if ($primary = menu_primary_local_tasks()) {
$output .= "<ol class=\"tabs primary\">\n". $primary ."</ol>\n";
}
if ($secondary = menu_secondary_local_tasks()) {
$output .= "<ol class=\"tabs secondary\">\n". $secondary ."</ol>\n";
}
return $output;
}
?>The only change here is the markup from an unordered list to an ordered list.
A listing of all the theme functions can be found on api.drupal.org.
- Overriding templates:
-
If the default implementation is done as a template then simply moving the source template file into the theme will automatically override it after clearing the theme registry. Here is an example for search-theme-form.tpl.php. Note that the theming hook in this case is "search_theme_form" with the template using hyphens instead of underscores.

That is all you need to do. Open the copied template in your editor to make your alterations. All the core .tpl.php files are documented. It should give a good indication on what can be done with the output.
Note: templates can be placed in any directory within the theme. This allows for better management and less clutter in the base level of the theme directory.
Related pages:
- To customize the variables inside templates, see the sub-page on Preprocess functions.
- A listing of all the theme templates can be found on the sub-page, Core templates and suggestions.
- Converting from functions to templates
-
Converting a theme function into a template takes some initial work but once it is done, it's easier to work with. If you are collaborating with a designer, the conversion will enable them to focus on designing, not coding. There are many templates already available in core and many more will be converted in future versions. Contributed modules that follow best practices should also have templates available. These instructions are provided for the theming hooks not already made available as templates.
Getting Drupal to recognize the theming hook as a template is automated. These are the only requirements to trigger this change:
- Name of the template must match the theming hook.
- The underscores in the hook must be changed to hyphens.
- The template name must have an extension of ".tpl.php". (It can vary based on the theme engine.)
Consider the theming function theme_user_signature. The theme hook here is "user_signature". Creating a file named "user-signature.tpl.php" will tell Drupal that the hook is now a template after clearing the registry. Any content in this file will now take the place of the function. The part that takes more work is setting up the variables to be used in this file and that is done through preprocess functions.
A few notes:
- While it is possible to code directly inside the template, it is not considered good practice. All the complex logic should be separated from the .tpl.php file. This keeps it clean and easy to manage.
- There is also the issue of security. The separation can minimize the chance of cross-site scripting attacks by cleaning out potentially malicious user generated content. When handing over template files to your designer, all the output should be clean so they do not have to concern themselves with security issues.
- Compare the theming functions in 5 to the template conversions in 6 for forums. You can use that as an example on converting between the two types.
- More information on preprocess functions available.
- The theme registry:
- Drupal's theme registry maintains cached data on the available theming hooks and how to handle them.
For most theme developers, the registry does not have to be dealt with directly. Just remember to clear it when adding or removing theme functions and templates. Editing existing functions and templates does not require a registry rebuild.
To clear the theme registry, do one of the following things:
- Clear button located at "Administer > Site configuration > Performance".
- With devel block enabled (comes with devel module), click the "Empty cache" link.
- The API function drupal_rebuild_theme_registry.
The theme registry is cached data instructing Drupal on the available theming hooks and how to handle it by indicating its type. In previous versions all theming calls were handled on the fly. Since a lot more work is being done under the hood, the cached instructions speeds up the process especially for templates. The theme engine your theme is running under should automatically register all the theming hooks for you.
There are special cases where you may need to work with the registry directly. When your theme requires a new hook to be registered that was not already implemented on the layers below it (core, modules, engine). This includes some forms when they are not explicitly themed by core or modules but instead rely on the default form presentation.
- More details can be found in the sub-page, The theme registry for special cases.
- Do not confuse the theme registry with the theme's .info file which is also cached. Points 1 and 2 on clearing the registry will clear both.

Creating callbacks and templates with custom modules
When creating a custom module you will want to check out hook_theme(). The hook registers your custom theme callbacks and templates with the Drupal theme registry so that they are called appropriately.
http://api.drupal.org/api/function/hook_theme
After I created this function in my module and emptied the cache, then all of my template callbacks where functioning properly.
That information is already
That information is already provided for module devs. See Registering theme hooks.
This handbook is for themers.
⎋ joon park
–www.dvessel.com–