Drupal related nodes by taxonomy term

One way to organize content in Drupal is through the use of taxonomy terms in a vocabulary.  This is not only important for organization, but also for getting visitors to your site to be presented with relevant related content once they find a valuable piece of information on your site from a search engine.  Ideally, when a vistor lands on a node that is tagged with term1 and term2, I would like a block in the sidebar to list other nodes that are tagged with either term1 or term2.  I couldn't find an easy way to do this in Drupal using a module, and the Views module is overwhelming, so I developed my own custom coded PHP block to accomplish this.

Here are my requirements for the design of this related nodes block:

  • Only display when viewing a node that has at least one taxonomy term associated with the node.
  • If the node has multiple taxonomy terms, group the terms together with an OR so I get all possible related nodes.
  • Be displayed in a list view that is themed like the rest of the site.
  • For now, display as many related pages as possible.

So go ahead and create a new block, and enter this as the block body:

 

 

<?php
  // make sure content is a node
  if ((arg(0) == 'node') && is_numeric(arg(1))) {
    // get the taxonomy terms for the current node
    $tax = taxonomy_node_get_terms(arg(1));
    // keys in the $tax array are the term ids, need to slice them out
    $tids = array_keys($tax);
    $operator = "or";
    // to find all related nodes, or all the terms together
    $result = taxonomy_select_nodes($tids, $operator);
    // fetch all of the terms with a db query
    while ($obj = db_fetch_object($result)) {
      // get info from the node
      $node = node_load(array('nid' => $obj->nid));
      // display titles and links to the node
      $items[] = l($node->title, "node/". $node->nid);
    }
    // theme the list using the standard built-in list theme
    return theme('item_list', $items);
  }
?>

And be sure to change the input type to "PHP code" before you save.

Now the block will be created, but we need to go into the block to set the block visibility so that it will only show on nodes that have some taxonomy terms associated with them.  Enter this into the Visibility section as PHP code:

<?php
if ((arg(0) == 'node') && is_numeric(arg(1))) {
  // get the taxonomy terms for the current node
  $tax = taxonomy_node_get_terms(arg(1));
  // if more than 1 term, show block
  if(count($tax) > 0) return TRUE;
  // otherwise hide block
  else return FALSE;
}
// if not a node, don't show the block
else return FALSE;
?>

Comments

few corrections


if ((arg(0) == 'node') && is_numeric(arg(1))) {

might be rewritten like this:

if (strpos('node/',$_GET['q']!==0)) return false; // i think is a bit quicker.

node_load is needed only if you want to echo node body,
taxonomy_select_nodes - returns nid,title,created and sticky