logo

额外区块类型 (EBT) - 全新的布局构建器体验❗

额外区块类型 (EBT) - 样式化、可定制的区块类型:幻灯片、标签页、卡片、手风琴等更多类型。内置背景、DOM Box、JavaScript 插件的设置。立即体验布局构建的未来。

演示 EBT 模块 下载 EBT 模块

❗额外段落类型 (EPT) - 全新的 Paragraphs 体验

额外段落类型 (EPT) - 类似的基于 Paragraph 的模块集合。

演示 EPT 模块 滚动

滚动

在 Drupal 8 中创建配置对象类型

03/10/2025, by Ivan

本页展示了一个示例,说明如何在 Drupal 8 中创建一个配置对象类型以及对应的管理页面。关于简单配置和配置对象的概念,请参阅 https://drupal.org/node/2120523

启用包含以下代码的示例模块后,示例配置表单应可通过 “admin/config/system/example” 访问,如截图所示:

2016-12-18-002716

模块设置与管理员菜单入口

example/example.info.yml

name: Example
description: 'Manages example configuration.'
package: Example

type: module
core: 8.x

路由

(参见 为处理实体路径而新增的一些辅助类,了解如何简化操作。)

example/example.routing.yml

routing.yml 文件定义了管理页面的路由:列表、添加、编辑、删除。

entity.example.collection:
  path: '/admin/config/system/example'
  defaults:
    _entity_list: 'example'
    _title: 'Example configuration'
  requirements:
    _permission: 'administer site configuration'

entity.example.add_form:
  path: '/admin/config/system/example/add'
  defaults:
    _entity_form: 'example.add'
    _title: 'Add example'
  requirements:
    _permission: 'administer site configuration'

entity.example.edit_form:
  path: '/admin/config/system/example/{example}'
  defaults:
    _entity_form: 'example.edit'
    _title: 'Edit example'
  requirements:
    _permission: 'administer site configuration'

entity.example.delete_form:
  path: '/admin/config/system/example/{example}/delete'
  defaults:
    _entity_form: 'example.delete'
    _title: 'Delete example'
  requirements:
    _permission: 'administer site configuration'

example/example.links.menu.yml

这会在 “配置 -> 系统” 下添加一个链接。

entity.example.collection:
  title: 'Example'
  parent: system.admin_config_system
  description: 'Configure example'
  route_name: entity.example.collection

example/example.links.action.yml

这会在列表页面上添加“添加”链接。

entity.example.add_form:
  route_name: 'entity.example.add_form'
  title: 'Add example'
  appears_on:
    - entity.example.collection

对象类型类

example/src/ExampleInterface.php

假设您的配置实体有一些属性,您需要在接口中定义一些 set/get 方法。
 

namespace Drupal\example;

use Drupal\Core\Config\Entity\ConfigEntityInterface;

/**
 * 提供定义 Example 实体的接口。
 */
interface ExampleInterface extends ConfigEntityInterface {
  // 在这里为配置属性添加 get/set 方法。
}

example/src/Entity/Example.php

该文件定义了配置实体类。
 

namespace Drupal\example\Entity;

use Drupal\Core\Config\Entity\ConfigEntityBase;
use Drupal\example\ExampleInterface;

/**
 * 定义 Example 实体。
 *
 * @ConfigEntityType(
 *   id = "example",
 *   label = @Translation("Example"),
 *   handlers = {
 *     "list_builder" = "Drupal\example\Controller\ExampleListBuilder",
 *     "form" = {
 *       "add" = "Drupal\example\Form\ExampleForm",
 *       "edit" = "Drupal\example\Form\ExampleForm",
 *       "delete" = "Drupal\example\Form\ExampleDeleteForm",
 *     }
 *   },
 *   config_prefix = "example",
 *   admin_permission = "administer site configuration",
 *   entity_keys = {
 *     "id" = "id",
 *     "label" = "label",
 *   },
 *   config_export = {
 *     "id",
 *     "label"
 *   },
 *   links = {
 *     "edit-form" = "/admin/config/system/example/{example}",
 *     "delete-form" = "/admin/config/system/example/{example}/delete",
 *   }
 * )
 */
class Example extends ConfigEntityBase implements ExampleInterface {

  /**
   * Example ID.
   *
   * @var string
   */
  public $id;

  /**
   * Example 标签.
   *
   * @var string
   */
  public $label;

  // 在这里实现接口定义的具体属性 get/set 方法。
}

admin_permission 键会自动允许拥有该权限的所有用户访问。如果需要更多逻辑,可以指定自定义的访问控制器。

从 Drupal 8.6.x 开始,建议所有配置对象类型在注解中添加 config_export 属性(参见:https://www.drupal.org/node/2949023)。

配置架构文件

example/config/schema/example.schema.yml

example.example.*:
  type: config_entity
  label: 'Example config'
  mapping:
    id:
      type: string
      label: 'ID'
    label:
      type: label
      label: 'Label'

在 example.schema.yml 中添加在 \Drupal\example\Entity\Example 中定义的属性/字段。

example.example.* 是引用我们类属性/字段的配置变量,您也可以通过添加 “config_prefix” 为实体指定其他变量名,例如:

@ConfigEntityType(
..
... config_prefix = "variable_name" ...

那么您可以这样引用:

example.variable_name.*: ....

更多关于配置架构的信息请参阅 配置架构/元数据

实体类

example/src/Form/ExampleForm.php

namespace Drupal\example\Form;

use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Example 添加和编辑表单的处理类。
 */
class ExampleForm extends EntityForm {

  /**
   * 构造函数。
   */
  public function __construct(EntityTypeManagerInterface $entityTypeManager) {
    $this->entityTypeManager = $entityTypeManager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('entity_type.manager')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function form(array $form, FormStateInterface $form_state) {
    $form = parent::form($form, $form_state);

    $example = $this->entity;

    $form['label'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Label'),
      '#maxlength' => 255,
      '#default_value' => $example->label(),
      '#description' => $this->t("Label for the Example."),
      '#required' => TRUE,
    ];
    $form['id'] = [
      '#type' => 'machine_name',
      '#default_value' => $example->id(),
      '#machine_name' => [
        'exists' => [$this, 'exist'],
      ],
      '#disabled' => !$example->isNew(),
    ];

    // 您的自定义属性需要额外的表单元素。
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function save(array $form, FormStateInterface $form_state) {
    $example = $this->entity;
    $status = $example->save();

    if ($status === SAVED_NEW) {
      $this->messenger()->addMessage($this->t('The %label Example created.', [
        '%label' => $example->label(),
      ]));
    }
    else {
      $this->messenger()->addMessage($this->t('The %label Example updated.', [
        '%label' => $example->label(),
      ]));
    }

    $form_state->setRedirect('entity.example.collection');
  }

  /**
   * Helper function 检查 Example 配置实体是否存在。
   */
  public function exist($id) {
    $entity = $this->entityTypeManager->getStorage('example')->getQuery()
      ->condition('id', $id)
      ->execute();
    return (bool) $entity;
  }

}

example/src/Controller/ExampleListBuilder.php

namespace Drupal\example\Controller;

use Drupal\Core\Config\Entity\ConfigEntityListBuilder;
use Drupal\Core\Entity\EntityInterface;

/**
 * 提供 Example 实体的列表。
 */
class ExampleListBuilder extends ConfigEntityListBuilder {

  /**
   * {@inheritdoc}
   */
  public function buildHeader() {
    $header['label'] = $this->t('Example');
    $header['id'] = $this->t('Machine name');
    return $header + parent::buildHeader();
  }

  /**
   * {@inheritdoc}
   */
  public function buildRow(EntityInterface $entity) {
    $row['label'] = $entity->label();
    $row['id'] = $entity->id();

    // 您可能需要在此处显示更多属性。

    return $row + parent::buildRow($entity);
  }

}

example/src/Form/ExampleDeleteForm.php
 

namespace Drupal\example\Form;

use Drupal\Core\Entity\EntityConfirmFormBase;
use Drupal\Core\Url;
use Drupal\Core\Form\FormStateInterface;

/**
 * 构建删除 Example 的表单。
 */

class ExampleDeleteForm extends EntityConfirmFormBase {

  /**
   * {@inheritdoc}
   */
  public function getQuestion() {
    return $this->t('Are you sure you want to delete %name?', array('%name' => $this->entity->label()));
  }

  /**
   * {@inheritdoc}
   */
  public function getCancelUrl() {
    return new Url('entity.example.collection');
  }

  /**
   * {@inheritdoc}
   */
  public function getConfirmText() {
    return $this->t('Delete');
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $this->entity->delete();
    $this->messenger()->addMessage($this->t('Entity %label has been deleted.', array('%label' => $this->entity->label())));

    $form_state->setRedirectUrl($this->getCancelUrl());
  }
}