2

I have created a nice Filter Handler for my View, and I set it up using hook_views_data_alter.

Does this mean that this will ALWAYS be the Filter Handler for this particular field? What if I want a different Filter Handler later, in a different view?

How can I specifically say "Only use the X handler on page X?"

For posterity, I thought I'd outline more of what I was trying to accomplish here:

I have "Friends" page and a "Content" page. On the "Content" page, I wanted to be able to filter by "Content posted by my friends." However, on the "Friends" page I want to filter by "Users in my Groups." Both of these query on the user.uid field, so it was making the filters the same, even though I wanted totally different logic for the two views.

3
  • Why can't you do it in hook_views_data_alter()? You know the view. You can get url of the current page or use args()
    – milkovsky
    Jan 15, 2014 at 11:55
  • No, it does not mean that it will always be the filter handler for a specific field. You can set the field handler. Please post your code if you want a better explanation. Jan 16, 2014 at 15:18
  • It would help if you could outline what you want to achieve. Generally speaking, it seems like a good approach to assume that a specific field with it's specific properties can always be handled by a single handler. This doesn't mean, that you can't change the outcome depending on the situation (a filter can have configuration too). In the context of a filter, you could also use hook_views_query_alter() to change the way filtering is done for specific views. So, please provide more details and also tag your question with the targeted drupal core version if possible.
    – berliner
    Jan 17, 2014 at 1:03

2 Answers 2

1
+50

Nope currently there is no explicit way to achieve it. However there is an workaround.

  1. Using hook_views_data_alter make your custom handler as the filter instead of existing one(You already did that)
  2. In your custom filter handler, add a new option to select which filter operation it needs to perform(whether normal one or custom one), Eventually a yes/no field.

Below is the example on adding extra options to the filter handler,

    function option_definition() {
      $options = parent::option_definition();

      $options['custom_filtering'] = array('default' => 0);

      return $options;
    }

    function extra_options_form(&$form, &$form_state) {
      parent::extra_options_form($form, $form_state);

      $form['custom_filtering'] = array(
        '#type' => 'checkbox',
        '#title' => t('Custom Filtering'),
        '#default_value' => $this->options['custom_filtering'],
        '#description' => t('Check this if you want to perform the custom filtering on this field instead of a regular filtering mechanism'),
      );
    }

3.Based on the above option do your filter mechanism like below,

function query() {
    // Do Custom filtering based on the option selected.
    if ($this->options['custom_filtering']) {
      // Do your custom filtering.
    }
    else {
      // Do regular filtering.
    }
  }

Now when you're adding the filter for this field, you can just select which filtering it needs to perform.

Edit by OP (I don't even know how I have the rights to do this): You must additionally implement the following:

function has_extra_options() { return TRUE; }

And then your extra options will be displayed!

3
  • Hey, so I selected your answer as the best one because it definitely does exactly what I'm looking for. However, I just now got a chance to implement it, and the extra options that I define aren't showing up anywhere. Any idea what could cause this? Jan 23, 2014 at 18:31
  • Figured it out & edited the answer! Jan 23, 2014 at 18:47
  • Ah missed has_extra_options!! Glad that you found it :) Jan 24, 2014 at 4:51
1

I always take the following approach: Copy the existing views_data code via php:

// Copy the existing definition.
$data['table']['field_special'] = $data['table']['field'];
// Force the real field, so views still consider it as a different field in SQL.
$data['table']['field_special']['real field'] = 'field';
// Set a special handler.
$data['table']['field_special']['field']['handler'] = 'foo_handler_field_...';

This allows you to easy reuse the custom handler if needed, but at the same time not conflict with existing views.

In contrast to the approach of berliner (which certainly works) this does not add any runtime code execution, which adds potential bugs. This approach just uses basically configuration.

1
  • Nice solution, never thought of that. So for tigertrussell this would mean to define $data['node']['custom_nid'] and to add his filter handler to $data['node']['custom_nid']['filter']['handler']? Then he can set this up for the view he wants to, using the UI.
    – berliner
    Jan 21, 2014 at 10:35

Your Answer

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

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