Création d’un widget pour un champ
Les widgets de champ sont utilisés pour afficher un champ dans les formulaires. Les widgets de champ sont définis comme des plugins, il est donc recommandé de consulter l’API des plugins avant de créer un nouveau type de champ.
Pour créer un widget de champ dans Drupal 8, vous avez besoin d’une classe avec l’annotation FieldWidget.
Emplacement de la classe du widget de champ : /[NOM_MODULE]/src/Plugin/Field/FieldWidget
. Par exemple : /foo/src/Plugin/Field/FieldWidget/BarWidget.php
.
Namespace de cette classe : [NOM_MODULE]\Plugin\Field\FieldWidget
. Par exemple : \Drupal\foo\Plugin\Field\FieldWidget
.
L’annotation au-dessus de la classe doit inclure un identifiant unique, une étiquette et un tableau des types de champs que ce widget peut gérer.
/** * Un widget bar. * * @FieldWidget( * id = "bar", * label = @Translation("Widget Bar"), * field_types = { * "baz", * "string" * } * ) */
La classe doit implémenter l’interface WidgetInterface. Elle peut étendre WidgetBase pour une implémentation commune de l’interface. La seule méthode obligatoire à implémenter est ::formElement(), qui doit retourner les éléments de formulaire représentant votre widget.
use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Field\WidgetBase; use Drupal\Core\Form\FormStateInterface; // ... class BarWidget extends WidgetBase { /** * {@inheritdoc} */ public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) { $element = []; // Construisez le tableau de rendu de l’élément. return $element; } }
Paramètres du widget
Si votre widget nécessite des paramètres supplémentaires, vous devez suivre trois étapes :
- Redéfinir PluginSettingsBase::defaultSettings() pour définir les valeurs par défaut
- Créer un schéma de configuration pour vos paramètres
- Créer un formulaire permettant aux utilisateurs de modifier ces paramètres
Étape 1 : redéfinir PluginSettingsBase::defaultSettings() pour les valeurs par défaut
/** * {@inheritdoc} */ public static function defaultSettings() { return [ // Créez un paramètre personnalisé 'size' avec une valeur par défaut de 60. 'size' => 60, ] + parent::defaultSettings(); }
Étape 2 : créer le schéma de configuration pour ces paramètres
Le schéma de configuration se trouve dans :
/[NOM_MODULE]/config/schema/[NOM_MODULE].schema.yml
Dans ce fichier, vous décrivez le type des paramètres que vous avez définis dans defaultSettings() :
Étape 1 a créé un paramètre « size » contenant un entier. Le schéma sera :
field.widget.settings.[ID_WIDGET]: type: mapping label: 'Paramètres du widget WIDGET_NAME' mapping: size: type: integer label: 'Taille'
Étape 3 : créer un formulaire pour modifier ces paramètres
Ce formulaire s’implémente en redéfinissant WidgetBase::settingsForm().
/** * {@inheritdoc} */ public function settingsForm(array $form, FormStateInterface $form_state) { $element['size'] = [ '#type' => 'number', '#title' => $this->t('Taille du champ texte'), '#default_value' => $this->getSetting('size'), '#required' => TRUE, '#min' => 1, ]; return $element; }
Vous pouvez aussi afficher un résumé des paramètres sélectionnés dans settingsSummary() :
/** * {@inheritdoc} */ public function settingsSummary() { $summary = []; $summary[] = $this->t('Taille du champ texte : @size', ['@size' => $this->getSetting('size')]); return $summary; }
Utilisez la méthode getSetting() pour récupérer un paramètre dans le widget :
Exemple :
class BarWidget extends WidgetBase implements WidgetInterface { /** * {@inheritdoc} */ public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) { $element['value'] = $element + [ '#type' => 'textfield', '#default_value' => isset($items[$delta]->value) ? $items[$delta]->value : NULL, '#size' => $this->getSetting('size'), ]; return $element; } }
Exemple de widget
Le TextWidget du module Examples :
namespace Drupal\field_example\Plugin\Field\FieldWidget; use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Field\WidgetBase; use Drupal\Core\Form\FormStateInterface; /** * Plugin implementation of the 'field_example_text' widget. * * @FieldWidget( * id = "field_example_text", * module = "field_example", * label = @Translation("Valeur RGB en format #ffffff"), * field_types = { * "field_example_rgb" * } * ) */ class TextWidget extends WidgetBase { /** * {@inheritdoc} */ public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) { $value = isset($items[$delta]->value) ? $items[$delta]->value : ''; $element += [ '#type' => 'textfield', '#default_value' => $value, '#size' => 7, '#maxlength' => 7, '#element_validate' => [ [static::class, 'validate'], ], ]; return ['value' => $element]; } /** * Valide le champ couleur. */ public static function validate($element, FormStateInterface $form_state) { $value = $element['#value']; if (strlen($value) == 0) { $form_state->setValueForElement($element, ''); return; } if (!preg_match('/^#([a-f0-9]{6})$/iD', strtolower($value))) { $form_state->setError($element, t("La couleur doit être une valeur hexadécimale à 6 chiffres, compatible CSS.")); } } }