Sorry, you need to enable JavaScript to visit this website.
Skip to main content
Welcome to our website! Explore our services and portfolio.

Creating a Custom Views Filter Plugin in Drupal

Submitted by admin on

Creating a custom Views Filter plugin in Drupal allows you to add complex logic to a View that isn’t possible with standard filters (e.g., filtering based on a calculation or an external API).

Here is the step-by-step process for Drupal 10/11.


1. Define the Filter in hook_views_data()

First, you must tell Views that your custom filter exists and which plugin should handle it. This goes in your module's MODULENAME.views.inc file.

PHP

/**
 * Implements hook_views_data().
 */
function my_module_views_data() {
  $data = [];
  // Use 'views' as the key to make it a Global filter, 
  // or 'node_field_data' to associate it with a specific table.
  $data['views']['my_custom_filter'] = [
    'title' => t('My Custom Logic Filter'),
    'help' => t('Filters results based on custom PHP logic.'),
    'filter' => [
      'id' => 'my_custom_filter_plugin', // This matches the Annotation ID
    ],
  ];
  return $data;
}

2. Create the Plugin Class

Create a file at: src/Plugin/views/filter/MyCustomFilter.php.

You will typically extend FilterPluginBase. If your filter behaves like a simple text search, you might extend StringFilter or NumericFilter instead to inherit their UI.

PHP

namespace Drupal\my_module\Plugin\views\filter;

use Drupal\views\Plugin\views\filter\FilterPluginBase;
use Drupal\Core\Form\FormStateInterface;

/**
 * Filters results by custom logic.
 *
 * @ViewsFilter("my_custom_filter_plugin")
 */
class MyCustomFilter extends FilterPluginBase {

  /**
   * Provide the form for the filter (the 'Value' field in Views UI).
   */
  protected function valueForm(&$form, FormStateInterface $form_state) {
    $form['value'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Custom Value'),
      '#default_value' => $this->value,
    ];
  }

  /**
   * Alter the database query.
   */
  public function query() {
    $this->ensureMyTable();
    
    // Example: Add a custom condition to the query
    // $this->query is a Drupal\views\Plugin\views\query\Sql object
    if (!empty($this->value)) {
      $this->query->addWhere(
        $this->options['group'], 
        'node_field_data.title', 
        '%' . $this->query->escapeLike($this->value) . '%', 
        'LIKE'
      );
    }
  }
}

3. Key Methods to Know

When building your class, these are the primary methods you'll override:

Method

Purpose

defineOptions()

Define configuration settings (defaults, storage).

buildOptionsForm()

Add settings to the "Filter Settings" modal in the Views UI.

valueForm()

Define the input field where the user (or visitor, if exposed) enters the filter value.

query()

Where you perform the actual $this->query->addWhere() or join operations.


Summary Checklist

  1. Module: Ensure my_module.info.yml exists.

  2. Hook: Put hook_views_data() in my_module.views.inc.

  3. Directory: File must be in src/Plugin/views/filter/.

  4. Annotation: The @ViewsFilter("ID") must match the id in your hook.

  5. Cache: Clear caches (drush cr) for the new filter to appear in the "Add Filter" list.

Would you like me to show you how to extend a specific filter type, like a dropdown (InOperator) or a date range?