9.3. Erstellen eines benutzerdefinierten Drupal-Moduls. Programmatische Seitenausgabe.
Beginnen wir mit der Erstellung unseres Moduls mit ein wenig Ordnung. Lassen Sie uns weiterhin benutzerdefinierte und bereitgestellte Module trennen. In Drupal befinden sich Module im /modules-Ordner. Jetzt müssen wir sie nicht mehr tief in /sites/all/modules ablegen, obwohl in der Readme steht, dass dies funktionieren sollte, verwenden Sie schließlich den /modules-Ordner. Innerhalb des /modules-Ordners erstellen wir zwei Ordner: custom und contrib. Im Ordner contrib werden zusätzliche Module von drupal.org gespeichert, und unsere benutzerdefinierten Module werden im Ordner custom abgelegt.
Englische Untertitel:
Code-Beispiele sind auf GitHub verfügbar:
https://github.com/levmyshkin/drupalbook8
So eine Kleinigkeit wie die Trennung der Module in contrib- und custom-Ordner erscheint vielleicht überflüssig, aber glauben Sie mir, wenn Sie 200 Contrib-Module und 30 benutzerdefinierte Module auf Ihrer Seite haben, werden Sie verstehen, wie schwierig es ist, alle benutzerdefinierten Module und den ganzen benutzerdefinierten Code auf der Seite zu finden. Außerdem, wenn Sie Code in einem Plug-in-Modul ändern (was nur bei absoluter Notwendigkeit geschehen sollte), wäre es ebenfalls gut, es in den custom-Ordner zu verschieben, damit Sie Ihre Änderungen bei einem Update nicht versehentlich überschreiben (oder ein anderer Entwickler überschreibt Ihre Änderungen, oder sogar Sie selbst, ohne es zu ahnen, überschreiben die Änderungen eines anderen Entwicklers).
Erstellen wir also unser benutzerdefiniertes Modul. Erstellen Sie den Ordner /modules/custom/drupalbook. In diesem Ordner müssen wir die Datei drupalbook.info.yml erstellen:
name: DrupalBook
description: Custom module for learning Drupal 8
type: module
core: 8.x
core_version_requirement: ^8 || ^9
package: DrupalBook
* Die .info.yml-Datei ist für die Beschreibung des Moduls verantwortlich. Die darin angegebenen Informationen werden auf der Seite „Erweiterungen“ (Extend) angezeigt. Der Dateiname besteht aus dem Modulnamen + .info.yml.
Drupal YML-Dateien sind ein Standardformat für Konfigurationen und Einstellungen. Felder und Werte in YML-Dateien sind durch Doppelpunkte getrennt, eine neue Zeile beginnt mit einer Einrückung von zwei Leerzeichen. Die Formatierung ist für eine YML-Datei sehr wichtig, wenn ein Fehler in der Formatierung gemacht wird, zum Beispiel ein zusätzliches Leerzeichen oder ein fehlender Doppelpunkt, kann Drupal einen Fehler ausgeben oder die YML-Datei nicht korrekt lesen.
Gehen Sie auf die Seite „Erweiterungen“ und aktivieren Sie Ihr Modul:
Nun, da wir das Modul eingebunden haben, können wir Funktionalität hinzufügen und es wird auf unserer Seite funktionieren. Um anzufangen, werden wir einfachen Text auf der Seite ausgeben. Dazu müssen wir eine weitere YML-Datei drupalbook.routing.yml erstellen:
drupalbook.first_page:
path: '/first-page'
defaults:
_controller: '\Drupal\drupalbook\Controller\FirstPageController::content'
_title: 'Hello World!'
requirements:
_permission: 'access content'
Werfen wir einen genaueren Blick auf den Inhalt dieser YML-Datei.
drupalbook.first_page: – das ist der Name unserer Route, über den Drupal eine Liste aller Routen und Pfade sammelt. Dieser Name muss eindeutig sein, es ist am besten, module_name.route_name zu verwenden, da Sie mehrere Routen in einem Modul haben können: drupalbook.first_page, drupalbook.second_page usw.
path: '/first-page' – der Pfad zu Ihrer Route. Achten Sie auf die Einrückung mit zwei Leerzeichen, diese ist zwingend erforderlich. Wenn Ihr Editor beim Drücken der Tabulatortaste Tabs einfügt, sollten Sie diese Einstellung ändern und stattdessen zwei Leerzeichen verwenden.
defaults: – definiert die Standardeinstellungen der Route und wie die Route erstellt wird. Es gibt mehrere Möglichkeiten, eine Route zu erstellen, eine davon ist über eine Controller-Klasse, aber auch andere Klassen sind möglich, um Routen dynamisch zu erstellen. Wir werden später vielleicht alle Möglichkeiten durchgehen, aber jetzt betrachten wir ein einfaches Beispiel über eine Controller-Klasse. Das Routing in Drupal ist von Symfony migriert und verwendet Symfony-Bibliotheken. Symfony ist ein MVC-Framework, sehr ordentlich, das auch in anderen Projekten, z. B. Laravel, verwendet wird. MVC steht für Model, View, Controller (hier ist View keine Views-Modul-Ansicht, sondern einfach eine Vorlage zur Darstellung von Informationen; Model sind Entitätsklassen, mit denen Informationen in die Datenbank eingefügt werden können, ähnlich wie das Entity API in Drupal). Der Controller wird hier für das Routing benötigt, was wir in dieser Lektion tun.
_controller: '\Drupal\drupalbook\Controller\FirstPageController::content' – Hier geben wir an, welche PHP-Klasse unsere Seite anzeigen wird. Nach dem Klassennamen mit :: geben wir an, welche Methode der Klasse die Seite darstellen soll. Die vielen Backslashes sind notwendig, damit Drupal versteht, in welchem Ordner sich die PHP-Klasse befindet.
_title: 'Hello World!' – Der Titel unserer Seite
_permission: 'access content' – Berechtigung, um diese Seite anzusehen, der Benutzer muss eine Rolle mit diesem Recht haben, um die Seite zu öffnen.
Nachdem wir die YML-Datei für das Routing hinzugefügt haben, müssen wir die PHP-Klasse hinzufügen, die unsere Seite anzeigt. Zunächst müssen wir das automatische Laden von Klassendateien aus unseren Modulen verstehen. Es gibt viele Klassen in Drupal, und nicht alle werden für eine bestimmte Seite geladen, deshalb werden nur die benötigten Klassen geladen. Drupal verwendet PHP Auto-Loading nach PSR-4:
https://www.php-fig.org/psr/psr-4/
Werfen wir einen Blick auf die Zeile in der Route, in der wir die PHP-Klasse angegeben haben:
\Drupal\drupalbook\Controller\FirstPageController
\Drupal bedeutet, dass die Klasse über die Drupal-Bibliothek geladen wird. Drupal ist mittlerweile auch eine eigenständige, wenn auch umfangreiche Bibliothek, die über Packagist eingebunden werden kann:
https://packagist.org/packages/drupal/drupal
Als Nächstes geben wir an, welches Modul wir verwenden möchten:
\drupalbook
Danach geben wir entweder direkt den Klassennamen im Ordner unseres Moduls an oder eine weitere Verschachtelung. Alle Ordner liegen dann im src-Ordner, also wenn wir den Controller-Ordner angegeben haben, liegt dieser hier:
/modules/custom/drupalbook/src/Controller
Achten Sie auf Groß- und Kleinschreibung, PHP unterscheidet zwischen Controller und controller.
Zum Schluss geben wir den Dateinamen an, dem wir .php hinzufügen müssen:
/modules/custom/drupalbook/src/Controller/FirstPageController.php
Erstellen wir diese Datei:
/**
* @file
* Contains \Drupal\drupalbook\Controller\FirstPageController.
*/
namespace Drupal\drupalbook\Controller;
/**
* Provides route responses for the DrupalBook module.
*/
class FirstPageController {
/**
* Returns a simple page.
*
* @return array
* A simple renderable array.
*/
public function content() {
$element = array(
'#markup' => 'Hello World!',
);
return $element;
}
}
So sollte die Struktur der Dateien aussehen:
Jetzt müssen wir den Cache leeren, damit unsere neue Route geladen wird. Die Seite sollte dann erreichbar sein unter http://drupalbook/first-page:
Werfen wir nun einen Blick auf die PHP-Klasse, die diese Seite anzeigt.
/**
* @file
* Contains \Drupal\drupalbook\Controller\FirstPageController.
*/
Hier geben wir den Pfad an, wie auch in der routing.yml-Datei, damit Drupal weiß, wo diese Klasse gefunden wird.
namespace Drupal\drupalbook\Controller;
Der namespace gibt den Pfad zu Ihrer Klassendatei an. Seien Sie vorsichtig, wenn Sie Code von anderen Seiten kopieren, ändern Sie den Modulnamen in Ihrem namespace entsprechend, hier ist es drupalbook, bei Ihnen kann es anders heißen.
class FirstPageController {
/**
* Returns a simple page.
*
* @return array
* A simple renderable array.
*/
public function content() {
$element = array(
'#markup' => 'Hello World!',
);
return $element;
}
}
Und hier unsere Klasse, die die Seite darstellt. Sie hat eine Methode content(), die wir in drupalbook.routing.yml angegeben haben. Diese Methode gibt ein Array mit dem Element #markup zurück, in dem wir den HTML-Ausgabeinhalt speichern. Wir geben ein Array zurück, keine Zeichenkette, weil über eine reguläre Route nicht nur HTML, sondern auch JSON-Endpunkte für APIs, XML- oder CSV-Dateien ausgegeben werden können.
Den Code des Moduls können Sie auf GitHub ansehen:
https://github.com/levmyshkin/drupalbook8
Das war's, in der nächsten Lektion werden wir die Möglichkeiten unseres Moduls weiter ausbauen.