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;
}
}