Posted by Tim-Erwin on September 13, 2010 at 1:39pm
Hi,
I'd like to create a block which shows a list of items related to the current node. I know how to do this in Drupal 6: views with an argument with taxonomy_node_get_terms(). However, this function does not exist in Drupal 7.
What is the correct way to get the terms associated to a node in Drupal 7?
Is there even a better way? I noticed the option "Load default argument from node page, thats good for related taxonomy blocks." for the Taxonomy: Term ID argument. However, it doesn't seem to work (the option does not get saved).
Thanks
Tim
Comments
ugly solution
Well, I found a way:
$node = node_load(arg(1));
if ($node != NULL) {
$field = $node->field_my_vocabulary;
$terms_en = $field['en'];
foreach ($terms_en as $term) {
$terms[] = $term['tid'];
}
return implode('+', $terms);
}
In Drupal 7 taxonomies are stored in fields, in this example "field_my_vocabulary". This contains a language array of which each item contains the terms. It works.
What's ugly about it is the hard-coded "en" in line 4. Is there a more generic way?
Thanks for your solution. For
Thanks for your solution.
For the language I have tried doing the following:
$lang= $node->language;
$terms = $field[$lang];
What I don't know if it would work with multilanguage sites.. but for the sites set up for a language seems to work.
New SQL query
Hi,
I checked the code you were suggesting but debugging it I realized that the data that was returned was not the same that was obtaining with the taxonomy_get_term function.
In order to get a suitable solution I modified the query that is done in the function but taking into account the new tables in Drupal 7.
This is what the query looks like:
$result = db_query(
SELECT ttd.tid, ttd.vid, ttd.name, ttd.description, ttd.weight
FROM taxonomy_term_data AS ttd
INNER JOIN taxonomy_index ti ON ti.tid = ttd.tid
WHERE ti.nid= :nid
ORDER BY ttd.weight, ttd.name',array(':nid' =>$node->nid));
Now the returned data looks like what one obtained by the function in Drupal 6.
saved by Pro Drupal 7 Development
A variation on the following worked for me, (credit goes to page 355 of Pro Drupal 7 Development):
<?php$nid = 2;
$node = node_load($nid);
$result = field_view_field('node', $node, 'field_tags', array('default'));
print render($result);
?>
--
Drupal 6 Theming Cheat Sheet
Matt - What is the variation
Matt -
What is the variation you used? This returns the rendered field with field label. How would one get just the field values? I'm trying to convert the following to D7 in order to have a related content block view:
$node=node_load(arg(1));
if($node){
foreach($node->taxonomy as $term){$terms[]=$term->tid;}
return implode('+',$terms);
}else {return;}
ah Drupal, so easy and SO
ah Drupal, so easy and SO COMPLICATED!!
Here's how to get the taxonomy name; I don't know if it will work for everybody. Using the various variations of code in this thread and exhaustive foreach'ing, I found the following print statement after calling 'field_view_field':
$result = field_view_field('node', $node, 'field_tags', array('default'));print $result['#object']->field_tags['und'][0]['taxonomy_term']->name;
I'll post the code I used to find that so that you can all get to the same solution even if your system is set up differently. Here are the steps:
1)Seeing the taxonomy name is easy:
$result = field_view_field('node', $node, 'field_tags', array('default'));
print render($result);
2) What is render doing? After the code in step 1, I printed the array to see where the name was coming from:
print_r($result);3) A little bit much, how about this:
print_r($result['#object']);4)Now we're getting somewhere. We only want the tags though so only look at 'field_tags' key.
foreach ($result['#object'] as $key => $field){ //looking through objectif ($key == 'field_tags') { //ah HA! must be here somewere
print_r($field);
print $field['und'][0]['tid']; //there's the taxonomy ID! no name though
}
}
5) The TID is easy to get. Now we find the name itself. There's another embedded object in there so the following code goes inside the IF statement in step 4:
foreach ($field['und'] as $term => $termInfo) { //was inside 'und', why?!print $termInfo['tid']; // got the ID!!
print_r($termInfo);
}
6) Finally, we can see the name inside the 'taxonomy_term' object with a 'print_r'. Here's that foreach again, but modified to show what we are looking for.
foreach ($field['und'] as $term => $termInfo) { //was inside 'und', why?!print $termInfo['taxonomy_term']->name ."<br>";
}
These steps should let you see all taxonomies, but I only have one. The name is therefor inside the 'taxonomy_term', of the first array inside the 'und' key field of the field_tags array, which is inside the '#object' field of the result from field_view_field().
print $result['#object']->field_tags['und'][0]['taxonomy_term']->name;
Easy right? XD
Works for me. But I want to
Works for me. But I want to have only the plain term name to get printed. Any idea? Thnx
Markus
An answer
An answer from #959984: taxonomy_node_get_terms doesn't work with drupal 7
function taxonomy_node_get_terms($node, $key = 'tid') {static $terms;
if (!isset($terms[$node->vid][$key])) {
$query = db_select('taxonomy_index', 'r');
$t_alias = $query->join('taxonomy_term_data', 't', 'r.tid = t.tid');
$v_alias = $query->join('taxonomy_vocabulary', 'v', 't.vid = v.vid');
$query->fields( $t_alias );
$query->condition("r.nid", $node->nid);
$result = $query->execute();
$terms[$node->vid][$key] = array();
foreach ($result as $term) {
$terms[$node->vid][$key][$term->$key] = $term;
}
}
return $terms[$node->vid][$key];
}
For non-php programmers, I believe that CCK Blocks module can do this for you, but it will only display one field per block, not ALL terms for the node.
Scott Jackson
Wollongong NSW Australia
Thanks for pointing me in the right direction
Scott,
Thanks for the update with link to that discussion. I've been struggling with this (finding terms associated with current node) in template.php for several days and was beginning to question my sanity. That discussion thread sheds a great deal of light on the issue.
Cheers,
Andrew
hi tim ;)
hi tim ;)
--
keine zeit für spielkonsolen mein leben ist jump n run!
valderama.net
I'd love to see a reason as
I'd love to see a reason as to why this function was removed, I can't seem to get anything to work correctly anymore. I understand taxonomy was revamped and changed a fair bit, but i'm sure the function could of been modified.
Doing such a simple task has become way to complicated and difficult it's to the point it's ridiculous.
Completely agree
How does the taxonomy module not support returning all terms for a node? It's kind of ridiculous that any module that wants to get the term names for a node has to manually muck through the db to grab the information. Sure all fields are automatically loaded with node_load, but in no way are they marked as being taxonomy terms.
For anyone who is interested
For anyone who is interested this can be accomplished with the use of Views and a contextual filter.
This basically will force the results to be node specific so add a contextual filter : Content: Nid.
"When the filter value is NOT in the URL"
-> Provide default value
- Type: PHP Code
- PHP contextual filter code: return arg(1);
Thanks
Thanks that work for me very well!!!
Many Thanks!
THANKS FOR ALL THE SOLUTIONS!
here's the version to display all the tags seperated by ',' as string stored in $tags variable.
NOTE:
i pasted the codes into my theme's node.tpl.php file
you can paste the code under your block or article body with php filters
DRUPAL 7:
<?php
$result = field_view_field('node', $node, 'field_tags', array('default'));
$arrItems = $result['#object']->field_tags['und'];
$tags="";
$i = 0;
foreach($arrItems as $new){
if( $i < count($arrItems) && $i > 0){
$tags .= ",";
}
$tags .= $arrItems[$i]['taxonomy_term']->name;
$i++;
}
print $tags;
?>
That's great - and this does
That's great - and this does the same thing but with a bit less PHP:
<?php
$result = field_view_field('node', $node, 'field_tags', array('default'));
$terms = $result['#object']->field_tags['und'];
$tags = array();
foreach($terms as $term){
array_push( $tags, $term['taxonomy_term']->name );
}
print implode(',', $tags);
?>
page template or region template
Thanks to everyone this was helpful. I found I needed a two slight variations to work in page and sidebar templates..
// following code helps to retreive the taxomony name tags FROM region(sidebar) templates.
$node = node_load(arg(1));
if ($node != NULL){
$field = $node->field_pageterms;
$terms_und = $field['und'];
foreach ($field['und'] as $term => $termInfo) { //was inside 'und', why?!
$tagName = $termInfo['taxonomy_term']->name;
}
}
OR
// following code helps to retreive the taxomony name tags FROM PAGE templates.
$result = field_view_field('node', $node, 'field_pageterms', array('default'));
foreach ($result['#object'] as $key => $field){ //looking through object
if ($key == 'field_pageterms') { //ah HA! must be here somewere
foreach ($field['und'] as $term => $termInfo) { //was inside 'und', why?!
$sidebar = $termInfo['taxonomy_term']->name;
}
}
}