
在之前的文章中,我们已经了解了链接字段类型(Link field type)的工作方式:存储(Storage)、小部件(Widget)、格式化器(Formatter)。在本篇文章中,我们将创建一个自定义的字段类型,用于在页面上输出来自 YouTube 的视频,并提供两种不同的显示格式和设置。
本文重点介绍 Fields API。如果你只是想为你的网站添加一个 YouTube 视频字段,那么更好的选择是直接使用现成的模块:
https://www.drupal.org/project/video_embed_field
我已经将所有代码上传到了 GitHub 中的 drupalbook_youtube 模块中,你可以下载该模块并将其添加到你的站点:


在开发 Drupal 模块时,执行数据库查询是很常见的操作。尽可能使用 entityQuery
,但有时为了获取更复杂的数据,需要直接执行 SQL 查询。
你可以将此页面添加到书签,作为在 Drupal 中执行 MySQL 查询(select、insert、update、delete)的速查表。
Select 查询
获取单个值:
$query = \Drupal::database()->select('node_field_data', 'n');
$query->addField('n', 'nid');
$query->condition('n.title', 'About Us');
$query->range(0, 1);
$nid = $query->execute()->fetchField();
获取数组形式的结果:


在本文中,我们将学习 字段格式化器(Field Formatters),它允许我们控制字段在页面上的显示方式。
在前面的文章中,我们创建了一个字段类型 Link。本文将讲解这些字段如何在页面上显示,以及哪个类负责这一过程。每个通过 Drupal 添加的字段都可以在页面上显示,并且可以在“显示管理(Manage display)”页面中编辑其显示设置。


事件系统允许你构建更复杂的系统,通过在特定事件上运行自定义代码来改变功能。许多来自 Drupal 7 的钩子(hooks)已经被事件(events)所取代。这使得 Drupal 核心和许多扩展模块的工作方式得到了统一。事件系统本身来自 Symfony,由以下几个部分组成:
事件订阅者(Event Subscribers) — 即“事件监听者”,在特定事件发生时执行的函数或方法。在代码中,它是一个实现以下接口的类:
\Symfony\Component\EventDispatcher\EventSubscriberInterface
事件注册器(Event Registry) — 负责收集和按照触发顺序组织所有事件订阅者。注册器存储在事件分发器(Event Dispatcher)对象中,作为一个事件名称和优先级的键值对数组。当事件作为服务注册时,它会成为一个全局可用的分发器。
事件分发器(Event Dispatcher) — 事件触发的机制,它负责在正确的时间调用对应的事件订阅者。通常至少有一个 Event Dispatcher 实例被注册为服务。该类实现以下接口:


在之前的文章中,我们已经接触过 钩子(hooks)。在本文中,我们将更深入地了解那些用于操作实体(Entity)的钩子。
你可以先阅读这篇文章,了解钩子的概念及其用途:
http://drupalbook.org/drupal/92-what-hook-drupal-8
我们将使用钩子在与实体相关的事件(添加、删除、更新等)触发时执行自定义代码。
所有 Drupal 的钩子都可以在此页面上查看:
https://api.drupal.org/api/drupal/core!core.api.php/group/hooks/8.2.x
我们只会讲解其中一部分,它们在自定义模块中最常用于操作内容。


在 Drupal 中,所有实体的工作方式是统一的,所有 CRUD 操作(创建、读取、更新、删除)对所有实体也都是相同的。本文将介绍如何在自定义代码中操作实体。
我们先来看一些简单的示例。
以编程方式创建节点(Create node programmatically)
use \Drupal\node\Entity\Node;
$node = Node::create([
'type' => 'article',
'title' => 'Druplicon test',
]);
$node->save();
为了创建一个节点,你需要填写所有必填字段,默认情况下只有标题(Title)字段是必填的。你还可以在节点创建后访问并修改节点对象:


在实体中获取字段值相当简单,但有几种不同的方法可用。让我们看看在自定义代码中处理字段值的最佳方式。你可以随时在官方网站上查看有关使用字段的最新信息:
https://www.drupal.org/docs/8/api/entity-api/working-with-the-entity-api
本文将通过示例讲解如何操作字段值。
你无需死记字段的工作方式,可以随时回到此页面复习。随着时间的推移,你会越来越多地查阅官方文档,并逐渐意识到在 Drupal 中操作字段其实非常简单。同时,你也可以将此页加入书签,以便随时查阅。
操作节点(Node)
按 nid 加载节点:


我们已经了解了 Form API、Fields API,并且知道 Drupal 中的数据是如何存入数据库的。现在让我们来看看所有 Drupal 网站的基础——Entity API(实体 API)。
你可能已经注意到,字段(fields)并不是独立存在的,而是“附加”在实体(entity)上的:节点(nodes)、区块(blocks)、分类术语(taxonomy terms)、视图(views)等。你可以创建可打包(bundle)的实体,例如内容类型、区块类型、分类字典等。但如果你需要创建一个带有自己 bundle 的新实体类型怎么办?这种情况下,你就需要使用 Entity API 来创建新的实体类型。
我已将所有代码添加到 GitHub 上的 drupalbook_product 模块中,你可以下载该模块并将其添加到自己的网站中:
https://github.com/levmyshkin/drupalbook8
创建新的实体类型最简单的方法是通过 Drupal Console,因为只需要执行一个命令即可完成。


“关系(Relationships)”是 Drupal 中非常重要的部分,正是通过它,术语与内容、用户与内容、商品与商品展示等元素才能相互关联。借助这种机制,我们可以在显示内容字段时显示作者的字段信息,在显示商品时显示它们的价格和货号。
借助这种机制,我们可以在显示内容字段时显示作者的字段信息,在显示商品时显示它们的价格和货号。
让我们创建一个视图(View),它将在当前页面的区块中显示创建该内容的用户信息。在之前的课程中,我们已经学习了如何使用上下文过滤器(Contextual Filter)来显示与当前页面相关的信息:


用户——这是 Drupal 的主要功能之一,我们可以创建或删除用户。网站上的用户可以留下评论、反馈、或发布内容。Drupal 具有用户管理与审核系统。这只是 Drupal 功能的一部分,因此我们需要了解 Drupal 的管理面板来管理这些内容。
让我们进入“账户设置(Account settings)”页面:
账户设置
