sort taxonony links ($terms) by vocabulary ($vid)
[Note: An alternative method using template.php can be found here: http://drupal.org/node/133223 ]
I figured out a way to sort term links by vocab - this actually works (!) in node.tpl.php 465 (that's only for phphtemplate themes). It does look a bit clumsy - If anyone can tidy it up a bit I'd be very grateful. It probably belongs in the template.php really ... but I'm happy to just have it working at all!
What it does is create a new set of links for each vocab group of terms rather than just having all terms in a single row. eg the code below would produce something like:
# Submitted by: JohnG on 08 Mar 2006
# Forums: newbies - hacking - drupal
# Articles: contributed - in good faith - GPL
Please note, that the code below only processes terms for a single vocab each time - in the example (vid) 27 and 28. You need to replace all the occurrances of 27 with the vid of your favourite vocab.
You can copy&paste these code-chunks as often as you like to cover all your vocabs if you like, as long as you remember to edit all the '27's correctly it will work.
One more thing, I put all instances of this vocab filter script between the <?php if ($terms): ?> ... <?php endif; ?> tags and it works happily.
so it goes something like:
<?php if ($terms): ?><?php /* sort taxonomy links by vocabulary 27 */
$terms27 = taxonomy_node_get_terms_by_vocabulary($node->nid, 27);
if ($terms27) {
print '<div class="terms">Forums: ';
foreach ($terms27 as $key => $term27) {
$lterm27 = l($term27->name, 'taxonomy/term/'.$term27->tid);
print $lterm27.' - ';
}
print '</div>';
}
?><?php /* sort taxonomy links by vocabulary 28 */
$terms28 = taxonomy_node_get_terms_by_vocabulary($node->nid, 28);
if ($terms28) {
print '<div class="terms">Articles: ';
foreach ($terms28 as $key => $term28) {
$lterm28 = l($term28->name, 'taxonomy/term/'.$term28->tid);
print $lterm28.' - ';
}
print '</div>';
}
?>repeat for each vocab vid as needed and then close the
<?php
if ($terms):
?><?php endif; ?>enjoy!

Generic version
If you want a more generic version of this the following code will loop through all vocabularies and output the related terms:
<?php if ($terms): ?><?php
$vocabularies = taxonomy_get_vocabularies();
foreach($vocabularies as $vocabulary) {
if ($vocabularies) {
$terms = taxonomy_node_get_terms_by_vocabulary($node->nid, $vocabulary->vid);
if ($terms) {
print '<div class="terms"><h1>' . $vocabulary->name . ':</h1> ';
foreach ($terms as $term) {
print l($term->name, 'taxonomy/term/'.$term->tid) . ' ';
}
print '</div>';
}
}
}
?>
<?php endif; ?>
Cheers
Dave
tooltips
Thanks a lot for this code, I was looking exactly for this :-)
I made one single change. Normally categories will add the term description as a tooltip (title attribute), and the code above is not doing this. Just add one more parameter to the function that creates the link:
<?php...
print l($term->name, 'taxonomy/term/'.$term->tid, array('title' => $term->description) ) . ' ';
...
?>
Minor Thing
This is also exactly what I was looking for! Thank you!
Would it be possible to separate the multiple terms under the same vocab with a comma or straight bracket? Can you tweak the snippet? I would greatly appreciate it.
Sorry for the delay...!
If you haven't sorted this yet here is the code to add a comma - for a straight bracket change the comma on line that reads:
print l($term->name, 'taxonomy/term/'.$term->tid) . ', ';<?phpif ($terms):
?>
<?php
$vocabularies = taxonomy_get_vocabularies();
foreach($vocabularies as $vocabulary) {
if ($vocabularies) {
$terms = taxonomy_node_get_terms_by_vocabulary($node->nid, $vocabulary->vid);
if ($terms) {
print '<div class="terms"><h1>' . $vocabulary->name . ':</h1> ';
foreach ($terms as $term) {
print l($term->name, 'taxonomy/term/'.$term->tid) . ', ';
}
print '</div>';
}
}
}
?>
<?phpendif;
?>
Trim added
I just added a trim to remove the last separation:
<?php
$vocabularies = taxonomy_get_vocabularies();
foreach($vocabularies as $vocabulary) {
if ($vocabularies) {
$terms = taxonomy_node_get_terms_by_vocabulary($node->nid, $vocabulary->vid);
$termslist = '';
if ($terms) {
print '<div class="terms">' . $vocabulary->name . ': ';
foreach ($terms as $term) {
$termslist = $termslist.l($term->name, 'taxonomy/term/'.$term->tid) . ' | ';
}
print trim ($termslist," |").'</div>';
}
}
}
?>
And you can use the code at /node/38768 to get a solution for alpha sorting.
Now I use t() for terms
Now I use t() for terms too:
<?php$vid = 5; /* vocabulaire 5 = Fruits */
$result = db_query("SELECT t.tid, t.name FROM {term_data} t, {term_node} r WHERE r.tid = t.tid AND r.nid = %d AND t.vid = %d ORDER BY weight, name", array($node->nid, $vid));
while ($term = db_fetch_object($result)) {
$tags[] = l(t($term->name), 'taxonomy/term/' . $term->tid);
}
if ($tags) {
print t("Products") . ": " . implode(' | ', $tags);
}
?>
Using taxonomy_term_path
I modified the code to use taxonomy_term_path. This is for vocabularies 1 and 2:
<?php
$terms = taxonomy_node_get_terms_by_vocabulary($node->nid, 1);
foreach ($terms as $term) {
$tags[] = l($term->name, taxonomy_term_path($term));
}
print t("Vocab 1 Terms") . ": " . implode(' | ', $tags);
$terms = taxonomy_node_get_terms_by_vocabulary($node->nid, 2);
foreach ($terms as $term) {
$tagsTwo[] = l($term->name, taxonomy_term_path($term));
}
print t("Vocab 2 Terms") . ": " . implode(' | ', $tagsTwo);
?>
Sort terms when t() is used
To sort alphabetically terms for i18n sites, I just tried to apply asort to the $tags array. I then needn't anymore of my previous use of db_query(). It works but not when l() is used. The following code then doesn't display hyperlinks of terms, it just displays the terms as text.
The following sample if for the vocabulary 5.
<?php$vid = 5; /* vocabulaire 5 = Fruits */
$terms = taxonomy_node_get_terms_by_vocabulary($node->nid, $vid);
foreach ($terms as $term) {
$tags[] = t($term->name) ;
}
if ($tags) {
asort($tags);
print t("Products") . ": " . implode(' | ', $tags);
}
?>
I don't know how to sort $tag if
$tags[] = l(t($term->name), taxonomy_term_path($term));
Ronan
semantic markup
Thanks all, this is a very useful snippet. I made a small change, for those who care about the semantic web: I put the results in a definition list. My code:
<dl class="taxonomy">
<?php
$vocabularies = taxonomy_get_vocabularies();
foreach($vocabularies as $vocabulary) {
if ($vocabularies) {
$terms = taxonomy_node_get_terms_by_vocabulary($node->nid, $vocabulary->vid);
$termslist = '';
if ($terms) {
print '<dt class="vocabulary-name">' . $vocabulary->name . ':</dt><div class="vocabulary-terms">';
foreach ($terms as $term) {
print '<dd class="term-name">'.l($term->name, 'taxonomy/term/'.$term->tid) . '</dd>';
}
print '</div>';
}
}
}
?>
</dl>
...
$vocabularies = taxonomy_get_vocabularies();[...]
$terms = taxonomy_node_get_terms_by_vocabulary(...);
Just to let you know: these add extra SQL queries to your page (they are not cached).
And instead of:
l($term->name, 'taxonomy/term/'.$term->tid, ...)Better use:
l($term->name, taxonomy_term_path($term->tid), ...)(So that 'forum.module' and 'image_gallery.module' and lots other can specialize the link.)
Drupal6?
Is there anyway do update this to work with drupal6 too?
Thx
Drupal 6
Works for me in D6...
<?phpif ($terms):
// replace '4' with your vocabulary ID
$terms = taxonomy_node_get_terms_by_vocabulary($node, 4);
if ($terms) {
foreach ($terms as $key => $term) {
$items[] = l($term->name, taxonomy_term_path($term), array('attributes' => array('rel' => 'tag', 'title' => $term->description)));
}
print '<p>' . t("Filed in: ") . implode(', ', $items) . '</p>';
// alternativle comment out the above and uncomment the following to theme as an item list.
//print theme('item_list', $items);
}
endif;
?>
Problem
I got a problem with this snippet:
I got 2 taxonomy term, with this snippet when I print the first one (number 1) everything is ok; but in the second call (taxomony term nr2) I have all the terms (taxonomy 1+2) and not the taxonomy 2 alone.
Any suggestion?
Arr, I see, yes me so lazy,
Arr, I see, yes me so lazy, sorry... wipped that out a bit too fast by the l@@ks..
See the "$items" bit, add the vocab id to it and it should solve your problem... i.e...
<?phpif (count($taxonomy)):
// replace '4' with your vocabulary ID
$terms = taxonomy_node_get_terms_by_vocabulary($node, 4);
if ($terms) {
foreach ($terms as $key => $term) {
$items4[] = l($term->name, taxonomy_term_path($term), array('attributes' => array('rel' => 'tag', 'title' => $term->description)));
}
print '<p>' . t("Filed in: ") . implode(', ', $items4) . '</p>';
// alternatively theme as an item list.
//print theme('item_list', $items4);
}
endif;
?>