Community Documentation

Expand term display to show complete paths of related terms

Last updated August 26, 2009. Created by lonehorseend on June 2, 2008.
Edited by bekasu, jhodgdon. Log in to edit this page.

Description

The purpose of this snippet is to replace the term list that is shown below the node title with listing of any related terms and their complete breadcrumb trail. This allows for easy navigation between related terms and eliminates the redundancy of listing the current term underneath the node title.

In each case, I edited the node.tpl file by replacing the

<?php
print $terms
?>
line instead of going through the template.php.

Drupal 5

Single vocabulary

This is for taxonomy terms with based only one one vocabulary. I took part of my code from http://drupal.org/node/53089 and documented the stuff that I added.

<?php
$termtoexclude
=arg(2); //figure out what term page you are looking at
$printvocab=FALSE;
$vocabs = array();
foreach( (array)
$node->taxonomy as $term ) {
 
$vocab = taxonomy_get_vocabulary($term->vid);
 
$parents = taxonomy_get_parents_all($term->tid); //get the parents of the current term in the list of terms
 
if ( !isset($vocabs[$vocab->name]) ) {
 
$vocabs[$vocab->name] = array();
  }
  if (
$term->tid != $termtoexclude) //make sure the current page term isn't in the list of terms
 
{
 
$printvocab=TRUE;
  if (
count($parents) > 0) //make sure there is at least one level of parents.  If not just use the current term
 
{
 
$vocabstemp = array(); //need this because taxonomy_get_parents_all starts with the current term and works backwards, so you have to reverse the order.
 
$vocabsfinal='';
 
//build your temporary list of parents
 
foreach ($parents as $parent) {
 
$vocabstemp[] .= l($parent->name, "taxonomy/term/$parent->tid");
  }
 
$vocabstemp = array_reverse($vocabstemp); //reverse the list of parents so that it makes sense to the human eye.  The next "foreach" build the final list of parents, making sure to take out the separator on the last term
 
foreach ($vocabstemp as $vocabstemp2key => $vocabstemp2) {

  if (
$vocabstemp2key < count($vocabstemp)-1)
  {
 
$vocabsfinal .= $vocabstemp2.">";
  }
  else
  {
  
$vocabsfinal .= $vocabstemp2;
  }
  }
 
$vocabs[$vocab->name][] = $vocabsfinal;
  }
  else
  {
   
$vocabs[$vocab->name][] = l($term->name, "taxonomy/term/$term->tid");
  }
  }
}
//print the term list only if it isn't the current page term.
if ($printvocab) {
foreach (
$vocabs as $name => $termlinks ) {
  print
'<div class="taxonomy"> See Also: ';
  print
implode(', ', $termlinks);
  print
'</div>';
  }
}
?>

Multiple vocabulary

Use this one if you have a term list where you know the terms come from all different categories. I've only documented the changes from above.

<?php
$termtoexclude
=arg(2);
//We don't want to repeat the current page's term or vocabulary. The next 3 lines are the setup for this.
$printvocab=FALSE;
$vocabtermtoskip = taxonomy_get_term($termtoexclude);
$vocabtoskip = taxonomy_get_vocabulary($vocabtermtoskip->vid);
$vocabs = array(); //The $vocabs array has changed to accommodate the multiple vocabularies. $vocabs[$vocab->name]['vocab'] contains the name / links to the vocabularies and $vocabs[$vocab->name]['links'][] contains the names / links to the terms of the vocabulary instance. (Yes, you can have more than one instance of the same vocabulary.)
foreach($node->taxonomy as $term )
    {
   
$vocab = taxonomy_get_vocabulary($term->vid);
   
$parents = taxonomy_get_parents_all($term->tid);
    if (
$vocab->name != $vocabtoskip->name)//If we aren't skipping the current page's vocabulary, we are putting the vocabulary in front of the term path.
       
{
       
$vocabs[$vocab->name]['vocab']=l($vocab->name, "taxonomy/vocabulary/$term->vid").">";
        }
    else
        {
       
$vocabs[$vocab->name]['vocab']="";
        }
    if (
$term->tid != $termtoexclude)
        {
       
$printvocab=TRUE;
        if (
count($parents) > 0)
            {
           
$vocabstemp = array();
           
$vocabsfinal='';
            foreach (
$parents as $parent)
                {
               
$vocabstemp[] .= l($parent->name, "taxonomy/term/$parent->tid");
                }
           
$vocabstemp = array_reverse($vocabstemp);
            foreach (
$vocabstemp as $vocabstemp2key => $vocabstemp2)
                {
                if (
$vocabstemp2key < count($vocabstemp)-1)
                    {
                   
$vocabsfinal .= $vocabstemp2.">";
                    }
                else
                    {
                   
$vocabsfinal .= $vocabstemp2;
                    }
                }
            
$vocabs[$vocab->name]['links'][] = $vocabsfinal;
            }      
        else
            {
           
$vocabs[$vocab->name]['links'][] = l($term->name, "taxonomy/term/$term->tid");
            }
        }
     }
if (
$printvocab) //We are using a string called $termcontent because it was the easiest way to make sure that the commas all fell in the right place.
   
{
   
$termcontent = '<div class="taxonomy"> See Also: ';  
    foreach (
$vocabs as $vocabcatkey => $vocabitems)
        {
        if (
count($vocabitems['links'])>0)
            {
            foreach (
$vocabitems['links'] as $vocabkey => $vocablinks)
                {
               
$termcontent .= $vocabitems['vocab'];
               
$termcontent .= $vocablinks;
               
$termcontent .= ", ";
                }
            }
        }
   
$trimmed = rtrim($termcontent,", ");
   
$trimmed .= '</div>';
    print
$trimmed;
    }
?>

Multiple vocabulary, multiple hierarchy

In this case, it looks at a vocabulary, determines if it's a multiple hierarchy that has more than 1 parent, and then traces the routes of those parents separately.

<?php
$termtoexclude
=arg(2);
$printvocab=FALSE;
$vocabtermtoskip = taxonomy_get_term($termtoexclude);
$vocabtoskip = taxonomy_get_vocabulary($vocabtermtoskip->vid);
$vocabs = array();
foreach(
$node->taxonomy as $term )
    {
   
$vocab = taxonomy_get_vocabulary($term->vid);
   
$parents = taxonomy_get_parents_all($term->tid);
    if (
$vocab->name != $vocabtoskip->name)
        {
       
$vocabs[$vocab->name]['vocab']=l($vocab->name, "taxonomy/vocabulary/$term->vid").">";
        }
    else
        {
       
$vocabs[$vocab->name]['vocab']="";
        }
    if (
$term->tid != $termtoexclude)
        {
       
$printvocab=TRUE;
        if (
count($parents) > 0)
            {
           
$vocabstemp = array();
           
$vocabsfinal='';
            if (
$vocab->hierarchy==2 && count($parents) > 1)
                {
               
$vocabstempmulti = array();
               
$parentsmulti = taxonomy_get_parents($parents[0]->tid);
                foreach (
$parentsmulti as $parentmulti)
                    {       
                       
$parentstrees = taxonomy_get_parents_all($parentmulti->tid);            
                        if (
count($parentstrees) > 1)
                        {
                        foreach (
$parentstrees as $parentstree)
                        {       
                           
$vocabstemp[] .= l($parentstree->name, "taxonomy/term/$parentstree->tid");           
                        }
                       
$vocabstemp = array_reverse($vocabstemp);       
                        foreach (
$vocabstemp as $vocabstemp2key => $vocabstemp2)
                            {
                            if (
$vocabstemp2key < count($vocabstemp)-1)
                                {
                               
$vocabsmultifinal .= $vocabstemp2.">";
                                }
                            else
                                {
                               
$vocabsmultifinal .= $vocabstemp2;
                                }
                            }
                           
$vocabstempmulti[] = $vocabsmultifinal;
                        }
                        else
                        {
                           
$parentnumber=$parentstrees[0]->tid;
                           
$vocabstempmulti[] = l($parentstrees[0]->name, "taxonomy/term/$parentnumber");
                        }
                    }
               
$termnumber=$parents[0]->tid;
                foreach (
$vocabstempmulti as $vocabstempmultikey => $vocabstempmulti2)
                    {
                    if (
$vocabstempmultikey < count($vocabstempmulti)-1)
                        {
                           
$vocabsfinal .= $vocabstempmulti2.">".l($parents[0]->name, "taxonomy/term/$termnumber").", ";
                        }
                    else
                        {
                           
$vocabsfinal .= $vocabstempmulti2.">".l($parents[0]->name, "taxonomy/term/$termnumber");
                        }
                    }
                }   
                else
                {
                    foreach (
$parents as $parent)
                    {       
                       
$vocabstemp[] .= l($parent->name, "taxonomy/term/$parent->tid");                   
                    }
                   
$vocabstemp = array_reverse($vocabstemp);       
                    foreach (
$vocabstemp as $vocabstemp2key => $vocabstemp2)
                    {
                        if (
$vocabstemp2key < count($vocabstemp)-1)
                        {
                       
$vocabsfinal .= $vocabstemp2.">";
                        }
                        else
                        {
                       
$vocabsfinal .= $vocabstemp2;
                        }
                    }
                   
                }
           
$vocabs[$vocab->name]['links'][] = $vocabsfinal;
            }           
        else
            {
           
$vocabs[$vocab->name]['links'][] = l($term->name, "taxonomy/term/$term->tid");
            }
        }
     }
if (
$printvocab)
    {
   
$termcontent = '<div class="taxonomy"> See Also: ';   
    foreach (
$vocabs as $vocabcatkey => $vocabitems)
        {
        if (
count($vocabitems['links'])>0)
            {
            foreach (
$vocabitems['links'] as $vocabkey => $vocablinks)
                {
               
$termcontent .= $vocabitems['vocab'];
               
$termcontent .= $vocablinks;
               
$termcontent .= ", ";
                }
            }
        }
   
$trimmed = rtrim($termcontent,", ");
   
$trimmed .= '</div>';
    print
$trimmed;
    }
?>

Drupal 6

Single vocabulary

One line was changed to make this work in Drupal 6.

<?php
$termtoexclude
=arg(2); //figure out what term page you are looking at
$printvocab=FALSE;
$vocabs = array();
foreach( (array)
$node->taxonomy as $term ) {
 
$vocab = taxonomy_vocabulary_load($term->vid); // Changed for Druapl 6
 
$parents = taxonomy_get_parents_all($term->tid); //get the parents of the current term in the list of terms
 
if ( !isset($vocabs[$vocab->name]) ) {
 
$vocabs[$vocab->name] = array();
  }
  if (
$term->tid != $termtoexclude) //make sure the current page term isn't in the list of terms
 
{
 
$printvocab=TRUE;
  if (
count($parents) > 0) //make sure there is at least one level of parents.  If not just use the current term
 
{
 
$vocabstemp = array(); //need this because taxonomy_get_parents_all starts with the current term and works backwards, so you have to reverse the order.
 
$vocabsfinal='';
 
//build your temporary list of parents
 
foreach ($parents as $parent) {
 
$vocabstemp[] .= l($parent->name, "taxonomy/term/$parent->tid");
  }
 
$vocabstemp = array_reverse($vocabstemp); //reverse the list of parents so that it makes sense to the human eye.  The next "foreach" build the final list of parents, making sure to take out the separator on the last term
 
foreach ($vocabstemp as $vocabstemp2key => $vocabstemp2) {

  if (
$vocabstemp2key < count($vocabstemp)-1)
  {
 
$vocabsfinal .= $vocabstemp2.">";
  }
  else
  {
  
$vocabsfinal .= $vocabstemp2;
  }
  }
 
$vocabs[$vocab->name][] = $vocabsfinal;
  }
  else
  {
   
$vocabs[$vocab->name][] = l($term->name, "taxonomy/term/$term->tid");
  }
  }
}
//print the term list only if it isn't the current page term.
if ($printvocab) {
foreach (
$vocabs as $name => $termlinks ) {
  print
'<div class="taxonomy"> See Also: ';
  print
implode(', ', $termlinks);
  print
'</div>';
  }
}
?>

Notes & References

Comments

D6?

has anyone tried this on D6.x ?

-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
"I would love to change the world,
but they won't give me the source code"
-JG

Yes, I have tried this on D6

Yes, I have tried this on D6 and unfortunately it does not work. I will post a workaround if I can, however any contributions are certainly welcome.

http://drupal.org/node/53089#

http://drupal.org/node/53089#comment-929924
So far this is the closest I have found, and it works quite well.

Aware of non-compatibility with D6

Single vocabulary now works for Drupal 6. Will work on the other versions in the future.

Thank you!

Hi lonehorseend.
The code for D6 works perfectly! Thank you!

Question: how can i move the code to template.php to keep my tpl.php page lean?
Thank you for any hints!

Page status

Needs updating

Log in to edit this page

About this page

Drupal version
Drupal 5.x, Drupal 6.x
Audience
Designers/themers

Theming Guide

Drupal’s online documentation is © 2000-2013 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution-ShareAlike 2.0. PHP code is distributed under the GNU General Public License. Comments on documentation pages are used to improve content and then deleted.