Creazione di un tipo di campo in un modulo Drupal
I tipi di campo definiscono le proprietà e il comportamento dei campi. I tipi di campo sono definiti come plugin, quindi è consigliato leggere l’API dei plugin prima di iniziare a scrivere un nuovo tipo di campo.
Per creare un tipo di campo in Drupal 8, serve una classe con l’annotazione FieldType.
Percorso della classe del tipo di campo: MODULE_NAME/src/Plugin/Field/FieldType
/modules/foo/src/Plugin/Field/FieldType/BazItem.php
Namespace della classe: Drupal\MODULE_NAME\Plugin\Field\FieldType
<?php namespace Drupal\MODULE_NAME\Plugin\Field\FieldType;
L’annotazione sopra la classe nel docblock deve includere un identificatore univoco, un’etichetta e il formattatore predefinito. Il formattatore predefinito sarà l’ID usato nell’annotazione della classe del formattatore di campo.
/** * Fornisce un tipo di campo baz. * * @FieldType( * id = "baz", * label = @Translation("Baz field"), * default_formatter = "baz_formatter", * default_widget = "baz_widget", * ) */
La classe deve implementare l’interfaccia FieldItemInterface ed estendere FieldItemBase per un’implementazione comune.
class BazItem extends FieldItemBase { }
FieldItemInterface::schema() deve essere sovrascritto per indicare al sistema come memorizzare i valori del campo:
/** * {@inheritdoc} */ public static function schema(FieldStorageDefinitionInterface $field_definition) { return array( // columns contiene i valori che il campo salverà 'columns' => array( // Questo campo salverà solo un valore: 'value' 'value' => array( 'type' => 'text', 'size' => 'tiny', 'not null' => FALSE, ), ), ); }
Questo metodo restituisce un array di specifiche delle colonne secondo l’API dello schema.
Il metodo FieldItemInterface::propertyDefinitions() fornisce al sistema informazioni dettagliate sulle proprietà del campo:
/** * {@inheritdoc} */ public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) { $properties = []; $properties['value'] = DataDefinition::create('string'); return $properties; }
Il metodo Map::isEmpty (ereditato da FieldItemBase) deve essere sovrascritto per indicare quando il campo è vuoto:
/** * {@inheritdoc} */ public function isEmpty() { $value = $this->get('value')->getValue(); return $value === NULL || $value === ''; }
Impostazioni del campo
Le impostazioni del campo permettono agli utenti di configurare il campo in base alle loro esigenze. Se un campo ha impostazioni, occorre seguire tre passaggi:
- Sovrascrivere FieldItemBase::defaultFieldSettings() per definire i valori predefiniti
- Creare lo schema di configurazione per queste impostazioni
- Creare un form che permetta agli utenti di modificarle
Passo 1: Sovrascrivere FieldItemBase::defaultFieldSettings()
/** * {@inheritdoc} */ public static function defaultFieldSettings() { return [ // Dichiara un’impostazione 'size' con valore predefinito 'large' 'size' => 'large', ] + parent::defaultFieldSettings(); }
Passo 2. Creare lo schema di configurazione
Lo schema si trova nel file:
[MODULE ROOT]/config/schema/[MODULE_NAME].schema.yml
In questo file si definiscono i tipi di dati delle impostazioni create in defaultFieldSettings():
Il passo 1 ha creato un parametro chiamato “size” che memorizza una stringa. Lo schema sarà così:
field.field_settings.[FIELD ID]: type: mapping label: 'FIELDNAME settings' mapping: size: type: string label: 'Size'
Passo 3: Creare un form per modificare le impostazioni
Il form per modificare i valori viene creato sovrascrivendo FieldItemBase::fieldSettingsForm()
/** * {@inheritdoc} */ public function fieldSettingsForm(array $form, FormStateInterface $form_state) { $element = []; // La chiave dell’elemento deve essere il nome dell’impostazione $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; }
Esempio reale
RgbItem dal modulo field_example del progetto Examples:
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; /** * Implementazione del plugin 'field_example_rgb' come tipo di campo. * * @FieldType( * id = "field_example_rgb", * label = @Translation("Example Color RGB"), * module = "field_example", * description = @Translation("Dimostra un campo composto da un colore RGB."), * 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; } }