10/27/2020, by Ivan

Views module is widely used in Drupal ecosystem. Lists of content, tables, blocks, slideshows, data export - these peaces of contents usually are displayed with Views. If you use Content types, Block types or another Entity types, then Views already integrated with them automatically and you can use Views to display your content. But for your custom module, where you use separate custom database table, which you created with hook_schema(), you should write integration with Views to display your module data in Views module UI.

Let's see integration for module Did this help with Views:

https://www.drupal.org/project/did_this_help

The module creates own database table to store data. In this table are strings, IDs, dates, so we need to define different handlers for Views integration:

Did this help database

In the beginning you need to add file MODULENAME.views.inc, which automatically loaded, so you don't need to specify location for the file anywhere else. In the file *.views.inc you need to implement hook_views_data():

<?php

/**
 * @file
 * Provide views data for did_this_help.module.
 */

/**
 * Implements hook_views_data().
 */
function did_this_help_views_data() {

}

For this implementation you need to return array which describes structure of your custom database table of custom module.

https://api.drupal.org/api/drupal/core%21modules%21views%21views.api.php/function/hook_views_data/9.0.x

Kick off with database table name in first array key:
 

  $data['did_this_help'] = [
    'table' => [
      'group' => t('Did this help?'),
      'base' => [
        'field' => 'id',
        'title' => t('Did this help? entries'),
        'help' => t('Contains a list of Did this help? entries.'),
      ],
    ],
  ];

Here are table description with name in array key $data['did_this_help']. If you need to add integration with few database tables, then add different keys for $data array: $data['did_this_help1'], $data['did_this_help2'].

Next in the array 'table' description follows:

group - allows to group fields in the same partition for easier field selection in UI Views.

base - shows serial ID for this table, later we will use serial ID to join tables by foreign keys.

After that we describe each field, which we want to see in Views:

$data['did_this_help']['id']= [
  'real field' => 'id',
  'title' => t('Did this help? record ID'),
  'help' => t('Did this help? record.'),
  'field' => [
    'id' => 'standard',
  ],
  'sort' => [
    'id' => 'standard',
  ],
  'filter' => [
    'id' => 'numeric',
  ],
  'argument' => [
    'id' => 'numeric',
  ],  
];

real field - allows to define real field name (column in database table), if you use aliases in the array keys. For one Drupal field type real fields can have different values, for example Link field has two values Title and URI. Each value matches own db table column. Column name consists of field name and property name (title, uri):

Link DB table

Name of these columns were created automatically by Link module, but for custom modules "real field" you need to define own real field values in hook_views_data().

title, help - Information for Views module UI.

Next Handler IDs follow for: field, sort, filter, argument. Handler defines way how to filter and display fields, for example dates should be displayed with Date Format and be filtered by Date Calendar Popup. For numbers we need filters with operations >, < and =, for strings we need filter by string length.

Field handlers

Field handlers helps to generate SQL query part after SELECT word.

List of Views field handlers from Drupal  core you can find here:

https://api.drupal.org/api/drupal/core%21modules%21views%21src%21Plugin%21views%21field%21FieldPluginBase.php/group/views_field_handlers/8.6.x

For custom modules often you will use standard handler for numbers and string, for data with dates you should use date handler.

For instance, ID field uses field handler "standard":

    'id' => [
      'real field' => 'id',
      'title' => t('Did this help? record ID'),
      'help' => t('Did this help? record.'),
      'field' => [
        'id' => 'standard',
      ],
      'sort' => [
        'id' => 'standard',
      ],
      'filter' => [
        'id' => 'numeric',
      ],
      'argument' => [
        'id' => 'numeric',
      ],
    ],

Sort handlers

Sort handlers help to use usual sorting and exposed sorting in Views. Sort handlers define SQL query part after ORDER BY words.

List of sort handlers you can find here:

https://api.drupal.org/api/drupal/core%21modules%21views%21src%21Plugin%21views%21sort%21SortPluginBase.php/group/views_sort_handlers/8.6.x

Filter handlers

Filter handlers help to display usual filters, exposed and contextual filters in Views. Filter handlers define SQL query part after WHERE word.

List of filter handlers you can find here:

https://api.drupal.org/api/drupal/core%21modules%21views%21src%21Plugin%21views%21filter%21FilterPluginBase.php/group/views_filter_handlers/8.6.x

To filter dates with Date Calendar popup you can use handler "date":

  $data['did_this_help']['created'] = [
    'title' => t('Created date for Did this help? record'),
    'help' => t('Created date for Did this help? record'),
    'field' => [
      'id' => 'date',
    ],
    'argument' => [
      'id' => 'date',
    ],
    'filter' => [
      'id' => 'date',
    ],
    'sort' => [
      'id' => 'date',
    ],
  ];

Relationship handler

Relationship handlers helps to add joins in SQL query and grab data from few tables in one query.

DB table of Did this help? module has a column with user IDs. Using relationship handler you can add relation in Views UI between rows in did_this_help and users and display data from few tables:

  $data['did_this_help']['uid'] = [
    'title' => t('User ID for Did this help? record'),
    'help' => t('User ID for Did this help? record'),
    'field' => [
      'id' => 'standard',
    ],
    'sort' => [
      'id' => 'standard',
    ],
    'filter' => [
      'id' => 'numeric',
    ],
    'argument' => [
      'id' => 'numeric',
    ],
    'relationship' => [
      'title' => t('User'),
      'help' => t('The user on which the log entry as written.'),
      'base' => 'users_field_data',
      'base field' => 'uid',
      'id' => 'standard',
    ],
  ];

For that we add relationship for field, where we specify "base" value with table which we want to join and field which we will use to join by this field "base field"; title and help for UI Views; id relationship handler. List of relationship types you can see here:

https://api.drupal.org/api/drupal/core%21modules%21views%21src%21Plugin%21views%21relationship%21RelationshipPluginBase.php/group/views_relationship_handlers/8.6.x

However, Views provides wide range of different handler, you can inherit base class of handler and write own custom handler for field, filter, sort. In the next article we will write custom handler for Views filter.

Did this help?

Why wasn't this information helpful

Limit to 250 characters.