Sep 19 2012 at 8:05am

Theming hierarchical taxonomy pages in Drupal

I recently came across a challenging theming problem in Drupal involving hierarchical taxonomy vocabularies. Drupal, in general, doesn’t handle taxonomy hierarchies very well. You can easily put taxonomy terms into hierarchies, but it’s difficult to do anything with that information afterwards (e.g. treat parent and child terms differently in some way, or identify where the term is in the hierarchy).

In my case, I needed to use a different page layout for taxonomy term pages depending on whether they were a parent or child term. Category (top-level) taxonomy landing pages needed to display a feature image and headline (fields in the taxonomy vocabulary) and a list of manually selected content (using Nodequeue). Sub-category (child-level) taxonomy landing pages needed to show a description (another field in the vocabulary) and all nodes associated with that term.

Screenshot of top-level landing page

Top-level (parent) term display

Screenshot of child-level display

Child-level term display

Note that the current taxonomy term of the parent terms is the same as the parent taxonomy term on the sub-category pages. Similarly, the child taxonomy terms on the parent term pages is the same as the sibling (and current) taxonomy terms on the child term pages.

The options

There are two ways to display taxonomy term pages:

  1. use the template provided by the  taxonomy module (or your own override)
  2. use a views override.

Views comes with a sample taxonomy term override, which simply displays a list of content associated with the term. The problem is that it does not display any fields associated with the taxonomy term.

On the other hand, the taxonomy page templates do display  the taxonomy fields but do not allow you to customize the way content is selected and displayed. Node teasers are simply displayed in the order they were published.

In this case, I needed to adjust how the content is selected for display, but also show some fields from the taxonomy vocabulary. To complicate matters, content for the top-level categories had to be selected differently from the child-level sub-categories.

To display the taxonomy fields at the top of the page (feature images, headlines, and descriptions), I decided to use a view override. Instead of using the example provided by Views, I created a new term view, which simply displays the fields from the vocabulary. I set all of them to “hide if empty”, which leaves it to the site manager to leave the fields blank when they aren’t supposed to display. On the up side, this gives them the opportunity to add feature images to child terms if they want to.

The content displays could easily be created by Views as well, but how to attach different views to parent vs. child terms?

Differentiating between parent and child terms

Context Taxonomy Depth

Context Taxonomy Depth admin interface

After much trial and error I finally decided that we needed to write a custom plugin for Context. I was already using context for other aspects of the site (e.g. defining the “shop” section). I enlisted the help of a Drupal developer (my husband, Liam McDermott) to write a “Taxonomy Term Depth” plugin for Context. We are planning to contribute the code for this back, either to Context Extras or as a separate sandbox module.

As you can see from the screenshot to the right, this plugin lets you define whether a taxonomy term is a top-level term (does not have parents), or is a child-level term (has parents). This is best used along with a Taxonomy Term condition, to define the vocabulary, and with “Require all conditions” checked.

Using this new plugin we defined two contexts: one for top-level terms, one for child-level terms in the Categories vocabulary.

Displaying the top-level term

The site designs also called for a sidebar menu displaying the top-level term and its child terms. The challenging part here is that the relationship between the current page and the top-level term differs depending on whether you are on a top-level term page or a child-level page. I played around with doing this in Views, but that required different views for parent vs. child terms vs. node pages. What a mess! Thankfully, I had a developer on-hand to help me out with this one. We came up with a custom theme function that is called in a block:

function beautifullife_parent_terms($vid = 1) {

 /* Get the tid.
 If on a Category (taxonomy/term) page, the tid is arg(2) in the path. */
 if (arg(0) == 'taxonomy' && arg(1) == 'term') {
 $tid = arg(2);
 }
 // If on a Product (node) page, get the tid from the node object.
 else if (arg(0) == 'node') {
 $nid = arg(1);
 $node = node_load($nid);
 $tid = $node->field_product_category[$node->language][0]['tid'];
 }

 // Get the top most ancestor of the current term.
 $parents = taxonomy_get_parents_all($tid);
 $first_ancestor = array_pop($parents);
 $output = '<h1>' . $first_ancestor->field_page_title[LANGUAGE_NONE][0]['safe_value'] . '</h1>';

 return $output;

}

This is called in a block set to use the PHP input format:

<?php // $vid is the vocabulary id.
 print beautifullife_parent_terms($vid = 1);
?>

Is that all?

I guess so! I actually wrote this post months ago but was waiting for the site to launch before I published it. Then I forgot. I figured I might as well put it up now in case anyone else has similar problems with theming taxonomies in Drupal. Better late than never :)

 

Comments RSS

One Response to “Theming hierarchical taxonomy pages in Drupal”

  1. Hello !

    the “Taxonomy Term Depth” Context plugin has been proposed for commit for D7 here: http://drupal.org/node/1444500 but is not yet committed to Context Plugin Extras module (which seems to have no official D7 version).

    Thanks very much for this blog article and plugin contribution !

    Happy new year !

Leave a Comment


(will not be published)