January 11, 2009

How to theme the heading title of a taxonomy page in Drupal

Filed under: Tips — Tags: , — Webopius @ 1:12 pm

In Drupal 6, when you navigate to a page listing all nodes for a specific taxonomy term (e.g. /taxonomy/term/1), Drupal will render a page for that term with the term description as the title heading and a list of nodes matching the term below this. If no nodes match the term then the text “There are currently no posts in this category.” is shown.

Styling this page is pretty straightforward using CSS and by editing the node.tpl.php template for your theme.

The big challenge though is that the page heading code looks something like this:

<div class="taxonomy-term-description">Term Description here</div>

For SEO purposes, as this is the key description for the page, you might want to wrap this in an H1 tag like this:

<h1>Term Description here</h1>

This is where you might start to hit problems. I have to be honest, I spent about 2 hours searching Google for a solution without much success. Most people seems to suggest either changing the core taxonomy module code or using the views module.

In my case, I like to have full control over the rendering of pages so I tend not to use the views module much and I wanted a cleaner solution than changing the Drupal core.

Themed Taxonomy Title – the solution

So, I dug deeper and the solution is actually very simple once you figure out how the theme() function hierarchy works. For my research I have to thank the excellent Pro Drupal Development 2nd Edition by John K. VanDyk. This book is a lot clearer to follow than some of the online Drupal API pages.

The key was within the taxonomy module in the file ‘taxonomy.pages.inc’. Within this file is a function taxonomy_term_page. This function makes a call to theme() as follows:

$output = theme('taxonomy_term_page', $tids, taxonomy_select_nodes($tids, $terms['operator'], $depth, TRUE));

If you look later in the same file, you’ll see the definition theme_taxonomy_term_page() itself.

Now, the important issue here is that when theme(‘taxonomy_term_page’,…) is called it looks in the following places for a match (let’s assume the theme you are using is called ‘mytheme’ and you are using the usual phptemplate theme engine):

  1. mytheme_taxonomy_term_page()
  2. phptemplate_taxonomy_term_page()
  3. sites/all/themes/custom/mytheme/taxonomy_term_page.tpl.php
  4. theme_taxonomy_term_page()

Because by default there are no matches for 1 to 3 above, the standard taxonomy theme_taxonomy_term_page() is called.

Having understood this concept, the solution is to write your own taxonomy_term_page() function within your theme’s template.php file (create this file if it doesn’t exist). An example of this is shown below, make sure you change the start of the function name to match your theme’s actual name:


function yourthemename_taxonomy_term_page($tids, $result) {
  $output = '';

  // Only display the description if we have a single term...
  if (count($tids) == 1) {
   $term = taxonomy_get_term($tids[0]);
   $description = $term->description;
   // Check that a description is set.
   if (!empty($description)) {
     $output .= '<h1>';
     $output .= filter_xss_admin($description) ;
     $output .= '</h1>';
    }
  }
  $output .= taxonomy_render_nodes($result);
  return $output;
}

Now, when you view a taxonomy term page, the title should be wrapped in <h1> tags

  • Tags