Erstellen eines Feldtyps in einem Drupal-Modul
Feldtypen definieren die Eigenschaften und das Verhalten von Feldern. Feldtypen werden als Plugins definiert, daher empfiehlt es sich, die Plugin-API zu studieren, bevor man einen neuen Feldtyp schreibt.
Um einen Feldtyp in Drupal 8 zu erstellen, benötigen Sie eine Klasse mit der Annotation FieldType.
Der Speicherort der Feldtyp-Klasse sollte in MODULE_NAME/src/Plugin/Field/FieldType liegen.
Beispiel: /modules/foo/src/Plugin/Field/FieldType/BazItem.php
Der Namespace dieser Klasse sollte Drupal\MODULE_NAME\Plugin\Field\FieldType sein.
<?php namespace Drupal\MODULE_NAME\Plugin\Field\FieldType;
Die Annotation über der Klasse im DocBlock muss eine eindeutige ID, eine Beschriftung und einen Standard-Formatter enthalten. Der Standard-Formatter ist der Identifikator, der in der Annotation der Feldformatter-Klasse verwendet wird.
/**
* Bietet einen Feldtyp 'baz'.
*
* @FieldType(
* id = "baz",
* label = @Translation("Baz-Feld"),
* default_formatter = "baz_formatter",
* default_widget = "baz_widget",
* )
*/
Die Klasse muss das Interface FieldItemInterface implementieren und sollte FieldItemBase für eine allgemeine Implementierung erweitern.
class BazItem extends FieldItemBase {
}
FieldItemInterface::schema() muss überschrieben werden, um dem System mitzuteilen, wie die Feldwerte gespeichert werden.
/**
* {@inheritdoc}
*/
public static function schema(FieldStorageDefinitionInterface $field_definition) {
return [
// 'columns' enthält die Werte, die das Feld speichert.
'columns' => [
// Dieses Feld speichert nur einen Wert 'value'.
'value' => [
'type' => 'text',
'size' => 'tiny',
'not null' => FALSE,
],
],
];
}
Diese Methode gibt ein Array von Spaltenspezifikationen für die Schema-API zurück.
Die Methode FieldItemInterface::propertyDefinitions() gibt dem System detailliertere Informationen über die Eigenschaften Ihres Feldes.
/**
* {@inheritdoc}
*/
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
$properties = [];
$properties['value'] = DataDefinition::create('string');
return $properties;
}
Die Methode Map::isEmpty() (Elternklasse von FieldItemBase) muss überschrieben werden, um dem System mitzuteilen, wann das Feld leer ist.
/**
* {@inheritdoc}
*/
public function isEmpty() {
$value = $this->get('value')->getValue();
return $value === NULL || $value === '';
}
Feldeinstellungen
Feldeinstellungen erlauben es Benutzern, ein Feld an ihre Bedürfnisse anzupassen. Wenn das Feld Feldeinstellungen besitzt, sind drei Schritte notwendig:
- Überschreiben Sie FieldItemBase::defaultFieldSettings(), um Standardwerte zu definieren
- Erstellen Sie ein Konfigurationsschema für Ihre Einstellungen
- Erstellen Sie ein Formular, um Benutzern die Änderung der Einstellungen zu ermöglichen
Schritt 1: Überschreiben Sie FieldItemBase::defaultFieldSettings()
/**
* {@inheritdoc}
*/
public static function defaultFieldSettings() {
return [
// Definieren Sie eine Einstellung 'size' mit
// Standardwert 'large'.
'size' => 'large',
] + parent::defaultFieldSettings();
}
Schritt 2: Erstellen Sie ein Konfigurationsschema für Ihre Einstellungen
Das Konfigurationsschema befindet sich in:
[MODULROOT]/config/schema/[MODULNAME].schema.yml
Dort beschreiben Sie die Datentypen der Einstellungen aus defaultFieldSettings():
Schritt 1 hat die Einstellung 'size' als String definiert. Das Schema sieht so aus:
field.field_settings.[FIELD-ID]:
type: mapping
label: 'FELDNAME Einstellungen'
mapping:
size:
type: string
label: 'Größe'
Schritt 3: Erstellen Sie ein Formular, mit dem Benutzer die Einstellungen ändern können
Das Formular wird durch Überschreiben von FieldItemBase::fieldSettingsForm() erstellt.
/**
* {@inheritdoc}
*/
public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
$element = [];
// Der Schlüssel muss dem Einstellungsnamen entsprechen
$element['size'] = [
'#title' => $this->t('Größe'),
'#type' => 'select',
'#options' => [
'small' => $this->t('Klein'),
'medium' => $this->t('Mittel'),
'large' => $this->t('Groß'),
],
'#default_value' => $this->getSetting('size'),
];
return $element;
}
Praktisches Beispiel
RgbItem aus dem Modul field_example im Examples-Projekt:
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-Implementierung des Feldtyps 'field_example_rgb'.
*
* @FieldType(
* id = "field_example_rgb",
* label = @Translation("Beispiel Farbe RGB"),
* module = "field_example",
* description = @Translation("Demonstriert ein Feld, das aus einer RGB-Farbe besteht."),
* default_widget = "field_example_text",
* default_formatter = "field_example_simple_text"
* )
*/
class RgbItem extends FieldItemBase {
/**
* {@inheritdoc}
*/
public static function schema(FieldStorageDefinitionInterface $field_definition) {
return [
'columns' => [
'value' => [
'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-Wert'));
return $properties;
}
}