Expand term display to show complete paths of related terms

Last modified: July 5, 2008 - 20:27

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.

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;
    }
?>

Notes & References

 
 

Drupal is a registered trademark of Dries Buytaert.