Im Jahr 2015 wurde entschieden, unsere CMS um WordPress zu erweitern und ich bekam die Aufgabe, das Plugin für WordPress zu erstellen. Die Entwicklung wurde anfangs stark vorangetrieben, funktional orientiert, jedoch ohne Backend-GUI. Alle Einstellungen waren in Konfigurationsdateien untergebracht, was oft hart, frustrierend und sehr unhandlich für die Webdesigner war.

Die Entwicklung des Backend-GUI wurde im Oktober 2017 gestartet. Im Commit-Graph sieht man ab dem Zeitpunkt deutlich mehr Commits.

Mein erster Eindruck vom WordPress-Basissystem war negativ:

  • WordPress enthält viel prozedurales PHP, gekoppelt an ein Event-System.
  • Es gibt Hürden wie globale Variablen oder Zustände.
  • Logik und Daten sind nicht gut getrennt und der Quellcode steht in Dateien, die viele Funktionen, Klassen oder Darstellungslogik enthalten und per include geladen werden.

Man findet zwar viele anfängerfreundliche Tutorials, die den Einstieg erleichtern. Für erweiterte Themen muss allerdings viel Quellcode studiert werden, weil die Dokumentationen hier nicht weiterhelfen.

Workflow in unserem Plugin

onOffice arbeitet bei anderen PHP-Softwareprodukten mit einem DI-Framework. Auch beim WordPress-Plugin wurde dies aufgenommen, was allerdings nicht das hauseigene DI, sondern php-di (php-di.org) ist.

In Klassen soll möglichst viel Logik liegen und alle Klassen sollen testbar sein. Um dieses Ziel zu erreichen, müssen große Teile des WordPress-Codes in Klassen gewrappt werden, da eine gute Testbarkeit sonst kaum zu erreichen ist. Die Unit-Tests erstellen wir mit PHPUnit.

Features und Bugfixes werden in einem neuen Branch erstellt, der von der QA-Abteilung vor dem Merge in den master manuell getestet wird. Das QA-Team testet dabei die Release-Konfiguration.

Ein Push eines neuen Git-Tags triggert automatisch eine Veröffentlichung ins WP-SVN. Ein Tag wird erstellt, sobald Unittests und manuelle Tests erfolgreich waren und der Feature- oder Bugfix-Branch in den master gemerged worden sind.

Die Veröffentlichung

Bei der Veröffentlichung sind wir auf einige Dinge hingewiesen worden, die wahrscheinlich viele Plugin-Entwickler betreffen. Folgende Punkte wurden erwähnt:

1. Core-Dateien sollen nicht inkludiert werden.

Das betrifft unter anderem wp-config.php, wp-blog-header.php, wp-load.php, da die Dateisystemstruktur je nach Installation und deren Einstellungen variieren kann.

Falls also neue Einstiegspunkte gebraucht werden, müssen zwingend neue Routen registriert oder bestehende mit GET-Parametern modifiziert werden, anstatt von außen direkt PHP-Dateien aufzurufen.

2. Es gibt viele Sanitizing- und Escaping-Funktionen. 

Zugriffe auf $_POST und anderen Superglobalen mit späterem Escaping/Sanitizing sollten vermieden werden.

Dokumentation:

Optimierung des Plugins

Ende September 2019 haben wir dann unsere verbesserte Version eingereicht. Wir haben den Code als Link zum Github-Repo angegeben und auch, wie man den Code lauffähig macht. Das bedeutet, dass man das Repo rekursiv klont und die Composer-Abhängigkeiten installiert. Wir wurden darüber informiert, dass der Code jedoch sofort lauffähig sein muss und auch das “tests/”-Verzeichnis nicht enthalten darf.

Daraufhin haben wir ein Release-Script erstellt, das den Composer-Schritt, den Eintrag der Versionsnummer und der stabilen Version in der readme.txt für uns übernimmt, damit uns dort Fehler durch händische Arbeit erspart bleiben. Das Script entfernt darüber hinaus das “tests/”-Verzeichnis mit den Unit-Tests vor der Veröffentlichung.

Nachdem wir unsere letzten Nachbesserungen eingereicht haben, wurde 12 Stunden später unser Plugin akzeptiert und ist seitdem im Store verfügbar.

Die Übersetzung

Das Übersetzungssystem von WordPress arbeitet mit dem PHP-Wrapper “gettext” von GNU. Nach der Veröffentlichung werden die Übersetzungen auf der WordPress Translations-Plattform verwaltet. Committer haben nach dem Einreichen in den Plugin-Store zunächst keinen Einfluss auf die Übersetzung. Unsere wurde angepasst, ohne dass wir eingreifen konnten. Wenn man diese wieder Übersetzen möchte, muss man sich per Chat auf der translate.wordpress.org-Plattform melden. Wer Interesse hat, Übersetzer für die deutsche Sprache zu werden, findet alle Infos hier.

Positiv ist, dass Übersetzungen nach klaren Regeln erfolgen und potenzielle Übersetzer zunächst gefragt werden, ob sie die Sprache, für die sie sich bewerben, auch tatsächlich fließend sprechen.

Man kann sich für verschiedene Übersetzerrollen bewerben. PTE ist ein projektspezifischer Übersetzer für eine Sprache, während ein GTE ein globaler Übersetzer für eine Sprache ist, ein CLPTE ist hingehen ein Cross-Locale Project Translation Editor.

Wichtig: Wenn die Übersetzungen auf translate.wordpress.org verwaltet werden, ändert sich gegebenenfalls auch die Translation Domain! Sie ist dann der Plugin Slug.

Hinweise zur Plugin-Veröffentlichung

WordPress ist ein historisch gewachsenes, abwärts-kompatibel gehaltenes System. Dafür ein neues Plugin mit modernen Programmiertechniken (DI/UnitTests) zu erstellen ist gar nicht so einfach. Dennoch ist es möglich und zahlt sich bei der Wartung aus. In der anfangs anstehenden Review kommen immer wieder neue Punkte hinzu, auf die man sich einstellen sollte. Man hat aber so viel Zeit, wie man möchte, um die Punkte zu bearbeiten. Man sollte allerdings nicht länger als sechs Monate mit der Antwort auf eine Mail warten, da der Antrag ansonsten verworfen wird.

Wenn das Plugin akzeptiert wurde, muss sich der Entwickler sofort um eine Position als PTE bemühen, um die Übersetzungen bearbeiten zu können. Achtet aber bitte vorher darauf, die richtige Text-Domain zu wählen.

Es ist eine gute Idee ein Build– und Commit-Script zu erstellen, das das Changelog auf einen Eintrag für die neue Version prüft, Composer-Abhängigkeiten installiert, den aktuellen git-Tag ins Version-Feld der Plugin-Datei einträgt und in der readme.txt die aktuelle Version als stable markiert. Darüber hinaus entfernt es das tests-Verzeichnis, commitet das Plugin mit allen Composer-Abhängigkeiten ins WP-SVN und erstellt einen stable-Tag im SVN. So erspart sich der Entwickler Fehler, die sich beim Verpacken des Releases einschleichen können.