11. Februar 2022

Bundle Fields im Code definieren

Fields in Drupal 9 können entweder im Code oder in der Konfiguration definiert werden. Beide Techniken haben ihren Nutzen und ihre Vorteile. Typischerweise gelten Code Fields für alle Bundles des Entity-Typs, als sogenannte Basisfelder, während config Fields nur für ein einzelnes Bundle gelten.

Code editor image with examples for Drupal bundle fields such as getImage(), getHeadline(), and getText() for field definition.

Was sind Bundle Fields?

Es gibt eine Möglichkeit, Code Fields zu haben, die nur für bestimmte Bundles gelten. Diese werden Bundle Fields genannt und sind besonders nützlich, um berechnete Felder zu bestimmten Bundles einer Entität hinzuzufügen (mehr zu berechneten Feldern in einem zukünftigen Blogbeitrag).

Die API dafür ist ein wenig klobig, da sie für Drupal 8 nicht fertiggestellt wurde und in Zukunft möglicherweise komplett geändert wird. Wenn Sie deshalb Bedenken haben, Bundle-Felder in Ihren Code zu implementieren, sollten Sie wissen, dass der letzte Patch zu diesem Thema aus dem Jahr 2017 stammt: Es handelt sich um ein komplexes Problem ohne viele Anwendungen, das dementsprechend nicht viel Aufmerksamkeit erhält.

Bundle Fields müssen an zwei Stellen definiert werden: im Field Storage und in der Field Definition selbst. Dies ist vergleichbar mit der Funktionsweise von config Fields; es ist eigentlich dasselbe wie bei Base Fields, aber die BaseFieldDefinition verbirgt dies vor Ihnen, da sie doppelte Arbeit leistet. (Es gibt ein Issue, das die Notwendigkeit, den Speicher zu definieren, beseitigen soll, aber auch hier passiert nicht viel).

Sie benötigen auch eine Field definition Class. Das Entity-Contrib-Modul bietet eine BundleFieldDefinition-Klasse, aber wenn dieses Modul nicht nur für eine einzige Klasse installieren werden soll, kann diese Klasse auch einfach in das Custom Modul kopiert werden.

(Es gibt eine Klasse in Core FieldDefinition, die zu diesem Zweck hinzugefügt wurde, die jedoch eine Storage Class benötigt, um mit ihr zusammenzuarbeiten, und das Issue, dies bereitzustellen, wurde noch nicht behoben).

Sobald Sie diese Klasse haben, hängt die Art und Weise, wie Sie das Feld definieren, von der Entität ab, der Sie es hinzufügen wollen.

Bundle Fields auf dem eigenen Entity Type

Im eigenen Entity Type wird die Entity Class definiert. Hier kann daher die Methode bundleFieldDefinitions() in dieser Class implementiert werden:

Damit wird das Field definiert. Da es sich um Bundle Fields handelt, muss die Speicherung separat in hook_entity_field_storage_info() definiert werden. Wir können jedoch den Vorteil nutzen, dass die Class BundleFieldDefinition sowohl als Storage als auch als Field fungiert und die Definition in der Entity Class einfach mitnehmen:

Die Dokumentation für hook_entity_bundle_field_info() schlägt vor, es andersherum zu machen und zuerst den Storage zu definieren und dann das Field vom Storage abzuleiten. Aber wenn man es auf die oben gezeigte Weise macht, bedeutet das, dass sich der Code für das Field in der Entitätsklasse befindet, wo er neben der Definition des Base Fields liegt und leichter zu finden ist.

Bundle Fields auf einem anderen Entity Type

Für einen Entity Type, der nicht kontrolliert wird, kann die Entitätsklasse in eine custom Unterklasse umgewandelt und bundleFieldDefinitions() in dieser implementiert werden. Leichter ist es jedoch hook_entity_bundle_field_info() zu verwenden.

Wir verwenden hier den gleichen Huckepack-Trick. Wenn ein anderer Entity Type geändert wird, macht es genauso viel Sinn, den Storage zu definieren und das Field abzuleiten, aber durch das Befolgen des gleichen Musters wie bei der custom Entität stimmen die beiden Methoden weiterhin überein.

Wie zu sehen, handelt es sich bei diesem Bereich des Entity-Systems von Drupal um einen Bereich, der leider unvollständig ist und sich in Zukunft noch ändern kann. Nichtsdestotrotz zeigt das Beispiel der Bundle-Fields, dass es sich lohnt, sie zu verwenden, da sie sehr nützlich sind. Wichtig ist hierbei sicherzustellen, dass dies im Code dokumentiert wird, damit künftige Entwickler*innen wissen, dass es sich um einen Bereich des Codes handelt, der möglicherweise gewartet werden muss, wenn die API aktualisiert wird. Und immer die Drupal Core Change Records im Auge behalten!

Portrait of Joachim Noreiko, a team member of Factorial.

Joachim Noreiko

Freelancer Drupal developer

Visit me on my profile on drupal.org

joachim@factorial.io

Verwandte Artikel