logo

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

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

演示 EBT 模块 下载 EBT 模块

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

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

演示 EPT 模块 滚动

滚动
04/10/2025, by Ivan

Menu

字段类型定义了字段的属性和行为。字段类型被定义为插件,因此在编写新的字段类型之前,建议先熟悉 插件 API

在 Drupal 8 中创建字段类型,需要一个带有 FieldType 注解的类。

类的位置 应放在 MODULE_NAME/src/Plugin/Field/FieldType
例如:/modules/foo/src/Plugin/Field/FieldType/BazItem.php

类的命名空间 应该是 Drupal\MODULE_NAME\Plugin\Field\FieldType

<?php

namespace Drupal\MODULE_NAME\Plugin\Field\FieldType;

类上的注解必须包含唯一的 ID、标签以及默认的格式化器和小部件。默认的格式化器 ID 应与字段格式化器类注解中定义的 ID 一致。

/**
 * Provides a field type of baz.
 * 
 * @FieldType(
 *   id = "baz",
 *   label = @Translation("Baz field"),
 *   default_formatter = "baz_formatter",
 *   default_widget = "baz_widget",
 * )
 */

类必须实现 FieldItemInterface,并且应扩展 FieldItemBase 以获得通用实现。

class BazItem extends FieldItemBase {

}

必须重写 FieldItemInterface::schema() 来告诉系统如何存储字段值。

/**
 * {@inheritdoc}
 */
public static function schema(FieldStorageDefinitionInterface $field_definition) {
  return array(
    // columns 包含字段将存储的值
    'columns' => array(
      // 本字段只保存一个值 'value'
      'value' => array(
        'type' => 'text',
        'size' => 'tiny',
        'not null' => FALSE,
      ),
    ),
  );
}

该方法返回 API schema 列定义数组。

方法 FieldItemInterface::propertyDefinitions() 提供关于字段属性的详细信息:

/**
 * {@inheritdoc}
 */
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
  $properties = [];
  $properties['value'] = DataDefinition::create('string');

  return $properties;
}

还需要重写 Map::isEmpty()(FieldItemBase 的父类)来定义字段何时为空。

/**
 * {@inheritdoc}
 */
public function isEmpty() {
  $value = $this->get('value')->getValue();
  return $value === NULL || $value === '';
}

字段设置

字段设置允许用户根据需求配置字段。如果字段有设置,需要完成以下三步:

  1. 重写 FieldItemBase::defaultFieldSettings() 来设置默认值
  2. 为这些设置定义配置 schema
  3. 创建表单让用户修改设置

步骤 1: 重写 FieldItemBase::defaultFieldSettings()

/**
 * {@inheritdoc}
 */
public static function defaultFieldSettings() {
  return [
    // 声明一个 'size' 设置,默认值为 'large'
    'size' => 'large',
  ] + parent::defaultFieldSettings();
}

步骤 2: 定义配置 schema

配置 schema 文件路径:

[MODULE ROOT]/config/schema/[MODULE_NAME].schema.yml

描述在 defaultFieldSettings() 中定义的设置的数据类型:

field.field_settings.[FIELD ID]:
  type: mapping
  label: 'FIELDNAME settings'
  mapping:
    size:
      type: string
      label: 'Size'

步骤 3: 创建表单让用户修改设置

通过重写 FieldItemBase::fieldSettingsForm() 创建表单:

/**
 * {@inheritdoc}
 */
public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
  
  $element = [];
  // 元素的 key 必须与设置名一致
  $element['size'] = [
    '#title' => $this->t('Size'),
    '#type' => 'select',
    '#options' => [
      'small' => $this->t('Small'),
      'medium' => $this->t('Medium'),
      'large' => $this->t('Large'),
    ],
    '#default_value' => $this->getSetting('size'),
  ];

  return $element;
}

实际示例

RgbItem 示例来自 Examples 模块 的 field_example:

namespace Drupal\field_example\Plugin\Field\FieldType;

use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\TypedData\DataDefinition;

/**
 * Plugin implementation of the 'field_example_rgb' field type.
 *
 * @FieldType(
 *   id = "field_example_rgb",
 *   label = @Translation("Example Color RGB"),
 *   module = "field_example",
 *   description = @Translation("Demonstrates a field composed of an RGB color."),
 *   default_widget = "field_example_text",
 *   default_formatter = "field_example_simple_text"
 * )
 */
class RgbItem extends FieldItemBase {

  /**
   * {@inheritdoc}
   */
  public static function schema(FieldStorageDefinitionInterface $field_definition) {
    return array(
      'columns' => array(
        'value' => array(
          'type' => 'text',
          'size' => 'tiny',
          'not null' => FALSE,
        ),
      ),
    );
  }

  /**
   * {@inheritdoc}
   */
  public function isEmpty() {
    $value = $this->get('value')->getValue();
    return $value === NULL || $value === '';
  }

  /**
   * {@inheritdoc}
   */
  public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
    $properties['value'] = DataDefinition::create('string')
      ->setLabel(t('Hex value'));

    return $properties;
  }

}