Een field type maken in een Drupal-module
Field types bepalen de eigenschappen en het gedrag van velden. Field types worden gedefinieerd als plugins, daarom is het aan te raden om kennis te maken met de Plugin API voordat je een nieuw field type gaat schrijven.
Om een field type in Drupal 8 te maken, heb je een klasse nodig met een FieldType-annotatie.
Locatie van de field type-klasse moet zijn: MODULE_NAME/src/Plugin/Field/FieldType
/modules/foo/src/Plugin/Field/FieldType/BazItem.php
Namespace van deze klasse moet zijn: Drupal\MODULE_NAME\Plugin\Field\FieldType
<?php namespace Drupal\MODULE_NAME\Plugin\Field\FieldType;
De annotatie boven de klasse in de docblock moet een uniek ID, label en een standaard formatter bevatten. De standaard formatter is het ID dat gebruikt wordt in de annotatie van de field formatter-klasse.
/** * Provides a field type of baz. * * @FieldType( * id = "baz", * label = @Translation("Baz field"), * default_formatter = "baz_formatter", * default_widget = "baz_widget", * ) */
De klasse moet het FieldItemInterface implementeren en moet FieldItemBase uitbreiden voor de basisimplementatie van het interface.
class BazItem extends FieldItemBase { }
FieldItemInterface::schema() moet worden overschreven om het systeem te vertellen hoe de waarden voor het veld moeten worden opgeslagen.
/** * {@inheritdoc} */ public static function schema(FieldStorageDefinitionInterface $field_definition) { return array( // columns bevat de waarden die het veld zal opslaan 'columns' => array( // Lijst van waarden die opgeslagen worden. Dit veld // slaat slechts één waarde op: 'value' 'value' => array( 'type' => 'text', 'size' => 'tiny', 'not null' => FALSE, ), ), ); }
Deze methode retourneert een array met kolomspecificaties voor de Schema API.
De methode FieldItemInterface::propertyDefinitions() geeft het systeem meer details over de eigenschappen van je veld.
/** * {@inheritdoc} */ public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) { $properties = []; $properties['value'] = DataDefinition::create('string'); return $properties; }
De methode Map::isEmpty (voorouder van FieldItemBase) moet worden overschreven, zodat het systeem weet wanneer het veld leeg is.
/** * {@inheritdoc} */ public function isEmpty() { $value = $this->get('value')->getValue(); return $value === NULL || $value === ''; }
Field settings
Field settings stellen gebruikers in staat een veld aan te passen naar hun behoeften. Als een veld field settings heeft, moeten er drie stappen worden uitgevoerd:
- Overschrijf FieldItemBase::defaultFieldSettings() om standaardwaarden in te stellen
- Maak een configuratieschema voor de gemaakte instellingen
- Maak een formulier waarmee gebruikers de instellingen kunnen wijzigen
Stap 1: overschrijf FieldItemBase::defaultFieldSettings()
/** * {@inheritdoc} */ public static function defaultFieldSettings() { return [ // Definieer de instelling 'size' met een standaardwaarde 'large' 'size' => 'large', ] + parent::defaultFieldSettings(); }
Stap 2. Maak een schema voor de gemaakte instellingen
Het configuratieschema wordt geplaatst in het bestand:
[MODULE ROOT]/config/schema/[MODULE_NAME].schema.yml
In dit bestand beschrijf je het type gegevens dat je hebt gedefinieerd in defaultFieldSettings():
Stap 1 creëerde een parameter genaamd ‘size’, waarin een stringwaarde wordt opgeslagen. Het schema daarvoor ziet er zo uit:
field.field_settings.[FIELD ID]: type: mapping label: 'FIELDNAME settings' mapping: size: type: string label: 'Size'
Stap 3: Maak een formulier waarmee gebruikers de instellingen kunnen wijzigen
Het formulier voor het aanpassen van de instellingen wordt gemaakt door FieldItemBase::fieldSettingsForm() te overschrijven.
/** * {@inheritdoc} */ public function fieldSettingsForm(array $form, FormStateInterface $form_state) { $element = []; // De sleutel van het element moet overeenkomen met de naam van de instelling $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; }
Voorbeeld uit de praktijk
RgbItem uit de module field_example in het Examples-project:
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; } }