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
A Modified Version
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
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.
Modified Method
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--
Use $node object in Drupal 6
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
i want to do this exactly same stuff with module. Can i add this
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
Well...
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
Taxonomy Image
In all of the examples above, if you want the Taxonomy Image shown instead, change the
l($term->name, taxonomy_term_path($term))
totaxonomy_image_display($term->tid)
.NancyDru
NancyDru
Drupal 6 by Vocabulary
Here is what I use in D6 to return a themed list of terms by vocabulary ID:
Taxonomy Image
The Taxonomy Image add-on, TI_Link_Alter, has the option of sorting the links by vocabulary.
NancyDru
How to do this exactly?
How to do this exactly?
Add the code from JaceRider
Add the code from JaceRider into your template.php
Then in your node.tpl.php add
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:
I'm having some major
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?
@charlie1234 Where did you
@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?
Perfect thank you very much I
@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)));
Custom links?
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 :)
same as above, returned as comma separated text (not links)
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).
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.
Drupal 6 version
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:
and change the following line to use $node rather than $nide:
Then in the node.tpl.php file, replace "print $terms" with:
(remember to always replace "yourthemename" with your theme name in all files.)
The completed code for use in D6 is:
Oops...
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):NancyDru
corrected l()
corrected l() function
Separate ID in dode
Is there any chance to call a single vocabulary ID in node.template with this method?
Thx
this works for 1
this works for 1 vocabulary
Code for localized taxonomies
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.
On the right track
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.
NancyDru
different i18n taxonomy lister
ej Naaretz, I coudlnt get your code to work, so i rewrote it a bit:
And I only need to call
YOURTHEMENAME_print_terms($node);
in node.tpl.phpYet Another Version
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.
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.
D6 version with core styles
I've checked out previous comments. But had to remix code to my taste. Here are some features:
Here we go, this code goes to your template.php:
I wanted a bit more class + reusable code for subthemes. So I've added this bit of preprocess to template.php:
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
Cheers,
Andrey
Free and Premium Drupal Themes | Drupal Sites Showcase. Add yours! | My Blog
Or...
Try the Taxonomy Link Mover module.
NancyDru
Hi betarobot, really like
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
Well...
<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)
.NancyDru
Splitting the terms with a comma (e.g. ', ')
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:
Using the '$sep;' variable to add the comma as necessary.
Well...
You didn't do what I suggested. See duckzland's reply below.
NancyDru
Thanks Nancy, I've done that,
Thanks Nancy, I've done that, but what do I put in node.tpl.php?
if you are using my function,
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
Thank you duckzland, I didn't
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! :)
worked perfectly
Thanks.
Slightly modified to use
Slightly modified to use theme_item_list as the output
--------------------------------------------------------------------------------------------------------
if you can use drupal why use others?
VicTheme.com
Tree-like display
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
Subscribing, greetings,
Subscribing, greetings, Martijn
Can multiple VIDs be added as arguments?
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
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.
:-)
just a quick change based on
just a quick change based on your spec, I havent tried them so it may not work
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
Tried this out, getting php error
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.
:-)
It works!
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!
No problem, Glad to hear it
No problem, Glad to hear it is working for you.
--------------------------------------------------------------------------------------------------------
if you can use drupal why use others?
VicTheme.com
try this
try this module
http://drupal.org/project/term_display
probably does most of what has been discussed above
------
GiorgosK
Web Development
error
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:
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.
Taxanomy tems in one page
I need to display all the terms of the taxanomy on one page.Please help me out.
Thanks in advance
nehasapra1: You should try
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!
Thanks for the help
Thanks for the help
Hide certain taxonomy vocabularies from a node
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.