Hi All,

I'm trying to build a block that shows the related nodes to the current node by taxonomy term. For example: If the current node in display has a taxonomy term "fish", a bunch of links that link to nodes that have the "fish" term is to be shown in a block on the page.

I have looked all over the forums and the handbook, and I did not see this addressed before.

I have worked out how to get the related nodes by category using the book page at http://drupal.org/node/2498 . But my question is how do I get the current nodes taxonomy terms from that Block?

Any ideas?

Comments

nedjo’s picture


if (arg(0) == 'node' && is_numeric(arg(1)) && is_null(arg(2))) {
  $terms = taxonomy_node_get_terms(arg(1));
}

chandika’s picture

Thanks nedjo. Now the block works great. It displays top 5 related nodes by the taxonomy term. The code is below if someone else is looking for something similar.

if (arg(0) == 'node' && is_numeric(arg(1)) && is_null(arg(2))) {
  $terms = taxonomy_node_get_terms(arg(1));

	$output .= "<ul>";
	foreach($terms as $term){


	//$taxo_id = 7;
	$sql = "SELECT node.title, node.nid FROM node INNER JOIN term_node ON node.nid = term_node.nid WHERE term_node.tid = $term->tid LIMIT 5";
  	
	$result = db_query($sql);
	while ($anode = db_fetch_object($result)) {
  		$output .= "<li>".l($anode->title, "node/$anode->nid")."</li>";
	}
  	
	}
	$output .= "</ul>";
	return $output;
}
pwolanin’s picture

adapted as a PHP snippet: http://drupal.org/node/76923

---
Work: BioRAFT

enes-1’s picture

This is great but is there a way to display terms from only one specific vocabulary, I have one node related to three vocabularies but want to display links just from one of them?

nishitdas’s picture

Did you get a solution for the above ??
I am exactly looking for the same.

jeffreyvddb’s picture

Same question as above: did someone already find a solution for getting the terms of one specific vocabulary?

soulston’s picture

taxonomy_node_get_terms_by_vocabulary($node, $vid, $key = 'tid')

http://drupalcontrib.org/api/drupal/drupal--modules--taxonomy--taxonomy....

mhd’s picture

Hi,

Is there anyway I put this code just below the node's content? I don't want to it's as a block, and making it part of a footer just seems silly. I tried pasting this code in page template and node template but none of it works.

greggles’s picture

Is there a solution for situations where you don't have URLs like "node/10". Speciflcally I use pathauto for all my nodes - I'm trying to think of a way to adapt this for the situation where the url is something like

"category/title-of-node"

Any ideas?
Greg

--
Growing Venture Solutions
Drupal Implementation and Support in Denver, CO

nevets’s picture

Use of arg(n) reflects unaliased name so the use of arg(0), arg(1), etc should even work if paths are aliased.

DayShallCome’s picture

Is this possible in the Views module? I've never quite understood how to do something like this in Views, so if you guys have any suggestions, I would appreciate it. Thanks.

afagioli’s picture

In these cases, the $n object is very handy...

what do you get from this?
echo "[".$node->nid ."]";

I've used the function above for a "very standard" translation at http://roma.cercachetrovi.it/ using a taxonomy vocabulaty "Language"

greggles’s picture

nevets comment two above this one solved my problem. I should have posted back - my bad.

--
Knaddison Family | mmm Free Range Burritos

mattconnolly’s picture

I found a nice way too, and that is to implement a hook_nodeapi function, intercepting a 'load' with a node of matching 'type' (or other condition), and then sets a global variable describing the node.

The block can simply check if the global variable is set, and can get whatever data it likes from the node through the variable.

Advantage here is that you don't need to read the url - which is nice when the url path is mapped by another module.

The only caveat I see is that it relies on drupal loading the node before building the blocks. This is how it works in Drupal 6.x.

TheDanScott’s picture

Hi all,

I've been working through the same issue myself today, but I'm fairly new to drupal so I don't know if my approach is considered "kosher" or not.

From what I can tell, the approach shown above (checking arg(0) = node and arg(1) contains a numeric ID) is very much tied to the path /node/X, or any alias that refers to it.

On the site I'm working on, I built myself a custom "catalog" module and registered a couple of menu callbacks - one of which is /resources/item/%node. That path displays nodes of a particular type and does a bit of custom tweaking of the breadcrumb (to include parent taxonomy terms etc). The site still supports the /node/X path because it seems unfeasible to remove it - particularly since various modules, like the developer module rely on it. Also editing nodes always sends a user back to /node/X/edit when the save or preview buttons are clicked.

All of this means I need an approach (in my "node terms" block) that isn't tied to a particular path structure. So, I came up with this (for Drupal 6 - not sure if it will work in Drupal 5):

	// STEP 1: Get current menu item (includes path arguments converted to 
	//         objects, as loaded by xxx_load functions);
		$menuitem = menu_get_item();	
		if ($menuitem && is_array($menuitem['map'])) {
			// Walk over each element of the path (e.g. /node/%node, where 
			// wildcard path items will have been replaced with their fully 
			// loaded objects). Stop at the first NODE we find.
			foreach ($menuitem['map'] as $item) {
				if (isset($item->nid)) {
					// We have found a node
					$node = $item;
					break;
				}
			}
		}

When the current path is of the form /somename/someothername/%node, some drupal menurouter magic invokes node_load on %nodeid and stores the returned node object in the map element of the menu object. My code just walks over each part of the path looking for anything that is a node.

It seems to work nicely - and on my site it works automatically with both /resource/item/X and /node/X paths. I would assume this also saves unnecessary processing since node_load doesn't need to be called again, and the node object has already been "processed" by various modules such as CCK, which add all kinds of useful properties.

So my question is this: is there any reason I shouldn't be doing this? Is this infact a better approach than the if (arg(0) == 'node' && is_numeric(arg(1)) approach I keep seeing in other articles discussing how to establish the "current node id"?

Any thoughts?

nevets’s picture

For the "standard" case of only caring about paths of the form node/{nid} your approach is potentially more expensive as it walks the menu path for all pages. You code also use

$node = menu_get_object();
if ( !empty($node) ) {
  // Have a node object
}

Side note: Calling node_load() when the load has already been loaded will used a cached copy (if the node was loaded by nid).