Friday, December 17, 2010

Drupal: Showing related content based on taxonomy

Everyone knows that the taxonomy module allows one to categorize your content using both tags and administrator defined terms and is very flexible for classifying content. You can create one free-tagging vocabulary for everything, or separate controlled vocabularies to define the various properties of your content.

By using views in conjunction with taxonomy, one can easily create a block of related content.

For example on www.OyeStyle.com, we have articles categorized by one vocabulary called as "Main" and another vocabulary called as "Subcategory". These contain a fixed set of terms. We also allow a taxonomy with free-flowing tags for that much more flexibility and further categorization.We wanted to show a block of related articles based on the taxonomy on each page and of-course views was the answer. The link here at http://drupal.org/node/65375 details out as to how to go about it for D5 and D6.

However due to the free-tagging entries, we were ending up with a long list of articles diluting the "meaning" of related content in some ways. Here is how you can pick up related content by using specific taxonomies by avoiding free tags:

After following the instructions above in the drupal link, go to your view and edit the "Taxonomy: Term ID" argument. We then need to modify the PHP code specified for the default argument handling. Modify it thus:

$node = node_load(arg(1));
if ($node && $node->type == 'article' && $node->taxonomy) {
foreach($node->taxonomy as $term) {
$vocab = taxonomy_vocabulary_load($term->vid);
  if (empty($vocab->tags))
      $terms[] = $term->tid;
}
return implode('+' , $terms);
} else { return; }

The key difference in the above code is that for each taxonomy term associated with the node, we are getting the vocabulary associated with it . We then check if this vocabulary allows free tagging and ignore it if so (the empty($vocab->tags) check does this). Do not worry about the performance implications here, the vocabulary will most probably be cached across future calls. One can possibly do other modifications to the above code. For example, lets say you only want terms from a specific vocabulary. That can be done by:

$specific_vocab_name = 'Main';

$vocab = taxonomy_vocabulary_load($term->vid);
  if (strtolower($vocab->name) == strtolower($specific_vocab_name))
      $terms[] = $term->tid;


The above code will only pick terms belonging to the 'Main' vocabulary.Basically modify the vocabulary checks appropriately to get the desired results.

I hope this was useful. Check out the working functionality on Oyestyle by browsing through the articles there! :)

1 comment:

Thomas John said...

Hello,

I am Thomas John, representing the website Ubuntu Manual. As the name suggests UM is a site that delivers content related to Ubuntu, its derivatives and related software. We are looking to expand our website and are seeking talented writers familiar with Ubuntu or Linux or similar open source software to include in our community of writers.

We had come across your article on the web and was wondering whether you would be interested in writing for us. We can provide sufficient compensation for your writings and would love to have you as one of our writers.

I will provide you with the rest of the details if you are interested.

Cheers,
--
Thomas John,
Ubuntu Manual