Filtering Views results with taxonomy terms including synonyms and relations

Taxonomy is a very powerful classification system, so powerful in fact that it's hard (and resource intensive) to fully utilize it in Views and other queries. If you've ever looked at views_handler_argument_term_node_tid_depth.inc you'll know what I mean.

So I needed to create a topic cloud for #recotype, and one of the requirements was to show results for selected terms and their synonyms together, such that a tweet tagged with #yvr would show up in results for #vancouver, given that these two terms are marked as related in the taxonomy.

Because this ability is not readily available in Views, I had to code it in. Here's a new argument handler that given a taxonomy term name, queries for the corresponding term ID in the term table along with its related terms and synonyms. A related term is another taxonomy term that is marked as related to this one, whereas a synonym is just a text phrase that corresponds to a taxonomy term - it has no ID of its own.

<?php
// @file mymodule.views.inc

/**
 * Implementation of hook_views_handlers().
 */
function mymodule_views_handlers() {
  return array(
   
'info' => array(
     
'path' => drupal_get_path('module', 'mymodule'),
    ),
   
'handlers' => array(
     
'mymodule_handler_argument_term_data_name_extra' => array(
       
'parent' => 'views_handler_argument_string',
      ),
    ),
  );
}

/**
 * Implementation of hook_views_data_alter().
 */
function mymodule_views_data_alter(&$data) {
 
$data['term_data']['name']['argument']['handler'] = 'mymodule_handler_argument_term_data_name_extra';
}

?>

And now the meaty part of the code where the query is generated:

<?php
// @file mymodule_handler_argument_term_data_name_extra.inc

class mymodule_handler_argument_term_data_name_extra extends views_handler_argument_string {
  function
query() {
   
$this->ensure_my_table();
   
$this->query->add_where(0, "
     
$this->table_alias.$this->real_field = '%s' OR
     
$this->table_alias.tid IN (
        SELECT _tr.tid1 FROM {term_relation} _tr
        INNER JOIN {term_data} _td ON _tr.tid2 = _td.tid
        WHERE _td.name = '%s'
        UNION SELECT _tr.tid2 FROM {term_relation} _tr
        INNER JOIN {term_data} _td ON _tr.tid1 = _td.tid
        WHERE _td.name = '%s'
        UNION SELECT _ts.tid FROM {term_synonym} _ts
        WHERE _ts.name = '%s'
      )
    "
, $this->argument, $this->argument, $this->argument, $this->argument);
  }
}

?>

Comments

Hi, This code seems very

Hi,

This code seems very useful, but I don't understand how to use it. Sorry :(

I create a custom module but I don't know what to put in mycustommodule.module.

Any help?

Thank you in advance, JF

An example of hook_view_api

An example of hook_view_api implementation would be nice to understand it.

Thanks in advance.

This Stack Overflow question

This Stack Overflow question should clarify it.

Implement hook_views_api so

Implement hook_views_api so that Views can detect your module. Clear your caches. The regular term argument handler should now be replaced with this new one.