Artikel
von Patrick Froch

Contao 4: Installation von Erweiterungen - Grundlagen

In dieser Artikelserie soll es darum gehen, wie man Erweiterungen unter Contao 4 installieren kann. Für Open Source Module ist dies recht einfach, man kann sie im Manager suchen und installieren. Für Entwickler, bei denen verschiedenste Anforderungen vorkommen, sieht die Sache aber leider ganz anders aus. Gerade wenn man Kundenerweiterungen hat, die nicht öffentlich zugänglich sein dürfen, wir es schwierig. Ein anderes Thema sind Kommerzielle Erweiterungen, die gefunden werden sollen, aber nicht einfach so installiert werden dürfen. Ein weiterer Fall sind Bibliotheken, die nicht einzeln installiert werden dürfen, da sie nur als Grundlage für eigene Projekte dienen sollen. Man sieht, es gibt viele Bereiche, die zur Zeit nur schwer mit Contao zu realisieren sind.

Disclaimer

Wie immer gilt, das hier gesagte erhebt keinen Anspruch auf Vollständigkeit! Da es wenig offizielle Informationen gibt, ist alles selbst ausprobiert, oder aus verschiedenen Quellen zusammengesucht. Ich übernehme keine Garantie für die Richtigkeit der Informationen und wie immer gilt zur Zeit bei Contao, was heute richtig ist, kann morgen schon wieder falsch sein.

Grundlagen

In diesem Artikel sollen erst einmal Grundlagen für die Entwicklungsumgebung geschaffen werden. In weiteren Texten werde ich auf die verschiedenen Installationsmöglichkeiten eingehen.

Managed Edition

In der Managed Edition von Contao können wir die meisten Konfigurationsmöglichkeiten von Symfony nicht nutzen. Sie funktionieren zwar, da auch unter Contao das Verzeichnis app/ eingelesen wird, wenn wir unsere Erweiterung aber später irgendwo installieren wollen, wird dies nicht ohne weiteres gehen, da die Einstellungen nicht enthalten wären.

Manager Plugin

Wir benötigen das Manager Plugin, um unsere Erweiterung zu konfigurieren. Hier ergibt sich gleich das nächste Problem. Denn das offizielle Handbuch sagt einerseits:

Each application can have one global class ContaoManagerPlugin which will be automatically loaded if it exists. We recommend this to be located in your app folder ...

Man soll also das Plugin ContaoManagerPlugin nennen und im Verzeichnis app/ speichern. Dies ist wie gesagt sehr ungünstig, wenn man seine Erweiterungen später installieren möchte.

Andererseits sagt das Handbuch:

Each Composer package can have one plugin, and it must be registered in the composer.json.

Wir können also pro Paket ein Plugin erstellen und dies in der composer.json registrieren. Das kling ja schon viel besser.

Aber was den nun??? An dieser Stelle habe ich einige Stunden meines Lebens versenkt, bis ich durch ausprobieren auf die richtige eine funktionierende Lösung gekommen bin. Es handelt sich um zwei unterschiedliche Dinge!

In unserer Entwicklungsumgebung wird das Plugin der Erweiterung nicht geladen, da sie nicht ins Verzeichnis vendor/ installiert wurde. Bei mir liegen die Erweiterungen unter src/Esit/NAMEderERWEITERUNG. Hier muss auch das Plugin liegen. Es sollte einen Namespace haben. Ist dies nicht der Fall werden alle Plugins im globalen Namespace überschrieben. Also keine gute Idee! Dieses Plugin wird verwendet, wenn unsere Erweiterung per Composer oder dem Manager installiert wurde.

Im Gegensatz dazu muss in unserer Entwicklungsumgebung das Plugin ContaoManagerPlugin heißen und im Verzeichnis app/ liegen. (Auch wenn letzteres nicht zwingend ist, da in der compsoer.json der classmap-Eintrag direkt auf die Datei zeigt.) Dieses Plugin darf keinen Namespace haben. Ansonsten ist es genauso aufgebaut, wie das Plugin in unserer Erweiterung.

Das Vorgehen mit dem doppelten Plugin, ist natürlich alles andere als schön. Leider habe ich keinen anderen Weg gefunden. Wenn hier jemand einen eleganteren Weg kennt, lasst es mich bitte wissen.

Das Plugin der Erweiterung könnte so aussehen:

Das Plugin in der Entwicklungsumgebung könnte so aussehen:

Wie man sieht unterscheiden sich die Plugins nur durch den Namen und das Fehlen des Namespaces von einander.

composer.json

Wie bereits oben beschrieben müssen wir das Plugin der Erweiterung in der composer.json registrieren. Auch hier gibt es wieder zwei, einmal die von Contao mitgebrachte (die im Document Root liegt) und die in unserer Erweiterung. Letztere sagt, wie unser Paket installiert wird und welche Abhängigkeiten es gibt.

In der composer.json ist darauf zu achten, dass sich die Einträge für die Namespaces unterscheiden.

Die globale comopser.json mit den nötigen Einträgen könnte z.B. so aussehen:

(TL_ROOT/composer.json)

Hier ist nur der Abschnitt autoload neu. Der Eintrag unter classmap zeigt auf das globale Manager Plugin der Entwicklungsumgebung. Der psr-4-Eintrag ist für das Laden unserer Klassen in der Entwicklungsumgebung zuständig.

Die composer.json der Erweiterung sieht ganz anders aus:

(TL_ROOT/src/Esit/Core/composer.json)

Auch hier gibt es einen Abschnitt autload. Der darin enthaltene Eintrag psr-4 geht vom aktuellen Verzeichnis als Root aus und nicht vom Document Root der Contao-Installation. Dies ist extrem wichtig, da sonst nach der Installation unsere Klassen nicht gefunden werden.

Der zweite wichtige Punkt ist der Abschnitt extra, dort wird das Manager Plugin konfigurieren. Hier wird einfach der Namespace des Plugins eingetragen.

Unter name sollten scheinbar nur Kleinbuchstaben verwendet werden.

Ich musste beim Ausprobieren jedes Mal ein copmoer update ausführen, damit die Änderungen wirksam wurden! Ein Leeren des Caches oder Erstellen des Autoloaders reichte nicht aus!

Laden der Einstellungen

Unter Symfony werden viele Einstellungen, wie z.B. Services und Listener, in YAML-Dateien gespeichert. Diese können über das Plugin geladen werden. In den beiden Plugins sind dann aber die Pfade unterschiedlich. Dies finde ich sehr unschön. Zum Glück kann man auch einfache eine Extension-Klasse im Verzeichnis DependencyInjection im Root der Erweiterung anlegen. Symfony lädt diese Klasse automatisch und wir können dort unsere YAML-Dateien laden. Dies funktioniert in der Entwicklungsumgebung und der späteren Installation.

Der Rest

Selbstverständlich benötigen wir auch eine Bundle-Klassen und den ganzen Rest. Aber dies alles sollte mittlerweile bekannt sein und wurde auch schon mehrfach hier im Blog behandelt.

So weit zu den Voraussetzungen für eine erfolgreiche Installation. Wir können nun ganz normal unsere Erweiterung entwickeln. Auf die verschiedenen Wege, wie diese in einer anderen Contao-Instanz installiert wird, gehe ich in den weiteren Texten dieser Serie ein.

Zurück

Kommentare

Aufgrund der unklaren Rechtslage durch die DSGV habe ich mich entschlossen, die Kommentare bis auf Weiteres zu deaktivieren.