logo

Extra Block Types (EBT) - Neue Erfahrung im Layout Builder❗

Extra Block Types (EBT) - gestylte, anpassbare Blocktypen: Diashows, Registerkarten, Karten, Akkordeons und viele andere. Eingebaute Einstellungen für Hintergrund, DOM Box, Javascript Plugins. Erleben Sie die Zukunft der Layouterstellung schon heute.

Demo EBT-Module EBT-Module herunterladen

❗Extra Absatztypen (EPT) - Erfahrung mit neuen Absätzen

Extra Paragraph Types (EPT) - analoger, auf Absätzen basierender Satz von Modulen.

Demo EPT-Module EPT-Module herunterladen

Scroll

9.10. Drupal Fields API. Drupal-Felder in der Datenbank.

27/05/2025, by Ivan

Menu

mysql

In diesem Artikel verstehen wir, wie Felder in Drupal funktionieren, warum sie benötigt werden und wie Felder helfen, Websites in Drupal schnell zu entwickeln.

Wir haben bereits in früheren Artikeln mit Feldern gearbeitet:

7.5. Dienste-Block mit Bootstrap-Spalten gestalten

7.6. Isotope Gallery für Drupal

7.7. Block mit YouTube-Video in Drupal

Nun werden wir herausfinden, wie es funktioniert. Gehen wir zur Bearbeitung der Inhaltsfelder des Inhaltstyps Artikel und fügen ein neues Feld vom Typ Link hinzu:

/admin/structure/types/manage/article/fields

Feld hinzufügen

Wenn Sie einen neuen Artikel erstellen, haben Sie zwei Eingabefelder für URL und Linktext:

Link

Jedes Mal, wenn Sie über die Administration ein neues Feld erstellen, werden zwei Tabellen in der Datenbank angelegt:

{entity_type}__{field_name}
{entity_type}_revision__{field_name}

Drupal unterstützt Revisionen, daher werden alle Daten mindestens einmal dupliziert, da die einzige Revision die aktuelle Revision Ihres Artikels ist. Somit sind die Felder und die gesamte Drupal Fields API notwendig, um die Arbeit mit der Datenbank zu vereinfachen. Wir erstellen einfach Felder über das Admin-Interface, und Drupal legt die Tabellen in der Datenbank an.

Aus dem Namen der MySQL-Tabellen sollte klar sein, dass dasselbe Feld für unterschiedliche Entitätstypen verwendet werden kann. Zum Beispiel können wir das Link-Feld nun auch im Inhaltstyp „Basis-Seite“ verwenden, da es bereits existiert:

/admin/structure/types/manage/page/fields/add-field

Feld hinzufügen

Möchten Sie jedoch ein Link-Feld in einem Block erstellen, müssen Sie ein neues Feld anlegen. Dasselbe Feld kann nicht in Entitäten unterschiedlichen Typs verwendet werden. Erstellen wir nun ein Link-Feld für den Basiskblock:

/admin/structure/block/block-content/manage/basic/fields/add-field

Wie Sie sehen, gibt es bei der Feld-Erstellung keine Möglichkeit, ein bestehendes Link-Feld auszuwählen, da Block und Node unterschiedliche Entitätstypen sind.

Wie bei Nodes werden auch für Blöcke zwei Tabellen zur Speicherung der Daten des Link-Felds angelegt:

Tabellen und Views

block_content_revision__field_link und block_content__field_link.

Nun sehen wir uns an, wie Drupal die Daten desselben Felds für unterschiedliche Bundle von Nodes speichert. Wir haben das Link-Feld für den Inhaltstyp Artikel erstellt und es dann für den Inhaltstyp Basis-Seite wiederverwendet. Zur besseren Übersicht lädt man am besten die Website-Konfiguration in einen Ordner herunter und betrachtet die Dateien, oder man sucht in der Tabelle config (z.B. via Adminer oder phpMyAdmin) nach der benötigten Konfiguration:

Konfiguration auswählen

Wenn Sie nach allen Konfigurationen suchen, die das Wort „link“ enthalten:

SELECT * FROM `config` WHERE CONVERT(`name` USING utf8mb4) LIKE '%link%' LIMIT 50

finden Sie folgende Konfigurationen für unser Feld field_link:

field.field.block.block_content.basic.field_link
field.field.node.article.field_link
field.field.node.page.field_link
field.storage.block_content.field_link
field.storage.node.field_link

Für jeden Entitätstyp erstellt jedes Feld seine eigene Field Storage Konfiguration. Diese Konfiguration definiert, wie Daten in den Tabellen {entity_type}__{field_name} und {entity_type}_revision__{field_name} gespeichert werden. In unserem Fall sind das die Tabellen block_content__field_link, block_content_revision__field_link, node__field_link und node_revision__field_link. Im Folgenden betrachten wir, wie das Link-Modul die Daten speichert. Öffnen wir die Field Storage Konfiguration für das Link-Feld:

uuid: dba847ef-f4d6-4462-a2ee-f642a007fca6
langcode: en
status: true
dependencies:
  module:
    - block_content
    - link
id: block_content.field_link
field_name: field_link
entity_type: block_content
type: link
settings: {  }
module: link
locked: false
cardinality: 1
translatable: true
indexes: {  }
persist_with_no_fields: false
custom_storage: false

Gehen wir die Zeilen durch, damit klar wird, was in der Field Storage Konfiguration gespeichert ist.

uuid: dba847ef-f4d6-4462-a2ee-f642a007fca6
Hier ist die eindeutige Config-ID gespeichert. Sie müssen das Feld nicht manuell auf einer Staging-Umgebung erstellen, wenn Sie es lokal erstellt und die Konfiguration hochgeladen haben. Das Feld wird automatisch erstellt. Löschen Sie das Feld lokal und importieren die Änderung auf Staging, werden alle Daten gelöscht. Haben Sie also ein Feld auf Staging erstellt, laden Sie die Konfiguration hoch und fügen Sie diese zu Git hinzu, um Ihre Änderungen nicht zu verlieren.

langcode: en
Auf mehrsprachigen Seiten werden für unterschiedliche Sprachversionen von Nodes in der Feldtabelle alle Daten für alle Sprachen gespeichert, wobei angegeben wird, welche Sprache welche Daten verwendet:

select

Ich habe die gleiche Sprache, daher ist die Standard-Sprache in der Konfiguration ebenfalls gleich.

status: true
Der Status zeigt an, ob diese Konfiguration aktiviert oder deaktiviert ist. Die Field Storage Konfiguration verwendet die erstellte Konfigurationsentität in Drupal, siehe die Klasse FieldStorageConfig, die von ConfigEntityBase erbt:

https://api.drupal.org/api/drupal/core!modules!field!src!Entity!FieldStorageConfig.php/class/FieldStorageConfig/8.2.x

dependencies:
  module:
    - block_content
    - link

Abhängigkeiten von Zusatzmodulen. Da wir das Link-Feld in Blöcken verwendet haben, ist das Modul Block Content Pflicht.

id: block_content.field_link
Der eindeutige Name unserer Konfiguration.

field_name: field_link
Der maschinenlesbare Name des Felds. Diesen Namen verwendet Drupal z.B. beim Zugriff auf das Node-Objekt mit $node->field_link->uri. Wie man auf das Entitätsfeld zugreift, behandeln wir in späteren Artikeln ausführlich.

entity_type: block_content
Der Entitätstyp, für den diese Field Storage Konfiguration gilt.

type: link
Drupal-Feldtyp. Wir werden unseren eigenen Feldtyp erstellen, aber jetzt wissen wir, dass dieser Link-Feldtyp vom Link-Modul erstellt wird. Sie können die Klasse ansehen:

core/modules/link/src/Plugin/Field/FieldType/LinkItem.php

die in unserem Modul verwendet wird.

settings: { }
Hier werden die Einstellungen für den Feldtyp gespeichert, aktuell leer. Zum Beispiel hat das Body-Feld eine Einstellung, ob die Teaser-Anzeige aktiviert ist oder nicht:

config/sync/field.field.block_content.basic.body.yml

settings:
display_summary: false

module: link
Das Modul, das den Link-Feldtyp bereitstellt. In unserem Fall haben Modulname und Feldtyp denselben Namen, das muss aber nicht sein, z.B. kann ein Modul mehrere Feldtypen implementieren, wie beim Modul DateTime:

core/modules/datetime/src/Plugin/Field/FieldType/DateTimeFieldItemList.php
core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItem.php

locked: false
Zeigt an, ob das Feld für die Bearbeitung gesperrt ist, d.h. ob die Feldeinstellungen geändert werden können. Zum Beispiel war das Feld Billing Information im Commerce-Modul gesperrt, da es zwingend benötigt wurde, wenn Lieferung und Steuerberechnung verwendet wurden.

cardinality: 1
Die Anzahl der Werte, die pro Entität für dieses Feld eingegeben werden können. Wir haben einen Wert ausgewählt, es kann aber auch 2, 3, 5 usw. sein. Für unbegrenzte Werte wird cardinality: -1 verwendet.

translatable: true
Gibt an, ob das Feld mehrsprachig ist.

indexes: { }
Zusätzliche SQL-Indizes zur besseren Suche in diesem Feld. Dies dient der Konfiguration und Optimierung von Datenbankabfragen.

persist_with_no_fields: false
Gibt an, ob die Field Storage gelöscht werden soll, wenn das Feld aus allen Entitäten entfernt wurde. Zum Beispiel wird die Field Storage nicht gelöscht, wenn das Feld aus Artikel und Basis-Seite gelöscht wurde.

custom_storage: false
Custom Storage bedeutet, dass für die Speicherung der Felddaten eine eigene Tabelle verwendet wird, nicht die Standardtabelle {entity_type}__{field_name}. Wir nutzen das hier nicht, aber manchmal ist das für die Integration mit anderen Systemen praktisch.

Öffnen wir nun die Datei des Link-Feldtyps:

core/modules/link/src/Plugin/Field/FieldType/LinkItem.php

Wir sehen, welche Daten das Feld in der Datenbank speichert. Das zeigt die Methode propertyDefinitions():

public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
  $properties['uri'] = DataDefinition::create('uri')
    ->setLabel(t('URI'));

  $properties['title'] = DataDefinition::create('string')
    ->setLabel(t('Link text'));

  $properties['options'] = MapDataDefinition::create()
    ->setLabel(t('Options'));

  return $properties;
}

Wir speichern also die Daten URI, Titel und Optionen. Öffnet man die Tabelle node__field_link, sieht man die gleichen Felder:

select

Wir sind nun beim Thema Fields API in Drupal angekommen. Wir erstellen einen Feldtyp in einem PHP-Modul mit der Klasse LinkItem. Damit können wir ein Feld für eine Entität erstellen, um dann Daten einzugeben und in der Datenbank zu speichern. Dies betrifft die Dateneingabe. Die Fields API konfiguriert außerdem das Formular für die Dateneingabe und die Ausgabe der Felder.

Zurück zum Erstellen der Felder für die Inhaltstypen Artikel und Basis-Seite: Für das Field Storage gibt es eine Konfigurationsdatei in Node: field.storage.node.field_link.yml, und bei der Feld-Erstellung gibt es für jedes Bundle eine weitere Konfigurationsdatei, z.B. jetzt drei Konfigurationsdateien für das Feld:

field.field.node.article.field_link.yml
field.field.node.page.field_link.yml
field.field.block.block_content.basic.field_link.yml

Diese Konfigurationen speichern Daten aus dem Einstellungsformular des Felds:

link

So können wir das Formular für die Dateneingabe für ein Feld in verschiedenen Bundles unterschiedlich anpassen. Jede einzelne Feldkonfiguration im Bundle heißt in Drupal Field Instance. Zuerst erstellen wir ein Field Storage Feld, das dann in jeder Instanz in Bundles separat verwendet werden kann. In Drupal 8 gibt es, anders als in Drupal 7, keine speziellen Funktionen mehr für Field Instances, die Funktionalität wurde ins CRUD API migriert:

https://www.drupal.org/node/2054619

Beispiele zur Arbeit mit Feldern per Code finden Sie in der offiziellen Dokumentation:

https://www.drupal.org/node/2012896

Wir haben hier nur den Teil der Fields API betrachtet, der die Speicherung von Felddaten in der Datenbank betrifft. In den nächsten Lektionen sehen wir, wie die Fields API mit der Dateneingabe und -ausgabe der Felder arbeitet und wie man einen eigenen vollständigen Feldtyp erstellt.