9.14. 编写与 Views 的集成
Views 模块在 Drupal 生态系统中被广泛使用。内容列表、表格、区块、幻灯片、数据导出 —— 这些内容通常都是通过 Views 来显示的。如果你使用内容类型(Content types)、区块类型(Block types)或其他实体类型(Entity types),那么 Views 已经自动与它们集成,你可以直接用 Views 来展示你的内容。但对于你自定义的模块,如果你使用了单独的自定义数据库表(通过 hook_schema() 创建),那么你需要为 Views 编写集成代码,才能在 Views 模块的 UI 中展示你模块的数据。
让我们看看模块 Did this help 与 Views 的集成:
https://www.drupal.org/project/did_this_help
该模块创建了自己的数据库表来存储数据。在这张表中有字符串、ID、日期,因此我们需要为 Views 集成定义不同的处理器(handlers):

首先,你需要添加文件 MODULENAME.views.inc,它会自动加载,因此不需要在其他地方指定该文件的位置。在 *.views.inc 文件中你需要实现 hook_views_data():
<?php
/**
* @file
* Provide views data for did_this_help.module.
*/
/**
* Implements hook_views_data().
*/
function did_this_help_views_data() {
}
在该实现中,你需要返回一个数组,用于描述自定义模块的自定义数据库表的结构。
首先在数组的第一个键中写入数据库表名:
$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.'),
],
],
];
这里数组键 $data['did_this_help'] 对应表的描述。如果你需要为多个数据库表添加集成,那么在 $data 数组中添加不同的键:$data['did_this_help1']、$data['did_this_help2']。
接下来在 'table' 描述中:
group —— 允许在 Views UI 中将字段分组,以便更容易选择字段。
base —— 显示此表的序列 ID,稍后我们将使用序列 ID 通过外键来连接表。
之后我们描述每个希望在 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 —— 用来定义真实的字段名(数据库表中的列名),如果你在数组键中使用了别名。对于一个 Drupal 字段类型,真实字段可能会有多个值。例如,Link 字段有两个值:Title 和 URI。每个值对应数据库表中的一列。列名由字段名和属性名(title, uri)组成:

这些列名是由 Link 模块自动生成的,但对于自定义模块来说,"real field" 需要你在 hook_views_data() 中自己定义。
title、help —— 用于 Views 模块 UI 的信息。
接下来是以下几种处理器(Handler IDs):field、sort、filter、argument。处理器定义了字段如何被过滤和显示,例如日期应该用日期格式显示,并通过日期选择器过滤;数字需要支持 >、<、= 操作的过滤器;字符串则需要字符串长度过滤。
字段处理器(Field handlers)
字段处理器帮助生成 SQL 查询中 SELECT 之后的部分。
Drupal 核心中的 Views 字段处理器列表可以在这里找到:
在自定义模块中,你通常会使用 standard 处理器来处理数字和字符串,对于日期数据则应使用 date 处理器。
例如,ID 字段使用字段处理器 "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)
排序处理器帮助在 Views 中使用普通排序和暴露排序。排序处理器定义 SQL 查询中 ORDER BY 之后的部分。
排序处理器列表可以在这里找到:
过滤器处理器(Filter handlers)
过滤器处理器帮助在 Views 中显示普通过滤器、暴露过滤器和上下文过滤器。过滤器处理器定义 SQL 查询中 WHERE 之后的部分。
过滤器处理器列表可以在这里找到:
要用日期选择器过滤日期,你可以使用处理器 "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)
关系处理器帮助在 SQL 查询中添加 JOIN,从多个表中抓取数据。
Did this help? 模块的数据库表有一列保存用户 ID。使用关系处理器,你可以在 Views UI 中添加 did_this_help 表和 users 表之间的关系,从而在一个查询中展示来自多个表的数据:
$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',
],
];
在这里我们为字段添加了关系,指定了 base —— 要连接的表名,以及 base field —— 用来连接的字段;同时还提供了 Views UI 使用的 title 和 help 信息,以及关系处理器 id。关系处理器类型列表可在这里查看:
然而,Views 提供了多种不同的处理器,你可以继承处理器的基类并编写自定义的字段、过滤器、排序处理器。在下一篇文章中,我们将为 Views 过滤器编写自定义处理器。