2

I have a taxonomy which defines the sections of a site. One of the terms is "Global". What I am doing is creating pages with the site section term and also creating promo boxes which use the same taxonomy. By default the "Global" term is selected wherever the term relation is used.

I would like to have a block view using contextual filters. I have set it up to use one filter which is the term id from the url. This works great but when I have a page that has a specific section but does not have any related promo boxes I would like to load the "Global" set of promo boxes.

Is there a way to create multiple contextual filters using or statements? The default sets them up as and statements which will not allow me to load the "Global" plus the related to the page. I am sorting the view by taxonomy weight and have "Global" at the bottom so if I can get an or contextual filter I'll be in business.

Does anyone know of a module to do this or will I have to hook the view using hook_views_query_alter

1 Answer 1

0

In case anyone wants to know, I was able to accomplish this with some views hooks and will share my solution.

First you need to register view api information

/**
 * Implements hook_views_api().
 */
function mymodule_views_api() {
  return array(
    'api' => 3, 
  );
}

Then you need to alter the view at pre build to include the "Global" term. I am using entity query to determine if there is any content with the Global term. If so I am adding that term as an argument.

/**
 * Implements hook_views_pre_build().
 */
function mymodule_views_pre_build(&$view) {
  // we were getting no results if the tid of the Global term was not 1
  // in some build instances it is not so we need to ensure that the default
  // value being passed is the actual tid of the Global term.
  if (($view->name == 'badge' || $view->name == 'promo_box' || $view->name == 'article'|| $view->name == 'tips') && $view->current_display == 'block') {
    $vocabulary = taxonomy_vocabulary_machine_name_load('site_section');

    $entityQuery = new EntityFieldQuery;
    $entityQuery->entityCondition('entity_type', 'taxonomy_term')
      ->propertyCondition('name', 'Global')
      ->propertyCondition('vid', $vocabulary->vid)
      ->range(0 ,1);

    $result = $entityQuery->execute();

    if ($result) {
      $term = array_slice($result['taxonomy_term'], 0);   
      $view->argument['tid_1']->options['default_argument_options']['argument'] = $term[0]->tid;
    }
  }
}

And finally you need to switch the where statement to and or

/**
 * Implements hook_views_query_alter().
 */
function mymodule_views_query_alter(&$view, &$query) {
  //  Let's find out if we are attempting to load either the badge or promo box
  //  view. If so we need to alter the where clause to include an or statement
  //  in the conditional filter to also look for the global term in the site secttion
  //  taxonomy. I was not able to find a way to create an OR condition filter via a 
  //  module so for now this is the best to do it.
  if (($view->name == 'badge' || $view->name == 'promo_box' || $view->name == 'article'|| $view->name == 'tips') && $view->current_display == 'block') {
    if (isset($query->where[0]) && isset($query->where[1])) {
      $query->where[0]['type'] = 'OR';  
    }
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.