Header-Bild
Image
DrupalLogo

Best-Practices in der Arbeit mit Drupal

Wenn du eine Website auf Basis von Drupal erstellen möchtest und nicht genau weißt wie, findest du Online mehr als genügend Anleitungen, nicht zuletzt auch die offizielle Anleitung von den Herausgebern des CMS.

In diesem Artikel möchte ich dir eine Dinge zeigen, die ich bei mittlerweile jeder neuen Website einbaue und verwende, die auch dir das Leben erleichtern können. Ich werde hierbei mit der Installation beginnen und dann jeden Schritt einzeln erklären.

Alles was du in diesem Artikel beschrieben findest sind nur Empfehlungen auf Basis meiner eigenen mehrjährigen Erfahrung in der Arbeit mit Drupal, nichts davon ist also verpflichtend.

Installation

Drupal.org selbst empfiehlt seit Version 9 die Installation von Drupal mit Composer, du hast aber dennoch die Möglichkeit, das ganze System als Archivdatei herunterzuladen und einfach zu entpacken. In diesem Archiv ist zwar alles was du brauchst, ich empfehle diesen Schritt aber dennoch nicht.

Stattdessen empfehle ich dir, Drupal mit Composer zu installieren:

$ composer create-project drupal/recommended-project PROJECT

Mit dem Befehl installierst du Drupal mit dem Composer-Projekt "drupal/recommended-project", was genau enthalten ist kannst du der Packagist-Seite entnehmen.

Post-Installation

Nach dem Download bzw. dem Aufsetzen als Composer-Projekt kannst du Drupal noch nicht wirklich benutzen. Deswegen kümmern wir uns jetzt um ein paar Kleinigkeiten die teilweise lästig aber sinnvoll oder sogar nötig sind.

Git

Als allererstes werden wir ein Repository einrichten:

$ git init

Auf der Git-Plattform deiner Wahl erstellst du ebenfalls ein Repository. Wenn du GitHub verwendest, kannst du hier ein neues Repo erstellen, für andere Plattformen wie GitLab oder BitBucket solltest du in die Handbücher der Plattformen schauen, falls du Hilfe benötigst.

Wenn du das Repository eingerichtet hast, bekommst du in der Regel eine Reihe an Befehlen vorgeschlagen um dein lokales Repository mit Remote zu synchronisieren. Der wichtigste ist hierbei git remote add. Die Repository-URL ist zwar individuell, aber der vollständige Befehl sollte in etwa so aussehen:

$ git remote add origin git@HOST:VENDOR/REPO.git

Bevor du nun aber alles committest und pushst, empfehle ich dir dringend eine .gitignore-Datei anzulegen, damit nicht alles im Git landet was du gar nicht brauchst. Lass uns einmal gemeinsam durchgehen was du nicht versionieren willst.

Als erstes wären da der Drupal-Core und alle Contrib-Module sowie -Themes und -Profile:

web/core
web/modules/contrib
web/modules/README.txt
web/profiles/contrib
web/profiles/README.txt
web/themes/contrib
web/themes/README.txt

Dann der vendor-Ordner, da dieser Drittanbieter-Code beinhaltet:

vendor

Als nächstes IDE-spezifische Ordner und Dateien. Hierüber kann man natürlich streiten ob die versioniert werden sollen oder nicht. Zumal die JetBrains-IDEs in ihre Projekt-Konfigurationen nochmal eine eigene .gitignore legen. Falls du sie ignorieren möchtest:

.idea
.fleet

Was ebenfalls nicht ins Git-Repo gehört sind alle Dateien, die durch das Scaffolding beim Ausführen von composer install erstellt bzw. kopiert werden:

web/sites/*/default.services.yml
web/sites/*/default.settings.php
web/sites/*/files
web/sites/development.services.yml
web/sites/example.settings.local.php
web/sites/example.sites.php
web/sites/README.txt
web/.csslintrc
web/.eslintignore
web/.eslintrc.json
web/.ht.router.php
web/.htaccess
web/autoload.php
web/example.gitignore
web/index.php
web/INSTALL.txt
web/README.md
web/robots.txt
web/update.php
web/web.config
/.editorconfig
/.gitattributes

Jetzt noch den temporären und den privaten Ordner sowie Dateien, die sensible Daten beinhalten können:

tmp/*
!tmp/.gitkeep
private/*
!private/.gitkeep
.env
deploy.php

Zu guter Letzt ignorieren wir alles was mit Datenbanken, Archiven und jegliche Arten von Test- oder Backup-Dateien:

*.sql
*.gz
*.tar
*.zip
*.test
*.test.*
test.*
*.bak
*.bak.*

So und nun kannst du alles comitten und pushen.

Ordnerstruktur

Die Struktur von Drupal-Projekten sieht bei mir mittlerweile immer gleich aus und beinhaltet folgende Ordner:

  • config/default
    • Dieser Ordner beinhaltet alle Konfigurationen der Site "default". Hast du einen anderen Seitennamen als "default" empfehle ich dir den Namen anzupassen.
    • Diese Struktur erlaubt es dir einfach und ohne großen Aufwand weitere Seiten zu erstellen und deren Konfigurationen dann in weiteren Ordnern unter config abzulegen
  • patches
    • Alle Patches die du erstellst oder herunterlädst werden hier abgelegt
  • private, tmp
    • Die Ordner die private oder temporäre Dateien enthalten sollten außerhalb des Docroots (web) liegen und nicht erreichbar sein. Eine Ebene über dem Docroot ist also ein guter Ort
  • vendor, web
    • Drittanbieter-Code und das Docroot, beide Ordner solltest du an diesem Punkt bereits haben, da diese durch composer install erstellt werden

Grundeinstellungen

Bevor wir Drupal wirklich installieren werden wir die Grundeinstellungen in der settings.php bearbeiten damit wir die Datei comitten können ohne sensible Daten im Repository zu speichern.

Als erstes installieren wir die Bibliothek vlucas/phpdotenv mit der wir Umgebungsvariablen verwenden können:

$ composer require vlucas/phpdotenv

Als nächstes erstellen wir die Datei .env und fügen folgende Daten ein:

MYSQL_USER=
MYSQL_DATABASE=
MYSQL_HOSTNAME=
MYSQL_PASSWORD=
MYSQL_PORT=

Hier werden wir später die Datenbank konfigurieren.

Jetzt sorgen wir dafür, dass diese .env-Datei auch geladen wird. Das machen wir in zwei Schritten, erst erstellen wir eine PHP-Datei die die .env einliest und dann sorgen wir dafür, dass der Autoloader diese Datei einbindet.

Hier erstmal der Code für die PHP-Datei:

<?php
/**
 * This file is included very early. See autoload.files in composer.json and
 * https://getcomposer.org/doc/04-schema.md#files
 */
use Dotenv\Dotenv;
use Dotenv\Exception\InvalidPathException;
/**
 * Load any .env file. See /.env.example.
 */
$dotenv = Dotenv::createImmutable(__DIR__);
try {
  $dotenv->load();
}
catch (InvalidPathException $e) {
  // Do nothing. Production environments rarely use .env files.
} 

Das speichern wir unter ./load.environment.php.

Jetzt erzählen wir Composer von dieser Datei. Dazu erweitern wir die composer.json um folgenden Block:

"autoload": {
    "files": [
        "load.environment.php"
    ]
}

Composer sorgt beim nächsten Ausführen von composer install oder composer dump-autoload dafür, dass die Datei load.environment.php durch den Autoloader mit eingebunden wird. Dadurch haben wir im Drupal Zugriff auf die Umgebungsvariablen via 

$var = $_ENV;

Das machen wir uns auch direkt zunutze. Wir haben weiter oben ja die Zugangsdaten zur Datenbank definiert. Diese werden in der Datei web/sites/default/settings.php verwendet und genau dort werden wir jetzt dafür sorgen, dass statt echter Daten die Umgebungsvariablen verwendet werden.

Als erstes kopieren wir die Datei web/sites/default/default.settings.php zu web/sites/default/settings.php. Die frische Datei öffnen wir jetzt im Editor unserer Wahl. Irgendwo zwischen Zeile 80 und 100 steht folgendes (in Drupal 10.1 ist die Stelle die wir suchen in Zeile 91):

$databases = [];

Hierunter definieren wir nun die Standard-Datenbankverbindung "default":

$databases = [];
$databases['default']['default'] = array (
  'database' => $_ENV['MYSQL_DATABASE'],
  'username' => $_ENV['MYSQL_USER'],
  'password' => $_ENV['MYSQL_PASSWORD'],
  'prefix' => '',
  'host' => $_ENV['MYSQL_HOSTNAME'],
  'port' => $_ENV['MYSQL_PORT'],
  'namespace' => 'Drupal\\mysql\\Driver\\Database\\mysql',
  'driver' => 'mysql',
  'autoload' => 'core/modules/mysql/src/Driver/Database/mysql/',
);

Nach der Installation von Drupal schauen wir noch einmal in diese Datei, meine Erfahrung hat mir gezeigt, dass Drupal trotz bereits getätigter Angeben zur Datenbank trotzdem ein neues Array am Ende der Datei erstellt.

Wo wir die settings.php bereits offen haben, bearbeiten wir auch direkt noch die letzten Konfigurationen.

Alle folgenden Einstellungen könnten ebenfalls über die .env eingelesen werden. Da das aber keine sensiblen Daten sind ist es vollkommen okay, die Einstellungen auf diesem Weg zu definieren.

Als erstes setzen wir die Einstellung config_sync_directory (ab ca. Zeile 249):

$settings['config_sync_directory'] = '../config/default';

Dann die Pfade zu den privaten und temporären Ordnern (ab ca. Zeile 558):

/**
 * [...]
 */
$settings['file_private_path'] = '../private';
/**
 * [...]
 */
$settings['file_temp_path'] = '../tmp';

Fast geschafft! Jetzt nur noch die Einstellung trusted_host_pattern die dafür sorgt, dass das Drupal nur unter bestimmten Domains laufen darf. 

Um den Wert korrekt setzen zu können, musst du zunächst mal wissen unter welcher Domain deine Seite erreichbar sein wird. Nehmen wir einmal "drupal.lndo.site" als Beispiel. In diesem Fall würde die Einstellung wie folgt aussehen:

$settings['trusted_host_patterns'] = [
  '^drupal\.lndo\.site$',
  '^.+\.drupal\.lndo\.site$',
];

Was es mit der Domain "lndo.site" auf sich hat, werden wir später noch klären.

Das einzige was jetzt noch fehlt ist die Einbindung von lokalen Einstellungen. Drupal hat mit der Datei settings.local.php Grundlagen geschaffen um gut lokal mit und vor allem an Drupal arbeiten zu können. Diese Datei hebelt beispielsweise den Cache aus und schaltet die Aggregierung von CSS und JavaScript aus. Damit diese lokalen Einstellungen auch greifen musst du am Ende der settings.php folgendes einfügen:

if (file_exists($app_root . '/' . $site_path . '/settings.local.php')) {
  include $app_root . '/' . $site_path . '/settings.local.php';
}

Sollte die Datei settings.local.php bei dir im System nicht existieren, kopiere einfach web/sites/example.settings.local.php nach web/sites/default/settings.local.php.

Entwicklungsumgebung

Als lokale Entwicklungsumgebung kann ich Lando sehr empfehlen. Lando bietet eine auf Docker basierende Entiwcklungsumgebung die sehr schnell aufgesetzt und einfach konfiguriert ist.

Hast du Lando auf deinem PC installiert, navigierst du im Terminal in den Ordner wo Drupal liegt und führst folgendes aus:

$ lando init

Damit initialisierst du das Lando-Setup. Als nächstes beantwortest du ein paar Fragen wie wo das Docroot ist, welches Recipe du verwenden möchtest und wie die Anwendung heißt. 

Gibst du bei der Frage nach dem Namen "Drupal" an ist die URL unter der dein Drupal erreichbar sein wird https://drupal.lndo.site.

Als Recipe wählst du drupal10 aus und die anderen Fragen beantwortest du so wie es zu deinem Setup passt. Nachdem die Initialisierung abgeschlossen ist trägst du in die .env folgende Daten ein:

MYSQL_USER=drupal10
MYSQL_DATABASE=drupal10
MYSQL_HOSTNAME=database
MYSQL_PASSWORD=drupal10
MYSQL_PORT=3306

Mehr Informationen dazu findest du in der Lando-Dokumentation zum Drupal-10-Recipe.

Was ich an dieser Stelle noch empfehlen kann ist Mailhog und phpMyAdmin zu konfigurieren. Mailhog fängt ausgehende Mails von Drupal ab, sodass du bspw. das Theming von ausgehenden Mails testen kannst ohne eine "echte" Empfänger-Adresse angeben zu müssen und mit phpMyAdmin bekommst du eine Web-GUI zur Datenbank.

Beides konfigurierst du wie folgt in der .lando.yml:

services:
  mailhog:
    type: mailhog
    portforward: false
    hogfrom:
      - appserver
  phpmyadmin:
    type: phpmyadmin
    hosts:
      - database

Drush

Wenn man viel mit Drupal arbeitet kommt man an Drush nicht vorbei. Drush ist ein Kommandozeilenwerkzeug mit dem du viele Tasks in Drupal einfacher erledigen kannst. Du kannst beispielsweise 

drush cr

ausführen anstatt erst auf Konfiguration, dann auf Entwicklung und schlussendlich auf Leistung klicken zu müssen nur um dort nochmal auf einen Button zu klicken um alle Caches zu leeren. 

Die Installation erfolgt über Composer mit

$ composer require drush/drush

Lando ? Drush 

Nutzt du Lando als Entwicklungsumgebung kannst du Drush-Befehle direkt im Lando-Container ausführen ohne dich erst einloggen zu müssen. Häng vor jeden Drush-Befehl einfach "lando", bspw.

$ lando drush cr

und schon wird der Befehl drush cr innerhalb des appserver-Containers in Lando ausgeführt.

Hilfreiche Module und Themes

Während meiner Arbeit mit Drupal haben sich mit der Zeit einige Module und Themes herauskristallisiert, die sich immer wieder als äußerst nützlich erwiesen haben. Diese möchte ich einmal auflisten, wobei ich klar dazu sagen muss, dass ich nicht im Detail auf die Module oder Themes eingehen werde. Dieser Artikel soll ja auch irgendwann mal ein Ende haben.

Gin + Gin-Login

Gin ist ein alternatives Admin-Theme welches meiner Meinung nach nochmal schöner ist als Olivero auch wenn das schon ein erhebliches Upgrade gegenüber Seven war. Gin-Login ist ein Modul, welches dafür sorgt, dass der Login- und Registrierungsbereich im Stil von Gin daherkommt.

Installation

$ composer require drupal/gin drupal/gin_login

Aktivierung

$ drush then gin && drush en gin_login

Nun musst du nur noch das Gin-Theme unter /admin/appearance als Admin-Theme festlegen.

Admin-Toolbar

Dieses Modul bzw. dieses Modulpaket verbessert die Toolbar, die du siehst, wenn du eingeloggt bist.

Installierst du nur das "Standard"-Modul werden die Menüpunkte um Dropdowns erweitert mit denen du beim Hovern darunterliegende Menüpunkte erreichen kannst. So kannst du beispielsweise ohne einen Klick zu tätigen von der Startseite deines Drupal zu den Performance-Einstellungen.

Welches Modul ich aus diesem Paket ebenfalls empfehlen kann ist das Modul admin_toolbar_tools, das fügt dem Admin-Menü noch ein paar nützliche Links hinzu wie zum Beispiel "Alle Caches leeren" oder "Cron ausführen".

Installation

$ composer require drupal/admin_toolbar

Aktivierung

$ drush en admin_toolbar admin_toolbar_tools

Config-Ignore

Es kann sein, dass du einige Konfigurationen im Produktivsystem tätigst, die dich in deiner Arbeit im lokalen System aber eher hindern. Das können beispielsweise Konfigurationen zur Performance oder Berechtigungen sein. 

Mit dem Modul "Config Ignore" kannst du definieren welche Konfigurationen beim Import ignoriert werden sollen. 

Installation

$ composer require drupal/config_ignore

Aktivierung

$ drush en config_ignore

EU Cookie Compliance

Wie der Name schon vermuten lässt geht es bei diesem Modul um den beliebten Cookie-Banner. Optimiert für den Einsatz in der EU kannst du mit diesem Modul mit nur wenig Arbeit ein Cookiebanner erstellen und konfigurieren.

Installation

$ composer require drupal/eu_cookie_compliance

Aktivierung 

$ drush en eu_cookie_compliance

Metatag

Wem SEO auch nur ansatzweise wichtig ist und wer keine Lust hat alle SEO-relevanten Meta-Tags zu programmieren oder programmieren zu lassen, dem lege ich das Metatag-Modul wärmstens ans Herz. 

Installation

$ composer require drupal/metatag

Aktivierung

$ drush en metatag

Pathauto

Normalerweise ist es so, dass eine Node den Pfad /node/NODE_ID hat sowie ein Term den Pfad /taxonomy/term/TERM_ID hat. Das kann auch vollkommen okay sein, du oder deine Kunden wollen das aber vielleicht nicht immer. Du hast jetzt natürlich die Option dein Drupal so zu konfigurieren, dass du jeder Node und jedem Term händisch einen neuen Pfad verpasst aber das kostet Zeit, vor allem wenn du viele Inhalte hast die du bearbeiten musst.

Eine gute Hilfe ist hier das Modul Pathauto, welches dir die Arbeit abnimmt. Du konfigurierst welche Inhaltstypen, Terms, User, etc. welche Pfade bekommen sollen und beim Speichern wird der Pfad automatisch erzeugt.

Der Pfad für Artikel auf dieser Seite ist zum Beispiel /article/[node:title]-[node:created:raw].

Installation

$ composer require drupal/pathauto

Aktivierung

$ drush en pathauto