[Drupal] How to expose a custom table to views

| | 2 min read

Drupal views help in querying and displaying information fast and it becomes so hard when it comes to custom table fields to be accessed in the view arguments. To help Drupal views understand the exposure of modules and custom table data, we use hook_views_data().

In implementing hook_views_data, it calls a file expose.views.inc in the folder(/includes/views/) and the array structure of the
data fields and are returned by hook_schema.


/**
 * Implements hook_views_data().
 */
function expose_views_data() { 
    $data = array(); 
    $data['exposed']['table']['group'] = t('example'); 
    $data['exposed']['table']['base'] = array(
        'title' => t('exposed'),
        'help' => t('Records exposed to Views.'),
    ); 
    return $data;
}

Now your view has an idea on which table to use from the above code. Next to tell the views the columns in the table structure for sorting, filtering and displaying.


// id field
$data['exposed']['id'] = array(
    'title' => t('id'),
    'help' => t('record-id'),
    'field' => array(
        'handler' => 'views_handler_field_numeric',
    ),
    'filter' => array(
        'handler' => 'views_handler_filter_numeric',
    ),
  'sort' => array(
        'handler' => 'views_handler_sort',
    ),
);
 
// name field
$data['exposed']['name'] = array(
    'title' => t('name'),
    'help' => t('record name'),
    'field' => array(
        'handler' => 'views_handler_field',
    ),
    'filter' => array(
        'handler' => 'views_handler_filter_string',
    ),
 'sort' => array(
        'handler' => 'views_handler_sort',
    ),
);

In the above code, for each field we create a different array inside the table array structure.
We also address the view handlers to use the above mentioned operations displaying, sorting and filtering.

Handler defines which data-type/ classes used.
For example, for saving an integer field we use integer handler and plain-text/string field we use string argument handler.
Now clear the caches and check if you can add , sort and filter your custom table fields.

Next, the main thing is JOIN , providing relationship for the fields with the nodes.
For this we need to tell the views about our table unique-id that can access the handlers for joining other tables.


$data['exposed']['table']['join'] = array(
    'node' => array(
        'left_field' => 'nid',
        'field' => 'node_id',
    ),
);

In the above code the left_field is the target table node-id and field is current exposed table.

Next is to define the current table field node-id in the same way we did for fields ID and Name with one more
argument relationships.


// The Node ID field
$data['exposed']['node_id'] = array(
    'title' => t('node-id'),
    'help' => t('record node-id'),
    'field' => array(
        'handler' => 'views_handler_field_node',
    ),
    'filter' => array(
        'handler' => 'views_handler_filter_numeric',
    ),
  'sort' => array(
        'handler' => 'views_handler_sort',
    ),
    'relationship' => array(
        'base' => 'node',
        'field' => 'node_id',
        'handler' => 'views_handler_relationship',
        'label' => t('node'),
    ),
    'argument' => array(
        'handler' => 'views_handler_argument_node_nid',
        'numeric' => TRUE,
        'validate type' => 'nid',
    ),
);

I have also included the argument by which we take care of handling arguments (contextual filters) based on the node ID.
So clear caches and refresh the current View. You should now be able to add a relationship based on the node-id.

Finally, from doing above the custom table fields could be accessed easily in the view configuration for displaying!