滚动
创建字段小部件
字段小部件用于在表单中渲染字段。字段小部件被定义为插件,因此在编写新的字段类型之前,建议先熟悉 插件 API。
在 Drupal 8 中创建字段小部件,需要一个带有 FieldWidget 注解的类。
类的位置 应该是 /[MODULE_NAME]/src/Plugin/Field/FieldWidget,例如:/foo/src/Plugin/Field/FieldWidget/BarWidget.php。
类的命名空间 应该是 [MODULE_NAME]\Plugin\Field\FieldWidget,例如:\Drupal\foo\Plugin\Field\FieldWidget。
类上的注解 必须包含唯一的 ID、标签以及此小部件可以处理的字段类型 ID 数组。
/**
* A widget bar.
*
* @FieldWidget(
* id = "bar",
* label = @Translation("Bar widget"),
* field_types = {
* "baz",
* "string"
* }
* )
*/
类 必须实现 WidgetInterface,并且可以扩展 WidgetBase 来提供通用实现。唯一必须实现的方法是 ::formElement(),它必须返回实际渲染你的小部件的表单元素。
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
//...
class BarWidget extends WidgetBase {
/**
* {@inheritdoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$element = [];
// 构建元素渲染数组。
return $element;
}
}
小部件设置
如果你的小部件需要额外的设置,需要执行以下三个步骤:
- 重写 PluginSettingsBase::defaultSettings() 来设置默认值
- 为你创建的设置定义配置 schema
- 创建表单,让用户可以修改这些设置
步骤 1: 重写 PluginSettingsBase::defaultSettings() 设置默认值
/**
* {@inheritdoc}
*/
public static function defaultSettings() {
return [
// 创建自定义设置 'size',默认值为 60
'size' => 60,
] + parent::defaultSettings();
}
步骤 2: 为自定义设置定义配置 schema
配置 schema 文件路径:
/[MODULE_NAME]/config/schema/[MODULE_NAME].schema.yml
在该文件中描述在 defaultSettings() 中声明的设置的数据类型:
field.widget.settings.[WIDGET ID]:
type: mapping
label: 'WIDGET NAME widget settings'
mapping:
size:
type: integer
label: 'Size'
步骤 3: 创建表单,让用户修改设置
通过重写 WidgetBase::settingsForm() 创建表单:
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$element['size'] = [
'#type' => 'number',
'#title' => $this->t('Size of textfield'),
'#default_value' => $this->getSetting('size'),
'#required' => TRUE,
'#min' => 1,
];
return $element;
}
你还可以在小部件的摘要中列出这些设置:
/**
* {@inheritdoc}
*/
public function settingsSummary() {
$summary = [];
$summary[] = $this->t('Textfield size: @size', array('@size' => $this->getSetting('size')));
return $summary;
}
你可以使用 getSetting() 方法在小部件中获取设置值:
class BarWidget extends WidgetBase implements WidgetInterface {
/**
* {@inheritdoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$element['value'] = $element + [
'#type' => 'textfield',
'#default_value' => isset($items[$delta]->value) ? $items[$delta]->value : NULL,
'#size' => $this->getSetting('size'),
];
return $element;
}
}
小部件示例
TextWidget 示例来自 Examples 模块 的 field_example:
namespace Drupal\field_example\Plugin\Field\FieldWidget;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Plugin implementation of the 'field_example_text' widget.
*
* @FieldWidget(
* id = "field_example_text",
* module = "field_example",
* label = @Translation("RGB value as #ffffff"),
* field_types = {
* "field_example_rgb"
* }
* )
*/
class TextWidget extends WidgetBase {
/**
* {@inheritdoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$value = isset($items[$delta]->value) ? $items[$delta]->value : '';
$element += [
'#type' => 'textfield',
'#default_value' => $value,
'#size' => 7,
'#maxlength' => 7,
'#element_validate' => [
[static::class, 'validate'],
],
];
return ['value' => $element];
}
/**
* 验证颜色文本字段。
*/
public static function validate($element, FormStateInterface $form_state) {
$value = $element['#value'];
if (strlen($value) == 0) {
$form_state->setValueForElement($element, '');
return;
}
if (!preg_match('/^#([a-f0-9]{6})$/iD', strtolower($value))) {
$form_state->setError($element, t("Color must be a 6-digit hexadecimal value, suitable for CSS."));
}
}
}