0

I have a view which is a HTML list of the most popular tags in a specific vocabulary it is displayed as a block on a page of most recent news items. It is also displayed on each individual news item.

When it is displayed on the individual news item page I would like any tag that the news item has been tagged with and that also appears in the popular tags block to be highlighted by adding a css class called active.

How would I achieve this?

  • I find you question really hard to understand. Can you edit it to improve the clarity and then I'll see what I can do to help... – Felix Eve Feb 20 '14 at 12:06
  • I have updated it, hopefully this makes it clearer. – Daniel Harper Feb 20 '14 at 12:11
1

Well, the only method I can think of is to do it the template, but have a feeling there must be a better solution than this... But to do it this way:

Edit your view and under Advanced click on Theme: Information. This shows a list of template file names that would apply to your view. If you had a view called tags then creating a template file called views-view-fields--tags.tpl.php would be appropriate. After adding your template file (in your themes directory) click the Rescan template files button.

The standard template file looks like this:

<?php foreach ($fields as $id => $field): ?>
  <?php if (!empty($field->separator)): ?>
    <?php print $field->separator; ?>
  <?php endif; ?>

  <?php print $field->wrapper_prefix; ?>
    <?php print $field->label_html; ?>
    <?php print $field->content; ?>
  <?php print $field->wrapper_suffix; ?>
<?php endforeach; ?>

But if you changed it to this:

<?php foreach ($fields as $id => $field): ?>
<?php if (!empty($field->separator)): ?>
<?php print $field->separator; ?>
<?php endif; ?>
<?php print $field->wrapper_prefix; ?>
<?php print $field->label_html; ?>
<?php 
$current = false;
if(arg(0)=='node' && is_numeric(arg(1))) { // check if we are on a node page
    $node = node_load(arg(1)); // load the node
    $tag = strip_tags($field->content);
    foreach($node->field_tags[LANGUAGE_NONE] as $term) { // loop over the tags attached to the node
        if($term['taxonomy_term']->name == $tag) { // there is a match
            $current = true;
            break;
        }
    }
}
if($current) {
    print '<span class="current">'.$field->content.'</span>'; // add a span with current class
} else {
    print $field->content; 
}
?>
<?php print $field->wrapper_suffix; ?>
<?php endforeach; ?>

The disadvantage of this method it that code needs to run for each tag in the list, but it would achieve the desired result.

  • This solution does work, but like you said there must be a better way I've created a views handler plugin (see below) but again I have to load the node every time a term is rendered when I only want to load the node once. – Daniel Harper Feb 25 '14 at 11:40
  • At least the node will be cached so there won't be too much overhead from loading the same node multiple times. – Felix Eve Feb 25 '14 at 11:58
0

MY_MODULE.module

function MY_MODULE_views_api() {
  return array(
    'api' => 3,
    'path' => drupal_get_path('module', 'MY_MODULE') . '/includes',
  );
}

MY_MODULE.views.inc

function MY_MODULE_views_data_alter(&$data) {
  $data['taxonomy_term_data']['name']['field']['handler'] = 'MY_MODULE_views_handler_field_taxonomy_active';
}

MY_MODULE_views_handler_field_taxonomy_active.inc

class MY_MODULE_views_handler_field_taxonomy_active extends views_handler_field_taxonomy {

  function options_form(&$form, &$form_state) {
     $form['active_class'] = array(
       '#title' => t('Add active class to term link'),
       '#description' => t('This allows you to add an active class to a link id the term exists on the current page.'),
       '#type' => 'checkbox',
       '#default_value' => !empty($this->options['active_class']),       
     );
    parent::options_form($form, $form_state);
  }

  function render_link($data, $values) {
    $tid = $this->get_value($values, 'tid');
    if (!empty($this->options['link_to_taxonomy']) && !empty($tid) && $data !== NULL && $data !== '') {
      $term = new stdClass();
      $term->tid = $tid;
      $term->vid = $this->get_value($values, 'vid');
      $term->vocabulary_machine_name = $values->{$this->aliases['vocabulary_machine_name']};
      $this->options['alter']['make_link'] = TRUE;
      $uri = entity_uri('taxonomy_term', $term);
      $this->options['alter']['path'] = $uri['path'];      
    }

    if (!empty($this->options['active_class']) && arg(0) == 'node' && is_numeric(arg(1))) {
      $raw_terms = array();
      $node = entity_load_single('node', arg(1));
      $terms = field_get_items('node', $node, 'field_tags');
      foreach($terms as $k => $v) {
        $raw_terms[] = $v['tid'];
      }

      if(in_array($tid, $raw_terms)){
       $this->options['alter']['link_class'] = 'active';       
      }
      else {
        $this->options['alter']['link_class'] = ''; 
      }
    }

    if (!empty($this->options['convert_spaces'])) {
      $data = str_replace(' ', '-', $data);
    }
    return $data;
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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