Erstellen eines Feldformatierers
Ein Feldformatierer-Modul formatiert die Felddaten für die Anzeige durch den Endbenutzer. Feldformatierer werden als Plugins definiert, daher empfiehlt es sich, die Plugin-API zu studieren, bevor man einen neuen Feldformatierer schreibt.
Die Klasse des Feldformatierers
Datei: /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; /** * Plugin-Implementierung des 'Random_default' Formatierers. * * @FieldFormatter( * id = "Random_default", * label = @Translation("Random text"), * field_types = { * "Random" * } * ) */ class RandomDefaultFormatter extends FormatterBase { /** * {@inheritdoc} */ public function settingsSummary() { $summary = []; $summary[] = $this->t('Zeigt den zufälligen Text an.'); return $summary; } /** * {@inheritdoc} */ public function viewElements(FieldItemListInterface $items, $langcode) { $element = []; foreach ($items as $delta => $item) { // Rendere jedes Element als Markup. $element[$delta] = ['#markup' => $item->value]; } return $element; } }
Formatierer-Einstellungen
Wenn Ihr Formatierer benutzerdefinierte Anzeigeeinstellungen benötigt, sind dafür drei Schritte notwendig:
- Überschreiben Sie PluginSettingsBase::defaultSettings(), um Standardwerte zu definieren
- Erstellen Sie ein Konfigurationsschema für Ihre Einstellungen
- Erstellen Sie ein Formular, das Benutzern erlaubt, die Einstellungen zu ändern
Schritt 1: Überschreiben Sie PluginSettingsBase::defaultSettings(), um Standardwerte festzulegen
/** * {@inheritdoc} */ public static function defaultSettings() { return [ // Definieren Sie eine Einstellung namens 'text_length' mit // Standardwert 'short'. 'text_length' => 'short', ] + parent::defaultSettings(); }
Schritt 2: Erstellen Sie ein Konfigurationsschema für Ihre Einstellungen
Das Konfigurationsschema befindet sich in:
[MODULROOT]/config/schema/[MODULNAME].schema.yml
Dort beschreiben Sie die Datentypen der Einstellungen, die Sie in defaultSettings() definiert haben:
Schritt 1 hat die Einstellung 'text_length' als String definiert. Das Schema sieht so aus:
field.formatter.settings.[FORMATTER-ID]: type: mapping label: 'FORMATTER-NAME Textlänge' mapping: text_length: type: string label: 'Textlänge'
Schritt 3: Erstellen Sie ein Formular, mit dem Benutzer die Einstellungen ändern können
Das Formular wird durch Überschreiben von FormatterBase::settingsForm() erstellt.
Vergessen Sie nicht, den Namensraum für FormStateInterface am Anfang der PHP-Datei hinzuzufügen:
use Drupal\Core\Form\FormStateInterface;
/** * {@inheritdoc} */ public function settingsForm(array $form, FormStateInterface $form_state) { $form['text_length'] = [ '#title' => $this->t('Textlänge'), '#type' => 'select', '#options' => [ 'short' => $this->t('Kurz'), 'long' => $this->t('Lang'), ], '#default_value' => $this->getSetting('text_length'), ]; return $form; }
Verwendung von #ajax in Einstellungsformularen
Die Nutzung von #ajax in Einstellungsformularen ist nicht trivial, da die Formularfragmente, die in settingsForm() erzeugt werden, nicht an der Wurzel des Formulars stehen, sondern tief verschachtelt sind. Im folgenden Beispiel gibt es zwei Einstellungen: display_type, das entweder „label“ oder „entity“ sein kann, und entity_display_mode, das entweder „full“ oder „teaser“ sein kann. Der Anzeige-Modus wird nur angezeigt, wenn display_type auf „entity“ gesetzt ist.
public function settingsForm(array $form, FormStateInterface $form_state) { $form['display_type'] = [ '#title' => $this->t('Anzeige-Typ'), '#type' => 'select', '#options' => [ 'label' => $this->t('Label'), 'entity' => $this->t('Entity'), ], '#default_value' => $this->getSetting('display_type'), '#ajax' => [ 'wrapper' => 'private_message_thread_member_formatter_settings_wrapper', 'callback' => [$this, 'ajaxCallback'], ], ]; $form['entity_display_mode'] = [ '#prefix' => '', '#suffix' => '', ]; // Hole den Feldnamen des aktuellen Feldes $field_name = $this->fieldDefinition->getItemDefinition()->getFieldDefinition()->getName(); // Bestimme den Schlüssel der Einstellung, dessen Wert abgerufen werden soll $setting_key = 'display_type'; // Versuche, einen Wert aus dem FormState abzurufen (existiert bei Erstaufruf nicht) if ($value = $form_state->getValue(['fields', $field_name, 'settings_edit_form', 'settings', $setting_key])) { $display_type = $value; } else { // Beim ersten Laden den Standardwert holen $display_type = $this->getSetting('display_type'); } if ($display_type == 'entity') { $form['entity_display_mode']['#type'] = 'select'; $form['entity_display_mode']['#title'] = $this->t('Ansichtsmodus'); $form['entity_display_mode']['#options'] = [ 'full' => $this->t('Voll'), 'teaser' => $this->t('Teaser'), ]; $form['entity_display_mode']['#default_value'] = $this->getSetting('entity_display_mode'); } else { // Erzwinge das Rendern des Elements (damit der AJAX-Wrapper angezeigt wird), auch wenn kein Wert gesetzt ist $form['entity_display_mode']['#markup'] = ''; } return $form; }
Erstellen Sie dann den Ajax-Callback und geben das zu aktualisierende Formularelement zurück:
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]; }
Dependency Injection in Feldformatierern
Die Nutzung von Dependency Injection in Feldformatierern erfordert drei Schritte:
- Implementieren Sie das Interface ContainerFactoryPluginInterface
- Implementieren Sie ContainerFactoryPluginInterface::create()
- Überschreiben Sie den Konstruktor FormatterBase::__construct()
1) Interface ContainerFactoryPluginInterface implementieren
use Drupal\Core\Plugin\ContainerFactoryPluginInterface; class MyFormatter extends FormatterBase implements ContainerFactoryPluginInterface {
2) Implementierung von ContainerFactoryPluginInterface::create()
Dieses Beispiel injiziert den Service entity.manager in den Formatter:
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'], // Hier die Services injizieren, die Sie benötigen $container->get('entity.manager') ); }
3) Konstruktor FormatterBase::__construct() überschreiben
Überschreiben Sie den Konstruktor, rufen Sie parent::__construct() auf und speichern Sie den Service in einer Klassen-Eigenschaft:
use Drupal\Core\Field\FieldDefinitionInterface; /** * Der Entity Manager Service. * * @var \Drupal\Core\Entity\EntityManagerInterface */ protected $entityManager; /** * Konstruktor für MyFormatter. * * @param string $plugin_id * Die Plugin-ID der Instanz. * @param mixed $plugin_definition * Die Plugin-Definition. * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition * Definition des Feldes. * @param array $settings * Die Formatierer-Einstellungen. * @param string $label * Die Label-Anzeigeeinstellung. * @param string $view_mode * Der View-Modus. * @param array $third_party_settings * Drittanbieter-Einstellungen. * @param \Drupal\Core\Entity\EntityManagerInterface $entityManager * Entity Manager Service. */ 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; }
Jetzt können Sie den Entity Manager überall in Ihrer Formatter-Klasse über $this->entityManager verwenden.
Drupal’s online documentation is © 2000-2020 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution-ShareAlike 2.0. PHP code is distributed under the GNU General Public License.