Note: See comments for several alternative approaches, each w different priorities and different results.

By default, taxonomy terms are displayed in the node by the function print $terms

This results in one big array of all taxonomy terms associated with that node, no matter what vocabulary. Sometimes it makes sense to break these up, so that the terms are displayed by vocabulary. For example:

  • Topic: foo, bar
  • Tags: bat

To do this, use one of the following approaches:

Method A: (Drupal 6 ONLY)

The following breaks up taxonomy by vocabulary, or, if you pass it a vocabulary id (vid) it will print only that vocabulary which corresponds to the vid you passed to it. If you pass it a true or false value, it will also print or not print the terms as ordered lists. Useful for teasers.

Add this following snippet to your template.php file, minus the php tags that surround it:

<?php
function yourthemename_print_terms($node, $vid = NULL, $ordered_list = TRUE) {
     $vocabularies = taxonomy_get_vocabularies();
     if ($ordered_list) $output .= '<ul>'; //checks to see if you want an ordered list
     if ($vid) { //checks to see if you've passed a number with vid, prints just that vid
        $output = '<div class="tags-'. $vid . '">';
        foreach($vocabularies as $vocabulary) {
         if ($vocabulary->vid == $vid) {
           $terms = taxonomy_node_get_terms_by_vocabulary($node, $vocabulary->vid);
           if ($terms) {
             $links = array();
             $output .= '<span class="only-vocabulary-'. $vocabulary->vid . '">';
             if ($ordered_list) $output .= '<li class="vocabulary-'. $vocabulary->vid . '">' . check_plain($vocabulary->name) . ': ';
             foreach ($terms as $term) {
               $links[] = '<span class="term-' . $term->tid . '">' . l($term->name, taxonomy_term_path($term), array('rel' => 'tag', 'title' => strip_tags($term->description))) .'</span>';
             }
             $output .= implode(', ', $links);
             if ($ordered_list) $output .= '</li>';
             $output .= '</span>';
           }
         }
       }
     }
     else {
       $output = '<div class="tags">';
       foreach($vocabularies as $vocabulary) {
         if ($vocabularies) {
           $terms = taxonomy_node_get_terms_by_vocabulary($node, $vocabulary->vid);
           if ($terms) {
             $links = array();
             $output .= '<ul class="vocabulary-'. $vocabulary->vid . '">';
             if ($ordered_list) $output .= '<li class="vocabulary-'. $vocabulary->vid . '">' . check_plain($vocabulary->name) . ': ';
             foreach ($terms as $term) {
               $links[] = '<span class="term-' . $term->tid . '">' . l($term->name, taxonomy_term_path($term), array('rel' => 'tag', 'title' => strip_tags($term->description))) .'</span>';
             }
             $output .= implode(', ', $links);
             if ($ordered_list) $output .= '</li>';
             $output .= '</ul>';
           }
         }
       }
     }
     if ($ordered_list) $output .= '</ul>';
     $output .= '</div>';
     return $output;
}
?>

Note: Be sure to replace 'yourthemename' with the actual name of your theme, or this will not work. [Remember, don't include the php tags if you already have them in your file.]

Step Two

Now add the following to your node.tpl.php file. This prints an comma-separated list if it's a teaser, and a ordered list if its a node body. This time leave in the php tags ;).

if ($terms && !$teaser) { print yourthemename_print_terms($node, $vid = NULL, $unordered_list = TRUE);}
if ($terms && $teaser) { print yourthemename_print_terms($node, $vid = NULL, $unordered_list = FALSE);}

Again, be sure to replace 'yourthemename' with the actual name of your theme, or this will not work. You might want to enclose this snippet in your node template within a div with the appropriate class for your stylesheet.

Now, say you want to print the terms from just one vocabulary.

print yourthemename_print_terms($node, $vid = 3, $unordered_list = TRUE);

Or, let's say you find all this confusing and just want print the terms broken out by taxonomy:

print yourthemename_print_terms($node);

To move the Taxonomy terms into a block, create a block visible only on node pages and then paste in the following code:

$nid = arg(1);
print yourthemename_print_terms($nid);

Remember to change the input format to PHP.

Method B: (Drupal 5 ONLY)

Step one

Add the following snippet to your template.php file:


// split out taxonomy terms by vocabulary
function yourthemename_print_terms($nid) {
     $vocabularies = taxonomy_get_vocabularies();
     $output = '<ul>';
     foreach($vocabularies as $vocabulary) {
       if ($vocabularies) {
         $terms = taxonomy_node_get_terms_by_vocabulary($nid, $vocabulary->vid);
         if ($terms) {
           $links = array();
           $output .= '<li>' . check_plain($vocabulary->name) . ': ';
           foreach ($terms as $term) {
             $links[] = l($term->name, taxonomy_term_path($term), array('rel' => 'tag', 'title' => strip_tags($term->description)));
           }
           $output .= implode(', ', $links);
           $output .= '</li>';
         }
       }
     }
     $output .= '</ul>';
     return $output;
}

$nid = arg(1);
print yourthemename_print_terms($nid);

Note: Be sure to replace 'yourthemename' with the actual name of your theme, or this will not work. [Remember, don't include the php tags if you already have them in your file.]

Step Two

Now add the following to your node.tpl.php file:

print yourthemename_print_terms($node->nid)

Again, be sure to replace 'yourthemename' with the actual name of your theme, or this will not work. You might want to enclose this snippet in your node template within a div with the appropriate class for your stylesheet.

To move the Taxonomy terms into a block, create a block visible only on node pages and then paste in the following code:

$nid = arg(1);
print yourthemename_print_terms($nid);

Remember to change the input format to PHP.

[Hat tip: styro]

Comments

JuliaKM’s picture

Thanks for the code. I ended up needing to be able to call each vocabulary individually since I didn't want to list all of my vocabularies on each node. To do this, I came up with the following code:

For template.php

<?php 
function mythemename_taxonomy_links($node, $vid) {

//if the current node has taxonomy terms, get them
  if (count($node->taxonomy)):

    $tags = array();
     foreach ($node->taxonomy as $term) {
	   if ($term->vid == $vid):
          $tags[] = l($term->name, taxonomy_term_path($term));
  		endif;
}
	if ($tags):
//get the vocabulary name and name it $name
    	$vocab = taxonomy_get_vocabulary($vid);
	    $name = $vocab->name;
        $output .= t("$name") . ": " . implode(' | ', $tags);
    endif;

  endif;

 	if ($output):
       return $output;
 	endif;

}
?>

For node.tpl.php

Note: 1 is the vid for the vocabulary I want to call.

<?php print mythemename_taxonomy_links($node, 1); ?>

Please let me know if you see a better way to do this.

Jody Lynn’s picture

function phptemplate_print_terms($nid) {
  $vocabularies = taxonomy_get_vocabularies();
  $items = array();
  if ($vocabularies) {
   foreach($vocabularies as $vocabulary) {
      $terms = taxonomy_node_get_terms_by_vocabulary($nid, $vocabulary->vid);
	    if ($terms) {
	      $links = array();
	      foreach ($terms as $term) {
	        $links[] = l($term->name, taxonomy_term_path($term), array('rel' => 'tag', 'title' => strip_tags($term->description)));
	      }
	      $output = implode(', ', $links);
	      $items[] = $vocabulary->name . ': '. $output;
	    }
	  }
   }
     return theme('item_list', $items);
} 

Then you need to change the $terms variable to use this function.
Use _phptemplate_variables to set

$vars['terms'] = phptemplate_print_terms($vars['nid']);

--Zivtech--

lrickard’s picture

The taxonomy_node_get_terms_by_vocabulary() api function has been changed in Drupal 6. Pass the $node object instead of $nid. (Compare Drupal 5 to Drupal 6 at api.drupal.org.) If you pass $nid in Drupal 6, the function will return an empty array.
http://api.drupal.org/api/function/taxonomy_node_get_terms_by_vocabulary

Thanks to Chill35 in the Drupal Theme Development forum:
http://drupal.org/node/297250

haroon373’s picture

i want to do this exactly same stuff with module. Can i add this method or function in my custom created module?

Actually i make search form and i want to list taxonomy terms in my search module. I use form api to make the module.

plz tell me how can i list all terms in my custom module?

What will be the code looks like?

Sorry for my english and stupid question because i am totally newbi in drupal developement.

thanks in advance

cheers

NancyDru’s picture

Why not start with the handbook docs http://drupal.org/project/taxonomy_image which details how to do it. You may find that one of the add-ons will take care of you with no coding.

NancyDru’s picture

In all of the examples above, if you want the Taxonomy Image shown instead, change the l($term->name, taxonomy_term_path($term)) to taxonomy_image_display($term->tid).

NancyDru

JaceRider’s picture

Here is what I use in D6 to return a themed list of terms by vocabulary ID:


function yourthemename_taxonomy_links($node, $vid) {
  if (count($node->taxonomy)){
    $tags = array();
    foreach ($node->taxonomy as $term) {
       if ($term->vid == $vid){
          $tags[] = array('title' => $term->name, 'href' => taxonomy_term_path($term), 'attributes' => array('rel' => 'tag'));
       }
		}
    if ($tags){
      return theme_links($tags, array('class'=>'links inline'));
    }
  }
}

NancyDru’s picture

The Taxonomy Image add-on, TI_Link_Alter, has the option of sorting the links by vocabulary.

encho’s picture

How to do this exactly?

fivehimself’s picture

Add the code from JaceRider into your template.php

Then in your node.tpl.php add

<?php print yourthemename_taxonomy_links($node, $vid); ?>

Replace: yourthemename with your theme engine (in my case phptemplate) and $vid with the ID of the vocabulary you want to fetch the terms from.

If I want to show all the terms from the vocabulary with ID 1, I add:

<?php print phptemplate_taxonomy_links($node, 1); ?>
charlie-s’s picture

I'm having some major problems with taxonomy in nodes.

$terms appears to be empty
$node->taxonomy returns nothing

I've even done a prinr_r of $node to see everything that's in this tree of arrays and there isn't any taxonomy. Even passing $vid or $nid to the many functions I've found on drupal (including this one) and google continue to return NO taxonomy terms. I am running 6.12, using a custom zen stylesheet, and haven't hacked any portion of core or any modules that I'm using. Does anyone know how I can directly request terms from the sql database?

fivehimself’s picture

@charlie1234

Where did you add the

<?php print_r($node); ?>

Did you check with DEV Module if there are any terms loaded with the node?

CccXxx’s picture

@JaceRider
Perfect thank you very much I also wanted to achieve the same as you. All I changed was to include the alt tag for better seo.

$tags[] = array('title' => $term->name, 'href' => taxonomy_term_path($term), 'attributes' => array('rel' => 'tag', 'title' => strip_tags($term->description)));

smzur22’s picture

Thanks. This worked great.

Any ideas on how do I create a custom link out of this? I've tried removing the href-part and added a
<a href="?q=my_custom_link&tid=<?php print zen_theme_taxonomy_names($node, 10); ?>
to my .tpl.php-file. But with no luck. Is this because the outcome is themed or something?

Sorry,
I'm new to php-programming :)

501cGeek’s picture

Thanks JaceRider, that worked well for me. Here's how I tweaked it to return a plain text list of terms separated by a comma (or other arbitrary separator).

function yourthemename_taxonomy_list($node, $vid, $separator) {
  if (count($node->taxonomy)){
	$tags = array();
	foreach ($node->taxonomy as $term) {
	   if ($term->vid == $vid){
		  $tags[] = $term->name;
	   }
        }
	if ($tags){
	  return implode($separator, $tags);
	}
  }
}

Then call the function in the appropriate place in the template like so:
print yourthemename_taxonomy_list($node, 9, ', ');
where 9 is the desired vocabulary ID and a comma followed by a space is how you want to separate the taxonomy terms.

Matthew OMalley’s picture

To make this work in Drupal 6 (printing out all terms for each node preceded by vocabulary headings for all vocabularies), just change the function line to:

function yourthemename_print_terms($node)

and change the following line to use $node rather than $nide:

         $terms = taxonomy_node_get_terms_by_vocabulary($node, $vocabulary->vid);

Then in the node.tpl.php file, replace "print $terms" with:

print yourthemename_print_terms($node)

(remember to always replace "yourthemename" with your theme name in all files.)

The completed code for use in D6 is:

<?php
// split out taxonomy terms by vocabulary
function yourthemename_print_terms($node) {
     $vocabularies = taxonomy_get_vocabularies();
     $output = '<ul>';
     foreach($vocabularies as $vocabulary) {
       if ($vocabularies) {
         $terms = taxonomy_node_get_terms_by_vocabulary($node, $vocabulary->vid);
         if ($terms) {
           $links = array();
           $output .= '<li>' . $vocabulary->name . ': ';
           foreach ($terms as $term) {
             $links[] = l($term->name, taxonomy_term_path($term), array('rel' => 'tag', 'title' => strip_tags($term->description)));
           }
           $output .= implode(', ', $links);
           $output .= '</li>';
         }
       }
     }
     $output .= '</ul>';
     return $output;
}
?>
NancyDru’s picture

You don't need if ($vocabularies) -- you won't be in the loop if it has a zero count; the "foreach" takes care of that. Beyond that, you are getting all vocabularies allowed in the system, rather than just the ones that are used by that node ($node->taxonomy, ""). So how about something like (untested):

// Split out taxonomy terms by vocabulary.
function yourthemename_print_terms($node) {
  $vocabularies = taxonomy_get_vocabularies();
  $vocs = array();
  foreach ($vocabularies as $vocabulary) {
    $terms = taxonomy_node_get_terms_by_vocabulary($node, $vocabulary->vid);
    if ($terms) {
      $links = array();
      foreach ($terms as $term) {
        $links[] = l($term->name, taxonomy_term_path($term),
          array('rel' => 'tag', 'title' => strip_tags($term->description)));
      }
      // The 'children' element gives us a nested list.
      $vocs[] = array('data' => check_plain($vocabulary->name) . ': ', 'children' => $links);
    }
  }
  return theme('item_list', $vocs);
}
PlayfulWolf’s picture

corrected l() function

// Split out taxonomy terms by vocabulary.
function yourthemename_print_terms($node) {
  $vocabularies = taxonomy_get_vocabularies();
  $vocs = array();
  foreach ($vocabularies as $vocabulary) {
    $terms = taxonomy_node_get_terms_by_vocabulary($node, $vocabulary->vid);
    if ($terms) {
      $links = array();
      foreach ($terms as $term) {
        $links[] = l($term->name, taxonomy_term_path($term),
          array('attributes' => array('rel' => 'tag', 'title' => strip_tags($term->description))));
      }
      // The 'children' element gives us a nested list.
      $vocs[] = array('data' => check_plain($vocabulary->name) . ': ', 'children' => $links);
    }
  }
  return theme('item_list', $vocs);
}
bartezzini’s picture

Is there any chance to call a single vocabulary ID in node.template with this method?
Thx

PlayfulWolf’s picture

this works for 1 vocabulary

function yourthemename_print_terms ($node, $vid) {
  $vocabularies = taxonomy_get_vocabularies();
  $vocs = array();
    $terms = taxonomy_node_get_terms_by_vocabulary($node, $vid);
    if ($terms) {
      $links = array();
      foreach ($terms as $term) {
	  
        
			$links[] = l($term->name, taxonomy_term_path($term), array('attributes' => array('rel' => 'tag', 'title' => strip_tags($term->description))));
			$output .= implode(', ', $links);
 }
 
 
      
    }
  return $output;
}
Narretz’s picture

Is it just me or does this not work for translated taxonomy terms? I have a vocabulary whose term names are translated into different languages. But with this function, only the original name is displayed. I tried both the Handbook versions and NancyDru's.

edit: Okay, this works for term and vocab string translation if your taxonomy translation option is "Localize terms. Terms are common for all languages, but their name and description may be localized." Specify each the $vid in the node.tpl.php when you call the function.
Code borrowed from i18n_taxonomy. I am not 100% sure if this is the right way to do it, so caution is advised. You can copy the lines to the code in the handbook page as well.

// Split out taxonomy terms by vocabulary.
function yourthemename_print_terms($node, $vid) {
  $vocabularies = taxonomy_get_vocabularies();
  $vocs = array();
   foreach($vocabularies as $vocabulary) {
    $terms = taxonomy_node_get_terms_by_vocabulary($node, $vocabulary->vid);
        // Get the translated strings for the term names
	$terms = i18ntaxonomy_localize_terms($terms, $fields = array('name'));
    if ($terms) {
      $links = array();
      foreach ($terms as $term) {
        $links[] = l($term->name, taxonomy_term_path($term),
          array('attributes' => array('rel' => 'tag', 'title' => strip_tags($term->description))));
      }
      // Get the translated string for the vocab name	 
      $vname = i18nstrings("taxonomy:vocabulary:$vid:name", $vocabulary->name);
      // The 'children' element gives us a nested list.
      $vocs[] = array('data' => check_plain($vocabulary->name) . ': ', 'children' => $links);
    }
  }
  return theme('item_list', $vocs);
}
NancyDru’s picture

From what little I know of coding for i18n, it looks pretty good. As you can see, the hoops to jump through here are more than many module developers want to do, so term translation is lagging. When core and i18n get more transparent, this issue will go away.

eiland’s picture

ej Naaretz, I coudlnt get your code to work, so i rewrote it a bit:

// split out taxonomy terms by vocabulary respecting i18n

function YOURTHEMENAME_print_terms($node) {
  $vocabularies = taxonomy_get_vocabularies();
  $vocs = array();
   foreach($vocabularies as $vocabulary) {
    $terms = taxonomy_node_get_terms_by_vocabulary($node, $vocabulary->vid);
        // Get the translated strings for the term names
    $terms = i18ntaxonomy_localize_terms($terms, $fields = array('name'));
    if ($terms) {
      $links = array();
      foreach ($terms as $term) {
        $links[] = l($term->name, taxonomy_term_path($term),
          array('attributes' => array('rel' => 'tag', 'title' => strip_tags($term->description))));
      }
      // Get the translated string for the vocab name    
        $vname=i18nstrings("taxonomy:vocabulary:$vocabulary->vid:name", "");

      // if in the default language or no translated string given  
      if ($vname=="") $vname=$vocabulary->name;

      // The 'children' element gives us a nested list.
      $vocs[] = array('data' => check_plain($vname) .":", 'children' => $links);
    }
  }
// return the list, not styled, that takes too much space.
foreach ($vocs as $hit)
{
    echo $hit['data']." ". implode($hit['children'],", "). "<br>";
}

return ;
}

And I only need to call YOURTHEMENAME_print_terms($node); in node.tpl.php

Jovean’s picture

I wanted a bit more control in theming, without having to write too much more CSS than I already have. So here is my (6.x) version.

<?php
function yourtheme_print_terms($node, $inline = FALSE){
	$vocabularies = taxonomy_get_vocabularies();
	$output = '<div class="terms' . ($inline ? ' terms-inline': '') . '">';
	$inline_class = $inline ? ' inline' : '';
	foreach($vocabularies as $vocabulary){
		if($terms = taxonomy_node_get_terms_by_vocabulary($node, $vocabulary->vid)){
			$vocab = strtolower(str_replace(' ', '_', str_replace('.', '',$vocabulary->name)));
			$output .= '<ul class="links' . $inline_class . ' vocabulary ' . $vocab . '-terms">';
			foreach ($terms as $term){
				$output .= '<li class="term ' . $vocab . '-term ' . 'term-'. strtolower(str_replace(' ', "_", str_replace('.', '',$term->name))) . '">';
				$output .= l($term->name, taxonomy_term_path($term), array('rel' => 'tag', 'title' => strip_tags($term->description)));
				$output .= '</li>';
			}
			$output .= '</ul>';
		}
	}
	$output .= '</div>';
	return $output;
}?>

This function takes an optional second argument, any ==TRUE value will add tags for inline list theming.
I changed the original spans to ul's, with the same structure as the default returned by print $terms, except that different vocabularies are split into sibling ul's.
I also added "vocabulary" and "term" classes, as well as [vocabulary]-terms and [vocabulary]-term, and term-[term] classes as appropriate to ul's and li's - after replacing spaces with underscores, removing periods, and lowercase-ing the vocabulary and term.

betarobot’s picture

I've checked out previous comments. But had to remix code to my taste. Here are some features:

  • Suggested in http://drupal.org/node/133223#comment-3245288 was my starting point, but output would rewrite core taxonomy classes. I think it's a bad idea as your user may just rename taxonomy term and you'll have to change the css for this term (if it was styled). My version sticks to standard drupal 'taxonomy_term_00' tid based approach.
  • Some other variations would also miss nice core ul.links.inline trend. But with .links.inline you don't even need to style your new taxonomy output any special. It's already in core CSS

Here we go, this code goes to your template.php:

<?php
function YOURTHEME_print_terms($node){
	$vocabularies = taxonomy_get_vocabularies();
	foreach($vocabularies as $vocabulary){
		if($terms = taxonomy_node_get_terms_by_vocabulary($node, $vocabulary->vid)){
			$output .= '<div>';
			$output .= '<span>'. $vocabulary->name . ': </span>';
			$output .= '<ul class="links inline">';
			foreach ($terms as $term){
				$output .= '<li class="taxonomy_term_' . $term->tid . '">';
				$output .= l($term->name, taxonomy_term_path($term), array('rel' => 'tag', 'title' => strip_tags($term->description)));
				$output .= '</li>';
			}
			$output .= '</ul>';
			$output .= '</div>';
		}
	}
	return $output;
}
?>

I wanted a bit more class + reusable code for subthemes. So I've added this bit of preprocess to template.php:

<?php
function YOURTHEME_preprocess_node(&$vars, $hook) {
	//split terms by vocabulary
	$vars['terms_split'] = YOURTHEME_print_terms($vars['node']);
}
?>

Now to get your terms split by vocabularies just add to your node.tpl.php:
<?php print $terms_split; ?>

Or if you still want to print stacked terms, it is still there:

<?php print $terms; ?>

Have fun!

custom drupal themes

NancyDru’s picture

Try the Taxonomy Link Mover module.

jonthomas83’s picture

Hi betarobot, really like your solution, have used it for my site, instead of using ul and li's I've used spans so they display inline, but I would like to split the tags/terms with a ', ' Can you let me know how I'd do this and where I'd put it in your code please.

Many thanks

NancyDru’s picture

<ul class="links inline"> should display inline - this is how core does it.

Build them in an array, rather than just outputting them. At the end of the loop, use an implode(', ', $my_term_array).

jonthomas83’s picture

Thanks Nancy Dru, I tried outputting it as an array but I got an output that was just wrong

e.g.
Vacab1: Term 1
Vacab2: Term 1, Term 2
Vacab3: Term 1, Term 2, Term 3

Really strange, it just kept on adding to itself.

Anyway, I managed to get what I wanted by doing the following:

 function myTheme_print_terms($node){
    $vocabularies = taxonomy_get_vocabularies();
    foreach($vocabularies as $vocabulary){
        if($terms = taxonomy_node_get_terms_by_vocabulary($node, $vocabulary->vid)){
            $output .= '<div class="field">';
            $output .= '<span class="field-label-inline-first">'. $vocabulary->name . ': </span>';
            $sep = '';
            foreach ($terms as $term){
                $output .= $sep.'<span class="taxonomy_term_' . $term->tid . '">';
                $output .= l($term->name, taxonomy_term_path($term), array('rel' => 'tag', 'title' => strip_tags($term->description)));
                $output .= '</span>';
                $sep=', ';
            }
            $output .= '</div>';
        }
    }
    return $output;
}

Using the '$sep;' variable to add the comma as necessary.

NancyDru’s picture

You didn't do what I suggested. See duckzland's reply below.

jonthomas83’s picture

Thanks Nancy, I've done that, but what do I put in node.tpl.php?

duckzland’s picture

if you are using my function, you can put this in node.tpl.php

print print_terms($node);

--------------------------------------------------------------------------------------------------------
if you can use drupal why use others?
VicTheme.com

jonthomas83’s picture

Thank you duckzland, I didn't realise I could just revert to the usual way of doing things, will try it when I get home tonight, much appreciated. Nice and easy! :)

snecci’s picture

Thanks.

duckzland’s picture

Slightly modified to use theme_item_list as the output

function print_terms($node) {
    $vocabularies = taxonomy_get_vocabularies();
    foreach($vocabularies as $vocabulary){
        if($terms = taxonomy_node_get_terms_by_vocabulary($node, $vocabulary->vid)){
            $title = $vocabulary->name;
           unset($links);
            foreach ($terms as $term){
              $links[] = l($term->name, taxonomy_term_path($term), array('rel' => 'tag', 'title' => strip_tags($term->description)));
            }
	$output .= theme('item_list', $links, $title);
        }
    	
   }
    return $output;
}

--------------------------------------------------------------------------------------------------------
if you can use drupal why use others?
VicTheme.com

Larry_H’s picture

I currently have the tags for a node displayed by vocabulary, the change I would like to make is also have the hierarchy display:

Vocabulary: Term ==> Child Term ==> Child Term
Term
Term ==> Child Term

Vocabulary 2: Term

Can you help me with this?

thanx

Summit’s picture

Subscribing, greetings, Martijn

qwckbrwnfx’s picture

Hey there,

This function is great! I have been trying the last several days to make it work a little differently, I hope someone can help! I am using this to override default $terms output in a custom node-contenttype-tpl.php file.

I would like this function to accept another argument of VID (actually, multiple VIDs), either in the function itself or when displaying it in my node tpl. I hope to be able to only list terms/vocab labels from vocabularies I specify, instead of all of them for this node.

I will write what I have done, and what's not working -- I think my lack of PHP knowledge is the problem. Maybe someone will get a good laugh!

1. I changed the funtion to have a $vid argument too:
function print_terms($node) {
to
function print_terms($node, $vid) {

2. I changed
if($terms = taxonomy_node_get_terms_by_vocabulary($node, $vocabulary->vid)){
to
if($terms = taxonomy_node_get_terms_by_vocabulary($node, $vid)){
Is that okay to do?

3. I changed my template code to have a vid argument (where 10 is an example of a vocab ID):
<?php print print_terms($node, 10); ?>

Now only the terms from vocabulary 10 are listed, but because of the foreach, I get a list of every vocabulary as a label for the terms in Vocab 10.

Example:
Vocab 1: Term1, Term2 (where term1 and term2 are from Vocab 10)
Vocab 2: Term1, Term2 (where term1 and term2 are from Vocab 10)
Vocab 2: Term1, Term2 (where term1 and term2 are from Vocab 10)
...etc

The problems I hope for help with are:

- The foreach is what is causing that list to behave in that way. When I get rid of the foreach, it lists just the two terms in Vocab 10 (great!), but there is no longer any label (Vocabulary name) -- just the two terms. I can't seem to figure out how to code this correctly.

- I cannot figure out how to make this work with multiple vocabularies, for example with Vocab 10 and Vocab 9. Is there a way to put in multiple VIDs as arguments for this funtion?

In the end, I am hoping to be able to separatly call specified groups of Vocabularies in my template with something like

<div class="example-group-1">
<?php print print_terms($node, 3, 4, 5); ?>
</div>

<div class="example-group-2">
<?php print print_terms($node, 9, 10, 11); ?>
</div>

<div class="example-group-2">
<?php print print_terms($node, 12, 13, 14 etc); ?> (all the rest of the vocabs)
</div>

Hope that someone out there can help! And thanks for this little function, it's very useful. Let me know if there's any other info I can provide that would help.

:-)

duckzland’s picture

just a quick change based on your spec, I havent tried them so it may not work

// $vids should be an array like $vids = array(1,2,3,4); or empty $vids to show all vid taxonomy term
function print_terms($node, $vids = FALSE) {
    $vocabularies = taxonomy_get_vocabularies();
    foreach($vocabularies as $vocabulary){
     if (in_array($vocabulary->vid, $vids) || empty($vids)) {
        if($terms = taxonomy_node_get_terms_by_vocabulary($node, $vocabulary->vid)){
            $title = $vocabulary->name;
           unset($links);
            foreach ($terms as $term){
              $links[] = l($term->name, taxonomy_term_path($term), array('rel' => 'tag', 'title' => strip_tags($term->description)));
            }     
           $output .= theme('item_list', $links, $title);
       }  
     }      
   }
    return $output;
}

it should be sorting the taxonomy based on $vids vid, other taxonomy outside the $vid will be ignored.

once again I havent test this code yet, so it may not work.

--------------------------------------------------------------------------------------------------------
if you can use drupal why use others?
VicTheme.com

qwckbrwnfx’s picture

Hi there, thanks for the code!

I gave it a try as is, and am getting the following error and no display of terms:
warning: in_array() [function.in-array]: Wrong datatype for second argument in /var/www/d6/sites/example/themes/mytheme/template.php on line 27.

I am using this code to display it in my template:
<?php print print_terms($node, 10); ?>

I am now looking through the function and the php documentation on in_array, which mentions this same error:
http://php.net/manual/en/function.in-array.php

Not sure if I can figure it out.

:-)

qwckbrwnfx’s picture

Hi again,

I think it was my template code that was causing that error. I started from scratch using exactly the function above again, with this as my template code now:

<?php print print_terms($node,$vids = array(8,9,10,11,12)); ?>

It's working perfectly! Thanks very much duckzland, it's amazing to have a solution!

duckzland’s picture

No problem, Glad to hear it is working for you.

--------------------------------------------------------------------------------------------------------
if you can use drupal why use others?
VicTheme.com

GiorgosK’s picture

try this module
http://drupal.org/project/term_display
probably does most of what has been discussed above

------
GiorgosK
Web Development

TapSkill’s picture

Trying to get the vocabulary name with
$vocab = taxonomy_get_vocabulary($vid);
freezes the page render and causes the page to cut off. I ended up adding the following code instead so i could manually set my vocabulary name:

function templatename_taxonomy_links($node, $vid, $nameofvoc="") {

//if the current node has taxonomy terms, get them
  if (count($node->taxonomy)) {

    $tags = array();
    foreach ($node->taxonomy as $term) {
       if ($term->vid == $vid):
          $tags[] = l($term->name, taxonomy_term_path($term), array('rel' => 'tag', 'title' => strip_tags($term->description)));
          endif;
	}
    if ($tags) {
//get the vocabulary name and name it $name
		if ($nameofvoc=="") {
			$vocab = taxonomy_get_vocabulary($vid);
			$name = $vocab->name;
		} else {
			$name = $nameofvoc;
		}
        $output = "<div class=\"section\">".t("$name") . ":</strong><br />" . implode(' | ', $tags)."</div>";
       return $output;
    }

 } else {
   return;
 }

}

Here's what you put in the node template:
<?php print templatename_taxonomy_links($node, 1, "vocabulary name goes here"); ?>
It is a temporary fix, I know. I want to actually fix the problem and not have to resort to this work-around.

---
I have created and maintained countless Drupal-powered sites and have made heavy modifications to modules on a site-by-site basis. I am an illustrator, a game developer, and a web developer. I also stream on Twitch in my spare time.

nehasapra1’s picture

I need to display all the terms of the taxanomy on one page.Please help me out.

Thanks in advance

charlie-s’s picture

nehasapra1: You should try posting this question in the forum or on IRC. But functions exist to do this, you would just build a small module (this is easier than it sounds) and print out the results of the function taxonomy_get_tree() (http://api.drupal.org/api/drupal/modules--taxonomy--taxonomy.module/func...) OR just build a View the prints out all taxonomy terms from a specified vocabulary!

nehasapra1’s picture

Thanks for the help

paultrotter50’s picture

To hide certain taxonomy vocabularies from a node is D6 GiorgosK's suggested module worked well for me: http://drupal.org/project/term_display

There isn't really any documentation for it, but basically you go to /admin/content/taxonomy/ and edit the vocabulary you wish to hide and in the display options choose display style: none.