Создание типа поля в модуле Drupal
Типы полей определяют свойства и поведение полей. Типы полей определяются как плагины, поэтому рекомендуется ознакомиться с 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;
Аннотация над классом внутри комментария к документу должна включать уникальный идентификатор, метку и средство форматирования по умолчанию. Форматтер по умолчанию будет идентификатором, используемым в аннотации класса форматера поля.
/**
* 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 contains the values that the field will store
'columns' => array(
// List the values that the field will save. This
// field will only save a single value, 'value'
'value' => array(
'type' => 'text',
'size' => 'tiny',
'not null' => FALSE,
),
),
);
}
Этот метод возвращает массив спецификаций столбцов API схемы.
Метод 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 === '';
}
Настройки поля
Настройки поля позволяют пользователям настраивать поле в соответствии с их потребностями. Если поле имеет какие-либо настройки поля, необходимо сделать три шага:
- Переопределите FieldItemBase::defaultFieldSettings(), чтобы установить значения по умолчанию
- Создайте схему конфигурации для созданных вами настроек
- Создайте форму, чтобы позволить пользователям изменять настройки
Шаг 1: переопределить FieldItemBase::defaultFieldSettings()
/**
* {@inheritdoc}
*/
public static function defaultFieldSettings() {
return [
// Declare a single setting, 'size', with a default
// value of 'large'
'size' => 'large',
] + parent::defaultFieldSettings();
}
Шаг 2. Создайте схему конфигурации для созданных вами настроек
Схема конфигурации идет в следующем файле:
[MODULE ROOT]/config/schema/[MODULE_NAME].schema.yml
В этом файле вы опишите тип (ы) данных настроек, которые вы создали в defaultFieldSettings():
Шаг 1 создал параметр с именем «size», в котором хранится строковое значение. Схема для этого будет выглядеть следующим образом:
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 = [];
// The key of the element should be the setting name
$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 из модуля 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;
}
}