Hi,

If a node has 2 terms from different Vocabularies associated with it, I'd like to print just the term from 1 vocabulary using the vid.

For example:

Vocab 'Cars' terms = VW, BMW, Chrysler
Vocab 'Names' terms = Tom, Sam, Mark

My node is associated with terms VW and Mark and I want to print just VW in my node.tpl without also printing Mark.

Ideally I'd like to add something similar to getTerm('Car', 6); into my node and it return a string resembling:

  • Car:VW
  • Heres a example function in my template.php

    function getTerm($label, $vid) {
    if ( vid == $vid && node is using this term){// I cant figure out how to achieve this check
    	return "<li><strong>$label:</strong>$term</li>";
    }
    

    Any help is much appreciated!

    Thanks,
    Marc

    Comments

    nevets’s picture

    You need the node, do something like this may help

    <?php
    function getTerm($node, $label, $vid) {
      foreach( (array)$node->taxonomy as $term ) {
       if ( $term->vid == $vid ) {
        return "<li><strong>$label:</strong>$term->name</li>";
      }
    }
    ?>
    

    Note this version passes in the node

    Fiasst’s picture

    I've modified it a little to go into the template.php and also added a variable for printing the term with or without a link.

    So if anyone needs this and IMO everyone does at some point :]

    // in node:
    print getTerm('Term Label', 4, true);
    
    //in template.php
    function getTerm($label, $vid, $link) {
    	$node = node_load(array('nid'=>arg(1)));
    	foreach((array)$node->taxonomy as $term){
    		if ($term->vid == $vid){
    			if ($link){
    				return "<li><strong>$label:</strong> <a href=\"/taxonomy/term/$term->tid\" title=\"$term->name\">$term->name</a></li>";
    			} else {
    				return "<li><strong>$label:</strong> $term->name</li>";
    			}
    		}
    	}
    }
    

    thanks again!

    Fiasst’s picture

    It would be nice to extend on this some more.

    If there are two or more terms from the same vocab is it possible to add them to an array before implode(', ', $output).. and returning the result. I did try this but my template.php through up an error when I tried to implode the array.

    Marc

    nevets’s picture

    If you have more than one term in the vocabulary this will help

    // in node:
    print getTerm('Term Label', 4, true);
    
    //in template.php
    function getTerm($label, $vid, $link) {
        $node = node_load(array('nid'=>arg(1)));
        $links = array();
        foreach((array)$node->taxonomy as $term){
            if ($term->vid == $vid){
                if ($link){
                    $link_set[] = l($term->name, taxonomy_term_path($term) );
                } else {
                   $link_set[] = $term->name;
                }
            }
        }
        if ( ! empty($link_set) ) {
          print "<li><strong>$label:</strong>" . implode(', ', $link_set) . "</li>";
        }
         
    }
    

    This version collects the term name (linked or not) in an array and output the set at the end (if any terms). It also use the l() function to construct the link and used the taxonomy_term_path() to get the correct path to the term (this lets you decide to override the path later and still have a correct link).

    Side note, you do not provide a context for where you call getTerm() but if it is from node.tpl.php you already have a node variable ($node) that you can pass in. Also if you are going to use arg(1) because $node is not available you should make sure the context is correct to avoid errors. In this case you would wrap the bottom of the function in if ( arg(0) == 'node' && is_numeric(arg(1)) ) { .. existing code ... }. But as I said you can probably just pass $node.

    Fiasst’s picture

    I didn't add the numeric node->nid check because the function is only executed when called from my node so unless I'm wrong there will always be a numeric $node->nid in arg(1) for that function?

    I couldn't see why $links = array(); was there and it seems to work without it.

    Also replaced print with return because i was wrapping my getTerm() with list tags and the term that resulted would print after the tags in my node.

    moved the colon in label to be added in getTerm('label:', #, false); incase the label is a question with the term being the answer and so needing a question mark.

    // in node:
    print '<li class="foo">'.getTerm('Foo:', 4, false).'</li>';
    
    //in template.php
    function getTerm($label, $vid, $link) {
    	$node = node_load(array('nid'=>arg(1)));
    	foreach((array)$node->taxonomy as $term){
    		if ($term->vid == $vid){
    			if ($link){
    				$link_set[] = l($term->name, taxonomy_term_path($term));
    			} else {
    				$link_set[] = $term->name;
    			}
    		}
    	}
    	if (!empty($link_set)){
    		$label = ($label) ? "<strong>$label </strong>" : "";
    		$link_set = $label.implode(', ', $link_set);
    	}
    	return $link_set;
    }
    

    this is a very nice, flexible code thanks to you :]

    one thing I think is missing however. I have a locations vocab:
    England
    -London
    --Camden
    -Manchester
    -Surrey

    The node is printing the deepest term (Camden). It would be great if you could specify the depth to print with a number argument. what do you think?

    Thanks,
    Marc