Drupal theming next steps: Overriding HTML output

Soon after you've started out with Drupal theming, you'll probably find that you need to change some of the HTML code it generates. But how do you do that? This article will break down the process of overriding Drupal's HTML code (or "Overriding themable output"), using template files and theme functions.

This article is a successor to How to create a simple Drupal 7 theme from scratch. It is assumed that you have read that article and/or have basic knowledge of how the Drupal theming system works. It has been written for Drupal 7, although the same concepts apply to Drupal 6 with some minor differences.

Overriding Drupal's HTML

The HTML code Drupal outputs can actually come from two places: template files (files with a .tpl.php extension) or theme functions (PHP). 

To override code in either case, you need to follow a few basic steps:

  1. Find the code you need to modify
  2. Copy it to your theme
  3. Customize as needed

I'm sure you know that you should never modify Drupal's code directly, right? You should always make a copy in your own theme and customize from there.

1. Where did that code come from?

Ah, one of the great mysteries of Drupal's theme layer. How do you determine where that bit of HTML came from?

There are two things you need to know to find the code you need to override: whether it's a template file or a theme function, and which module created it. One simple rule of thumb is that big things usually have template files (e.g. a node, a block), while small, repetitive things (e.g. a menu, a group of links), will be generated with a theme function. The reason for this because template files are easier for theme developers to use, but slower than theme functions. The most commonly customized elements are therefore done as template files, while smaller, less frequently customized elements can use the quicker theme functions.

How do you know which module may have generated that code? If it isn't obvious, try using your browser's developer tools to look at the CSS classes on the containing element. The module may have left an identifying class there.

Once you know one or both of those things (or can make a reasonable guess), there are a few methods you can use to find out how to change that code:

  1. Look for it – If you think you need to override a template file, try looking in the modules/[module] directory for a .tpl.php file that might contain the code you're looking for. For example, if you want to override a node template, you need the node.tpl.php file which can be found in the modules/node directory (note: a few important templates are in the system module, including html.tpl.php, page.tpl.php, region.tpl.php and maintenance-page.tpl.php). Open the file with your text editor to see if it contains the code you're looking for. Drupal.org also has a handy list of templates provided by Drupal core.

    If you've determined that the code you're looking for is in a theme function (or can't find a relevant template file), you can try searching for the relevant function in Drupal's API documentation. The search form has a handy autocomplete feature that helps you to find relevant functions. The function you're looking for will probably start with theme_ or template_preprocess_. The API doc pages show you the function's code, which you can compare to the code you're trying to override.

  2. Search - One of the wonderful things about Drupal is that with so many people using it, someone else has probably had the same problem. If you search (using Drupal.org or your search engine of choice) for "How to customize Drupal's ___________", you'll probably come up with lots of helpful examples.
  3. Devel Themer – If the previous methods didn't work, you can use the Devel themer module to find out exactly what created the code you're trying to override. This module can be slow and sometimes alters the display of your site, which means that you probably want to turn it off if you're not using it. For that reason, I find the other methods above to be more efficient in many cases.
  4. Views theme information – Views also uses template files to generate HTML mark-up. It provides information about which templates are being used in your view under Advanced > Theme Information.

2. Copy the code to your theme

Once you've found the code you want to override, you need to copy it to your theme and give it a more specific name. The process for doing this is, of course, different for templates and theme functions.

One important thing to remember is that Drupal stores templates and theme functions in the cache. Whenever you add a new template suggestion or theme function, you need to clear the cache to make it appear on the site. You shouldn't need to do this if you've just made a change to a template or theme function override that you've already created.

Overriding template files

To override a template file, you first need to copy the template from it's originating module to your theme folder. You can keep your templates in the root of your theme folder, or create a separate templates folder for them. Drupal will find them either way.

If you want to customize a template in all the places it is used on your site (e.g. all blocks, all nodes), just keep the original file name and customize the code as needed. Drupal will look in your theme for template files first. If it can't find one for a particular case, it will default to the template provided by the module.

Template suggestions

Things get a bit more complicated if you want to customize a template only in certain instances. You can customize templates for specific cases such as:

  • The node template for a node type or a specific nid
  • The block template for a region or a specific block
  • The field template for a content type or a specific field
  • The taxonomy/term template for a vocabulary or a specific term
  • The comment template for a node type
  • Many more!

In these cases you need to rename the template file to tell Drupal when to use it. The general filename pattern is:

template--case.tpl.php

(note the two dashes between the name of the core template name and your use case).

For example, if you want to customize the node template for a particular content type, you use the name of the content type as the case. To create a node template suggestion for the article content type only, you would rename your file to:

node--article.tpl.php

The machine name of the content type shown on the Content Types admin screen.

Drupal will use the most specific template available for a particular element. So, for example, if you provide a template suggestion for an individual node as well as for all nodes of that type, Drupal will use the one suggested for that particular node (because it's more specific). In some cases, a suggestion will only work if you've provided an instance of the base template (e.g. the above node template suggestion won't work unless you also have a node.tpl.php file in your theme).

With all the options available for customization, these naming conventions can get a bit confusing. Drupal's documentation page on Template (Theme Hook) Suggestions lists all the core templates and the suggestion conventions for each. Devel themer will provide you a list of possible template suggestions, as does Views' Theme Information. You can also create completely custom template suggestions.

Overriding theme functions

Theme function overrides go into a file named template.php. This file should go in the root of your theme folder.

First, create an empty file called template.php. When you've located the function you need to override, copy it to your template.php file and replace the theme_ prefix with the machine name of your theme (the name you gave to your .info file). For example, to customize theme_breadcrumb(), you would change the name of the function to yourtheme_breadcrumb().

Now, customize as needed. You will probably need to know at least some basic PHP in order to do this.

3. Customize as needed

This part is up to you! In a future article I will go into more detail about working with template files.

A few words of caution

  • Every override you put into your theme makes your theme bigger, slower, more complicated, and harder to upgrade in the future. Before you go crazy customizing Drupal's HTML output, consider whether you could find a solution by changing settings or in CSS alone (or whether you really need to change that HTML at all...)
  • Avoid adding PHP logic to your template files. These files are for structural mark-up only – logic goes elsewhere.

Discussion

To discuss, ask questions or comment on this article please see the Webmaster Forums discussion on Drupal theming next steps: Overriding HTML output. Please post there if you have any questions or comments.

Reference

Megan McDermott's picture

About the Author

Megan is co-founder and editor of A Padded Cell and administrator at The Webmaster Forums. She has been designing websites since 1997, with expertise in design, information architecture, usability, HTML/CSS, Drupal theming, and more. She is available for short-term or ongoing freelance work in any of those areas. Read her web design blog at MeganMcDermott.com or check out her portfolio.