logo

Types de blocs supplémentaires (EBT) – Nouvelle expérience de Layout Builder❗

Types de blocs supplémentaires (EBT) – types de blocs stylisés et personnalisables : diaporamas, onglets, cartes, accordéons et bien d’autres. Paramètres intégrés pour l’arrière-plan, la boîte DOM, les plugins JavaScript. Découvrez dès aujourd’hui le futur de la création de mises en page.

Démo des modules EBT Télécharger les modules EBT

❗Types de paragraphes supplémentaires (EPT) – Nouvelle expérience Paragraphes

Types de paragraphes supplémentaires (EPT) – ensemble de modules basé sur les paragraphes analogiques.

Démo des modules EPT Télécharger les modules EPT

Défilement
05/07/2025, by Ivan

Menu

Un module de formateur de champ formate les données d’un champ pour l’affichage final à l’utilisateur. Les formatteurs de champ sont définis comme des plugins, il est donc recommandé de se familiariser avec l’API des plugins avant de créer un nouveau formateur de champ.

Classe du formateur de champ

Fichier : /modules/random/src/Plugin/Field/FieldFormatter/RandomDefaultFormatter.php

<?php

namespace Drupal\random\Plugin\Field\FieldFormatter;

use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Field\FieldItemListInterface;

/**
 * Implémentation du plugin du formateur 'Random_default'.
 *
 * @FieldFormatter(
 *   id = "Random_default",
 *   label = @Translation("Texte aléatoire"),
 *   field_types = {
 *     "Random"
 *   }
 * )
 */
class RandomDefaultFormatter extends FormatterBase {

  /**
   * {@inheritdoc}
   */
  public function settingsSummary() {
    $summary = [];
    $summary[] = $this->t('Affiche la chaîne aléatoire.');
    return $summary;
  }

  /**
   * {@inheritdoc}
   */
  public function viewElements(FieldItemListInterface $items, $langcode) {
    $element = [];

    foreach ($items as $delta => $item) {
      // Rendre chaque élément en tant que markup.
      $element[$delta] = ['#markup' => $item->value];
    }

    return $element;
  }

}

Paramètres du formateur

Si votre formateur nécessite des réglages personnalisés d’affichage, trois étapes sont nécessaires :

  • Redéfinir PluginSettingsBase::defaultSettings() pour définir les valeurs par défaut
  • Créer un schéma de configuration pour les réglages créés
  • Créer un formulaire pour permettre aux utilisateurs de modifier ces réglages

Étape 1 : redéfinir PluginSettingsBase::defaultSettings() pour définir les valeurs par défaut

/**
 * {@inheritdoc}
 */
public static function defaultSettings() {
  return [
    // Déclare un paramètre nommé 'text_length',
    // avec une valeur par défaut 'short'
    'text_length' => 'short',
  ] + parent::defaultSettings();
}

Étape 2 : créer un schéma de configuration pour vos réglages

Le schéma de configuration se place dans :

[MODULE ROOT]/config/schema/[MODULE_NAME].schema.yml

Dans ce fichier, vous décrivez le(s) type(s) de données des réglages créés dans defaultSettings() :

Étape 1 a créé un paramètre nommé 'text_length' qui stocke une chaîne. Le schéma correspondant ressemble à :

field.formatter.settings.[ID_DU_FORMATTEUR]:
  type: mapping
  label: 'Longueur du texte pour FORMATTER NAME'
  mapping:
    text_length:
      type: string
      label: 'Longueur du texte'

Étape 3 : créer un formulaire pour permettre aux utilisateurs de modifier les réglages

Le formulaire pour modifier les réglages est créé en redéfinissant FormatterBase::settingsForm().

N’oubliez pas d’ajouter l’espace de noms pour FormStateInterface en début de fichier PHP :

use Drupal\Core\Form\FormStateInterface;
/**
 * {@inheritdoc}
 */
public function settingsForm(array $form, FormStateInterface $form_state) {
  $form['text_length'] = [
    '#title' => $this->t('Longueur du texte'),
    '#type' => 'select',
    '#options' => [
      'short' => $this->t('Court'),
      'long' => $this->t('Long'),
    ],
    '#default_value' => $this->getSetting('text_length'),
  ];

  return $form;
}

Utilisation de #ajax dans les formulaires de réglages

L’utilisation de #ajax dans les formulaires de réglages est complexe car le fragment de formulaire généré par settingsForm() n’est pas à la racine du formulaire, mais imbriqué profondément. Dans l’exemple ci-dessous, le formulaire possède deux réglages : display_type, qui peut être "label" ou "entity", et entity_display_mode, qui peut être "full" ou "teaser". Le mode d’affichage de l’entité est affiché uniquement si display_type vaut "entity".

public function settingsForm(array $form, FormStateInterface $form_state) {
  $form['display_type'] = [
    '#title' => $this->t('Type d’affichage'),
    '#type' => 'select',
    '#options' => [
      'label' => $this->t('Étiquette'),
      'entity' => $this->t('Entité'),
    ],
    '#default_value' => $this->getSetting('display_type'),
    '#ajax' => [
      'wrapper' => 'private_message_thread_member_formatter_settings_wrapper',
      'callback' => [$this, 'ajaxCallback'],
    ],
  ];

  $form['entity_display_mode'] = [
    '#prefix' => '<div id="private_message_thread_member_formatter_settings_wrapper">',
    '#suffix' => '</div>',
  ];

  // Récupérer le nom du champ actuel
  $field_name = $this->fieldDefinition->getItemDefinition()->getFieldDefinition()->getName();
  // Clé du réglage à récupérer
  $setting_key = 'display_type';

  // Essayer d’obtenir la valeur dans l’état du formulaire (absente au premier chargement)
  if ($value = $form_state->getValue(['fields', $field_name, 'settings_edit_form', 'settings', $setting_key])) {
    $display_type = $value;
  }
  else {
    // Sinon, valeur par défaut
    $display_type = $this->getSetting('display_type');
  }

  if ($display_type == 'entity') {
    $form['entity_display_mode']['#type'] = 'select';
    $form['entity_display_mode']['#title'] = $this->t('Mode d’affichage');
    $form['entity_display_mode']['#options'] = [
      'full' => $this->t('Complet'),
      'teaser' => $this->t('Résumé'),
    ];
    $form['entity_display_mode']['#default_value'] = $this->getSetting('entity_display_mode');
  }
  else {
    // Forcer le rendu pour que le wrapper AJAX soit affiché même sans valeur
    $form['entity_display_mode']['#markup'] = '';
  }

  return $form;
}

Créez ensuite la callback ajax qui retourne l’élément de formulaire approprié :

public function ajaxCallback(array $form, FormStateInterface $form_state) {
  $field_name = $this->fieldDefinition->getItemDefinition()->getFieldDefinition()->getName();
  $element_to_return = 'entity_display_mode';

  return $form['fields'][$field_name]['plugin']['settings_edit_form']['settings'][$element_to_return];
}

Injection de dépendances dans les formatteurs de champ

Pour utiliser l’injection de dépendances dans les formatteurs de champ, trois étapes sont nécessaires :

1) Implémenter l’interface ContainerFactoryPluginInterface

use Drupal\Core\Plugin\ContainerFactoryPluginInterface;

class MyFormatter extends FormatterBase implements ContainerFactoryPluginInterface {

2) Implémenter ContainerFactoryPluginInterface::create()

Exemple d’injection du service entity.manager dans le formateur :

use Symfony\Component\DependencyInjection\ContainerInterface;

public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
  return new static(
    $plugin_id,
    $plugin_definition,
    $configuration['field_definition'],
    $configuration['settings'],
    $configuration['label'],
    $configuration['view_mode'],
    $configuration['third_party_settings'],
    // Ajouter ici les services à injecter
    $container->get('entity.manager')
  );
}

3) Redéfinir FormatterBase::__construct()

Redéfinissez __construct() dans FormatterBase, n’oubliez pas d’appeler parent::__construct(), puis sauvegardez le service dans une propriété de la classe :

use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Entity\EntityManagerInterface;

/**
 * Service entity manager.
 *
 * @var \Drupal\Core\Entity\EntityManagerInterface
 */
protected $entityManager;

/**
 * Constructeur de MyFormatter.
 *
 * @param string $plugin_id
 *   L’ID du plugin.
 * @param mixed $plugin_definition
 *   La définition du plugin.
 * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
 *   Définit l’interface pour les définitions de champ d’entité.
 * @param array $settings
 *   Les réglages du formateur.
 * @param string $label
 *   Le paramètre d’affichage de l’étiquette du formateur.
 * @param string $view_mode
 *   Le mode d’affichage.
 * @param array $third_party_settings
 *   Les réglages tiers éventuels.
 * @param \Drupal\Core\Entity\EntityManagerInterface $entityManager
 *   Service entity manager.
 */
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, EntityManagerInterface $entityManager) {
  parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings);

  $this->entityManager = $entityManager;
}

Vous pouvez maintenant utiliser le gestionnaire d’entités n’importe où dans votre classe de formateur via $this->entityManager.