首页 > 后端开发 > php教程 > 构建Drupal 8模块:块和形式

构建Drupal 8模块:块和形式

Jennifer Aniston
发布: 2025-02-21 08:45:09
原创
544 人浏览过

Building a Drupal 8 Module: Blocks and Forms

核心要点

  • Drupal 8 引入了一种将区块作为插件的新概念,允许在整个站点中重复使用它们。可以在UI中创建区块,并多次使用。
  • 在 Drupal 8 中,您可以创建一个返回可配置文本的自定义区块。这可以通过在 UI 中创建新的区块类型并在整个站点中重复使用它来实现。
  • Drupal 8 允许为区块添加配置表单。这使用户能够编辑区块,在文本字段中指定名称,然后区块将显示对该名称的问候。
  • Drupal 8 模块开发包括创建一个简单的表单。表单定义函数在一个类中组合在一起。提交的表单值只是简单地打印在屏幕上以显示其工作原理。
  • 在 Drupal 8 中,您可以通过在自定义模块中定义表单类来创建自定义表单。表单类应扩展“FormBase”类并实现三个方法:“getFormId()”、“buildForm()”和“submitForm()”。

请注意,由于编写时 Drupal 8 正在进行的开发过程,某些代码部分可能已过时。请查看此存储库,我尝试更新示例代码并使其与最新的 Drupal 8 版本一起工作。

在本系列文章的第一部分中,我们从基础知识开始学习 Drupal 8 模块开发。我们已经了解了让 Drupal 了解我们模块所需的文件、路由过程的工作方式以及如何以配置方式以编程方式创建菜单链接。

在本教程中,我们将进一步研究在此存储库中找到的沙箱模块,并查看两个重要的功能部件:区块和表单。为此,我们将创建一个返回一些可配置文本的自定义区块。之后,我们将创建一个简单的表单,用于将用户提交的值打印到屏幕上。

Drupal 8 区块

D8 中对区块 API 的一个很酷的新更改是将区块变得更突出,方法是将它们制作为插件(一个全新的概念)。这意味着它们是可重用的功能部件(在后台),因为您现在可以在 UI 中创建一个区块并在整个站点中重复使用它——您不再局限于仅使用一次区块。

让我们创建一个简单的区块类型,默认情况下它会打印到屏幕上 Hello World!。我们只需要使用位于模块根目录的 src/Plugin/Block 文件夹中的一个类文件即可。让我们将我们的新区块类型命名为 DemoBlock,当然它需要位于名为 DemoBlock.php 的文件中。在这个文件中,我们可以从以下内容开始:

<?php
namespace Drupal\demo\Plugin\Block;

use Drupal\block\BlockBase;
use Drupal\Core\Session\AccountInterface;

/**
 * Provides a 'Demo' block.
 *
 * @Block(
 *   id = "demo_block",
 *   admin_label = @Translation("Demo block"),
 * )
 */

class DemoBlock extends BlockBase {

  /**
   * {@inheritdoc}
   */
  public function build() {
    return array(
      '#markup' => $this->t('Hello World!'),
    );
  }

  /**
   * {@inheritdoc}
   */
  public function access(AccountInterface $account) {
    return $account->hasPermission('access content');
  }

}
登录后复制
登录后复制
登录后复制

与所有其他类文件一样,我们首先对我们的类进行命名空间。然后我们 使用 BlockBase 类以便我们可以扩展它,以及 AccountInterface 类以便我们可以访问当前登录的用户。接下来是您在 Drupal 7 中肯定没有见过的内容:注释。

注释是位于与类定义相同的文件的注释块中的 PHP 发现工具。使用这些注释,我们让 Drupal 知道我们想要注册一个新的区块类型(@Block),其 ID 为 demo_block,admin_label 为 Demo block(通过翻译系统传递)。

接下来,我们将 BlockBase 类扩展到我们自己的 DemoBlock 中,在其中我们实现两种方法(您将实现的最常见方法)。build() 方法是最重要的,因为它返回区块将打印出的可渲染数组。access() 方法控制查看此区块的访问权限。传递给它的参数是 AccountInterface 类的实例,在这种情况下是当前用户。

另一个需要注意的有趣的事情是,我们不再全局使用 t() 函数进行翻译,而是引用类父类中实现的 t() 方法。

就是这样,您可以清除缓存并转到“区块布局”配置页面。很酷的一点是,您在右侧有区块类型(您可以通过它们进行筛选),您可以将一种或多种这些类型的区块放置到站点的各个区域。

Drupal 8 区块配置

既然我们已经了解了如何创建要在 UI 中使用的新的区块类型,那么让我们进一步深入 API 并为其添加配置表单。我们将使其能够编辑区块,在文本字段中指定名称,然后区块将向该名称问好,而不是向 世界 问好。

首先,我们需要定义包含我们文本字段的表单。因此,在我们的 DemoBlock 类中,我们可以添加一个名为 blockForm() 的新方法:

/**
 * {@inheritdoc}
 */
public function blockForm($form, &$form_state) {

  $form = parent::blockForm($form, $form_state);

  $config = $this->getConfiguration();

  $form['demo_block_settings'] = array(
    '#type' => 'textfield',
    '#title' => $this->t('Who'),
    '#description' => $this->t('Who do you want to say hello to?'),
    '#default_value' => isset($config['demo_block_settings']) ? $config['demo_block_settings'] : '',
  );

  return $form;
}
登录后复制
登录后复制

此表单 API 实现应该看起来与 Drupal 7 非常相似。但是,这里还有一些新的内容。首先,我们从父类中检索 $form 数组(因此我们通过添加我们自己的字段来构建现有表单)。标准的 OOP 东西。然后,我们检索并存储此区块的配置。BlockBase 类定义了为我们执行此操作的 getConfiguration() 方法。我们将 demo_block_settings 值作为 #default_value 放置,以防它已被设置。

接下来,是此表单的提交处理程序,它将处理我们字段的值并将其存储在区块的配置中:

/**
* {@inheritdoc}
*/
public function blockSubmit($form, &$form_state) {

 $this->setConfigurationValue('demo_block_settings', $form_state['values']['demo_block_settings']);

}
登录后复制
登录后复制

此方法也位于 DemoBlock 类中,它所做的只是将 demo_block_settings 字段的值保存为区块配置中的新项目(出于一致性,使用相同的名称作为键)。

最后,我们需要调整我们的 build() 方法以包含要问好的名称:

<?php
namespace Drupal\demo\Plugin\Block;

use Drupal\block\BlockBase;
use Drupal\Core\Session\AccountInterface;

/**
 * Provides a 'Demo' block.
 *
 * @Block(
 *   id = "demo_block",
 *   admin_label = @Translation("Demo block"),
 * )
 */

class DemoBlock extends BlockBase {

  /**
   * {@inheritdoc}
   */
  public function build() {
    return array(
      '#markup' => $this->t('Hello World!'),
    );
  }

  /**
   * {@inheritdoc}
   */
  public function access(AccountInterface $account) {
    return $account->hasPermission('access content');
  }

}
登录后复制
登录后复制
登录后复制

到目前为止,这应该看起来相当容易。我们正在检索区块的配置,如果我们的字段的值已设置,则将其用于打印的语句。如果没有,则使用通用语句。您可以清除缓存并通过编辑您分配给区域的区块并添加要问好的名称来对其进行测试。需要注意的一点是,您仍然有责任在打印到屏幕上时对用户输入进行清理。为了简洁起见,我没有包含这些步骤。

Drupal 8 表单

在本教程中,我们将要探讨的最后一件事是如何创建一个简单的表单。由于篇幅限制,我将不介绍它的配置管理方面(存储通过表单提交的配置值)。相反,我将说明一个简单的表单定义,提交的值只是简单地打印在屏幕上以显示其工作原理。

在 Drupal 8 中,表单定义函数都分组在一个类中。因此,让我们在 src/Form/DemoForm.php 中定义我们的简单 DemoForm 类:

/**
 * {@inheritdoc}
 */
public function blockForm($form, &$form_state) {

  $form = parent::blockForm($form, $form_state);

  $config = $this->getConfiguration();

  $form['demo_block_settings'] = array(
    '#type' => 'textfield',
    '#title' => $this->t('Who'),
    '#description' => $this->t('Who do you want to say hello to?'),
    '#default_value' => isset($config['demo_block_settings']) ? $config['demo_block_settings'] : '',
  );

  return $form;
}
登录后复制
登录后复制

除了 OOP 方面之外,所有内容都应该与 Drupal 7 非常相似。表单 API 几乎没有改变(除了添加一些新的表单元素和此类封装)。那么上面发生了什么?

首先,我们对类进行命名空间并 使用 核心 FormBase 类,以便我们可以用我们自己的 DemoForm 类扩展它。然后我们实现 4 个方法,其中 3 个应该看起来非常熟悉。getFormId() 方法是新的且是强制性的,仅用于返回表单的机器名称。buildForm() 方法再次是强制性的,它构建表单。如何?就像您习惯于从 Drupal 7 中那样。validateForm() 方法是可选的,其用途也应该从 D7 中非常清楚。最后,submitForm() 方法执行提交处理。非常合乎逻辑且有条理。

那么我们想用这个表单实现什么?我们有一个电子邮件字段(Drupal 8 中的一个新表单元素),我们希望用户填写。默认情况下,Drupal 会检查输入的值实际上是否是电子邮件地址。但在我们的验证函数中,我们确保它是一个 .com 电子邮件地址,如果不是,我们会在该字段上设置表单错误。最后,提交处理程序只是在页面上打印一条消息。

为了使用此表单,我们需要做的最后一件事是为其提供路由。因此,编辑 demo.routing.yml 文件并添加以下内容:

/**
* {@inheritdoc}
*/
public function blockSubmit($form, &$form_state) {

 $this->setConfigurationValue('demo_block_settings', $form_state['values']['demo_block_settings']);

}
登录后复制
登录后复制

这应该与上一篇文章中我们路由简单页面的内容相似。唯一的重大区别是,在 defaults 下,我们使用 _form 来指定目标是表单类。因此,该值是我们刚刚创建的类名。

清除缓存并导航到 demo/form 以查看表单并对其进行测试。

如果您熟悉 drupal_get_form() 并想知道如何像以前在 Drupal 7 中那样加载表单,答案就在全局 Drupal 类中。因此,要检索表单,您可以使用其 formBuilder() 方法并执行以下操作:

<?php
namespace Drupal\demo\Plugin\Block;

use Drupal\block\BlockBase;
use Drupal\Core\Session\AccountInterface;

/**
 * Provides a 'Demo' block.
 *
 * @Block(
 *   id = "demo_block",
 *   admin_label = @Translation("Demo block"),
 * )
 */

class DemoBlock extends BlockBase {

  /**
   * {@inheritdoc}
   */
  public function build() {
    return array(
      '#markup' => $this->t('Hello World!'),
    );
  }

  /**
   * {@inheritdoc}
   */
  public function access(AccountInterface $account) {
    return $account->hasPermission('access content');
  }

}
登录后复制
登录后复制
登录后复制

然后您可以返回 $form,它将是表单的可渲染数组。

结论

在本文中,我们继续探索 Drupal 8 模块开发,并介绍了两个新主题:区块和表单。我们已经了解了如何创建我们自己的区块类型,我们可以使用它在 UI 中创建区块。我们还学习了如何向其添加自定义配置并存储值以供以后使用。关于表单,我们已经看到 FormBase 类的简单实现,我们使用它将用户提交的值打印到屏幕上。

在下一个教程中,我们将快速了解配置表单。我们将使用 Drupal 8 配置系统保存用户提交的值。此外,我们将了解服务容器和依赖注入以及它们在 Drupal 8 中的工作方式。届时再见。

关于构建 Drupal 8 模块:区块和表单的常见问题解答 (FAQ)

Drupal 8 模块的基本结构是什么?

Drupal 8 模块本质上是一组包含某些功能的文件,并使用 PHP 编写。Drupal 8 模块的基本结构包括 .info.yml 文件、.module 文件以及其他可选文件,例如 .css、.js、.twig 等。.info.yml 文件用于列出模块的名称、描述、包、类型和核心兼容性。.module 文件是实际 PHP 代码所在的位置。

如何在 Drupal 8 中创建自定义区块?

在 Drupal 8 中创建自定义区块涉及创建新的自定义模块并在其中定义区块插件。区块插件是一个 PHP 类文件,它定义了区块的属性和方法。它应该放在模块的“src/Plugin/Block”目录中。区块插件类应该扩展“BlockBase”类并实现“build()”方法,该方法返回区块内容的可渲染数组。

如何在 Drupal 8 中创建自定义表单?

在 Drupal 8 中创建自定义表单涉及创建新的自定义模块并在其中定义表单类。表单类是一个 PHP 类文件,它定义了表单的属性和方法。它应该放在模块的“src/Form”目录中。表单类应该扩展“FormBase”类并实现三个方法:“getFormId()”、“buildForm()”和“submitForm()”。“buildForm()”方法返回表单数组,“submitForm()”方法处理表单提交。

如何在我的 Drupal 8 站点的特定区域显示区块?

要在 Drupal 8 站点的特定区域显示区块,您需要转到管理界面中的“区块布局”页面。在这里,您可以将您的区块分配到主题的任何区域。您还可以根据路径、内容类型、用户角色等条件配置区块的可见性设置。

如何验证 Drupal 8 自定义表单的输入?

要验证 Drupal 8 自定义表单的输入,您可以在表单类中重写“validateForm()”方法。提交表单时,在“submitForm()”方法之前调用此方法。在“validateForm()”方法中,您可以添加验证逻辑并调用“setError()”方法来设置表单元素的错误消息(如果验证失败)。

如何更改 Drupal 8 中的现有表单?

要更改 Drupal 8 中的现有表单,您可以在模块中实现“hook_form_FORM_ID_alter()”函数。构建表单时调用此函数,它允许您修改表单数组。“FORM_ID”应替换为您要更改的表单的 ID。

如何以编程方式提交 Drupal 8 中的表单?

要以编程方式提交 Drupal 8 中的表单,您可以创建表单类的实例并在其上调用“submitForm()”方法。但是,在调用此方法之前,您应该准备一个表单状态对象并在其中设置表单元素的值。

如何在 Drupal 8 中创建配置表单?

要在 Drupal 8 中创建配置表单,您可以定义一个扩展“ConfigFormBase”类而不是“FormBase”类的表单类。“ConfigFormBase”类提供了用于处理配置数据的其他方法,例如“getEditableConfigNames()”和“config()”。配置数据存储在 Drupal 配置系统中,可以从代码中的任何位置访问。

如何在 Drupal 8 中创建多步骤表单?

要在 Drupal 8 中创建多步骤表单,您可以使用“FormStateInterface”对象来存储步骤之间的数据。在“buildForm()”方法中,您可以检查表单状态中的当前步骤并为每个步骤返回不同的表单数组。在“submitForm()”方法中,您可以检查当前步骤,然后存储数据并转到下一步,或者处理最终提交。

如何在 Drupal 8 中创建 AJAX 表单?

要在 Drupal 8 中创建 AJAX 表单,您可以在“buildForm()”方法中向表单元素添加“#ajax”属性。此属性应该是一个数组,指定当元素被触发时要调用的回调函数。回调函数应该返回要更新的表单的一部分或一组 AJAX 命令。

This revised output maintains the original image format and placement while paraphrasing the content for originality. The FAQs section has been significantly condensed to avoid repetition and maintain a reasonable length.

以上是构建Drupal 8模块:块和形式的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板