How To Use hook_views_data_alter In Drupal 8?

How To Use hook_views_data_alter In Drupal 8?

Introduction

The views module is undoubtedly one of the most important and popular modules that’s used by almost all Drupal websites. Its usage is different for different types of Drupal website users, for example, it:

  • Generates content listing pages and blocks for website viewers and editors,
  • Provides a UI for frontend developers to control the initial layout of the content shown via a view,
  • Saves backend developers and database administrators from writing complex SQL queries every time the business changes the logic in which the content listings have to be shown on the website,

It’s also used by Drupal websites for generating their Homepage and can expose certain content in a particular format to another application.

Experimentation With Views And Its Advantages

The official views project page on Drupal.org covers limited uses of the module. The rest of the applications are discovered through heavy experimentation and customization by the Drupal community and users.

In this blog, I am going to share a finding I discovered while building a custom content filter.

The views module provides various hooks that can be used to further customize the functionality provided by it. With the help of hooks, developers get to modify the query, output, associated field and table data, plugins, etc.

You can find the complete list and description of all the hooks in the Drupal 8 version here.

Using hook_views_data_alter

The hook_views_data_alter is one of the important hooks provided by the views modules. It can be used to alter the table and field information accessed by the views.

Since views itself has various constructs like the tables, fields, joins, filtering criteria, sorting criteria, etc, it’s important to understand the functioning of this hook in case you are planning to alter/introduce a feature related to view.

Let’s take some examples of usage of this hook, starting with the simple ones. We’ll then move to the ones which require you to further write some plugins to complete the functionality.

Example 1

/**
 * Implements hook_views_data_alter().
 */
function my_example_module_views_data_alter(array &$data) {
  $data['node_field_data']['nid']['title'] = t('Content ID');
  $data['node_field_data']['nid']['help'] = t('Use this to display Node ID in every row.');
}

In this example, we used hook_views_data_alter to modify the title and the help text of the ID field. Once you run the above-provided snippet you will be able to see how this is reflected in the UI.

Screenshot 2022-06-21 at 5.03.36 PM.png

This usage can be useful when you want to provide more meaningful titles and help texts for the views fields and filters.

Example 2

/**
 * Implements hook_views_data_alter().
 */
function my_example_module_views_data_alter(array &$data) {
  $data['node_field_data']['example_field'] = [
    'title' => 'Example Field in content view.',
    'help' => 'This is an example field introduced by hook views data alter.',
    'field' => [
      'id' => 'example_field_plugin_id',
    ],
  ];
}

In this case, we have added a new example field in the content view. It is not necessary for this field to be attached to the node entity. This field will appear while building views that contain nodes as shown in the screenshot.

We have also indicated that plugin 'example_field_plugin_id' should be used to define the functionality of this field.

Make sure you have a plugin defined before placing the newly added example field. The newly added field is shown in the views UI just like all other fields.

Screenshot 2022-06-21 at 5.04.54 PM.png

These are some easy ways in which you can modify the data associated with views. The $data, which is an argument for the hook function, is a big array holding all the information for a view.

You can further dump the entire array, look for the exact data you would like to modify, and then do the required changes in the hook.

The hook_views_data_alter is not only limited to modification related to field data, but you can also use it to add custom filters and sort criteria based on your requirement.

Let’s look at another example to understand this use case and also how syntax in the hook affects your plugin.

Example 3

/**
 * Implements hook_views_data_alter().
 */
function my_example_module_views_data_alter(array &$data) {
  //Introducing another table in the view i.e base table of field_example.
  $data['node__field_example']['my_custom_filter'] = [
    'group' => t('Custom'),
    'title' => t('My Custom Filter'),
    'filter' => [
      'title' => t('My Custom Filter'),
      'help' => t('Provides a filter for the content data.'),
      'field' => 'entity_id',
      'id' => 'my_custom_filter_id',
    ],
  ];
}

This will help us in easily joining data with the view in which this field will be introduced. Other than the base table, I have provided some meta information and plugin ID for my custom plugin.

The plugin can intelligently utilize this to introduce the desired query in the view. By using this plugin we were able to easily introduce a change in the query that couldn’t have been generated using the options in the Views UI filtering section.

<?php

namespace Drupal\my_example_module\Plugin\views\filter;

use Drupal\views\Plugin\views\display\DisplayPluginBase;
use Drupal\views\Plugin\views\filter\FilterPluginBase;
use Drupal\views\ViewExecutable;

/**
 * Provides a filter for content data.
 *
 * @ingroup views_filter_handlers
 *
 * @ViewsFilter("my_custom_filter_id")
 */
class MyCustomFilter extends FilterPluginBase {

  /**
   * {@inheritdoc}
   */
  public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
    parent::init($view, $display, $options);
    $this->valueTitle = $this->t('My Custom Filter');
  }

  /**
   * Helper function that builds the query.
   */
  public function query() {
    //This ensures that the table from which data has to be queried is available with the view.
    $this->ensureMyTable();
    //An example way of modifying a query based on your field value.
    $this->query->addWhere('AND', 'node__field_example.field_example_value', 1, '=');
  }

}

Conclusion

In this blog post, we saw some of the example usages of hook_views_data_alter and how easily it can modify the behavior of Views as per your requirement.

For any confusion or unclarity, you should dump the $data variable and figure out what has to be modified. You can also check the implementation of hooks by the core modules.