WordPress-Plugins entwickeln
Vom Plugin-Header über Actions und Filter bis zu Gutenberg-Blöcken: wie ein sauberes WordPress-Plugin aufgebaut ist und worauf das Plugin-Verzeichnis achtet.
WordPress ist das Paradebeispiel für eine Plattform, die von Erweiterungen lebt. Das offizielle Plugin-Verzeichnis listet Zehntausende Plugins, und kaum eine Website kommt ohne aus. Die Einstiegshürde ist niedrig: Wer etwas PHP kann, schreibt in wenigen Minuten ein funktionierendes Plugin. Die eigentliche Kunst liegt darin, es so zu bauen, dass es sicher ist, mit anderen Plugins zusammenspielt und auch nach dem nächsten WordPress-Update noch funktioniert.
Das Grundgerüst
Ein Plugin ist ein Ordner unter wp-content/plugins/. Darin liegt eine Hauptdatei, deren Kopfkommentar WordPress ausliest. Pflicht ist nur die Zeile Plugin Name, sinnvoll sind einige weitere Angaben.
<?php
/**
* Plugin Name: Lesezeit anzeigen
* Description: Blendet über jedem Beitrag die geschätzte Lesezeit ein.
* Version: 1.0.0
* Requires at least: 6.0
* Requires PHP: 7.4
* Author: Ihr Name
* License: GPL-2.0-or-later
* Text Domain: lesezeit-anzeigen
*/
defined( 'ABSPATH' ) || exit;
Die letzte Zeile verhindert, dass die Datei direkt über ihre Adresse aufgerufen wird. Für größere Plugins hat sich eine Aufteilung bewährt: Hauptdatei als schlanker Einstieg, Logik in einem Ordner includes/, Skripte und Styles in assets/, Übersetzungen in languages/ und eine uninstall.php, die beim Löschen des Plugins eigene Optionen und Tabellen entfernt.
Hooks: Actions und Filter
WordPress ruft Ihr Plugin nicht direkt auf. Stattdessen bietet es an vielen Stellen sogenannte Hooks an, an die sich Plugins hängen. Es gibt zwei Arten:
- Actions sind Ereignisse. An einer bestimmten Stelle sagt WordPress „jetzt passiert X“, und alle registrierten Funktionen werden ausgeführt. Beispiele sind
init,wp_enqueue_scriptsodersave_post. - Filter reichen einen Wert durch. Jede registrierte Funktion bekommt ihn, darf ihn verändern und muss ihn zurückgeben. Beispiele sind
the_contentoderthe_title.
add_filter( 'the_content', function ( $inhalt ) {
if ( ! is_singular( 'post' ) || ! in_the_loop() ) {
return $inhalt;
}
$woerter = str_word_count( wp_strip_all_tags( $inhalt ) );
$minuten = max( 1, (int) ceil( $woerter / 200 ) );
$hinweis = sprintf(
'<p class="lesezeit">%s</p>',
esc_html( sprintf( 'Lesezeit: etwa %d Minuten', $minuten ) )
);
return $hinweis . $inhalt;
} );
Ein Filter, der vergisst, den Wert zurückzugeben, lässt den Inhalt verschwinden. Das ist einer der häufigsten Anfängerfehler. Über die Priorität als drittes Argument von add_filter und add_action steuern Sie, ob Ihre Funktion vor oder nach anderen läuft. Eigene Hooks mit do_action und apply_filters machen Ihr Plugin wiederum für andere erweiterbar.
Blöcke für den Editor
Seit der Block-Editor (Gutenberg) Standard ist, liefern viele Plugins eigene Blöcke. Ein Block besteht aus einer Beschreibungsdatei block.json, JavaScript für die Darstellung im Editor und entweder gespeichertem HTML oder einer PHP-Funktion, die den Block serverseitig ausgibt. Das offizielle Paket @wordpress/create-block erzeugt ein lauffähiges Gerüst samt Build-Konfiguration:
npx @wordpress/create-block@latest lesezeit-block
Für den Build nutzt das Gerüst @wordpress/scripts, eine vorkonfigurierte Kombination aus Bundler, Babel und Linting. Sie müssen also kein eigenes Build-Setup pflegen.
Sicherheit ist Pflicht
Plugins laufen mit vollen Rechten in der WordPress-Installation. Eine Lücke in Ihrem Code ist eine Lücke in jeder Website, die es nutzt. Vier Regeln decken die meisten Fälle ab:
- Rechte prüfen: Vor jeder Aktion mit
current_user_can()sicherstellen, dass die Person das darf. - Absicht prüfen: Formulare und AJAX-Aufrufe mit einer Nonce absichern (
wp_nonce_field(),check_admin_referer(),check_ajax_referer()). - Eingaben bereinigen: Alles aus
$_POST,$_GETund Co. mit passenden Funktionen wiesanitize_text_field()oderabsint()säubern. - Ausgaben escapen: Erst beim Ausgeben mit
esc_html(),esc_attr()oderesc_url()maskieren. Datenbankabfragen mit Variablen immer über$wpdb->prepare().
Die meisten gemeldeten Schwachstellen in Plugins sind Cross-Site-Scripting durch ungeprüfte Ausgaben und fehlende Rechteprüfungen in AJAX- oder REST-Endpunkten. Wer konsequent „früh bereinigen, spät escapen“ umsetzt, schließt den Großteil davon aus.
Lokale Entwicklungsumgebung
Entwickeln Sie nie direkt auf einer Live-Website. Bewährt sind lokale Umgebungen auf Basis von Docker, etwa das offizielle Werkzeug @wordpress/env, das mit einem Befehl eine WordPress-Instanz mit Ihrem Plugin startet. Aktivieren Sie in der Testumgebung WP_DEBUG, damit Warnungen und veraltete Funktionsaufrufe sofort sichtbar werden.
Ins Plugin-Verzeichnis
Das Verzeichnis auf wordpress.org ist der größte Vertriebsweg. Voraussetzungen sind eine GPL-kompatible Lizenz, eine readme.txt im vorgegebenen Format und das Einhalten der Plugin-Richtlinien. Dazu gehört zum Beispiel, dass ein Plugin ohne Zustimmung der Betreiber keine Werbelinks oder Credits im Frontend der Website einblendet. Nach einer manuellen Prüfung erhalten Sie Zugang zu einem SVN-Repository, über das Sie Versionen ausliefern. Ablauf und Fallstricke behandelt der Bereich Add-ons veröffentlichen und pflegen.
Kompatibel bleiben
WordPress legt großen Wert auf Rückwärtskompatibilität, markiert alte Funktionen aber als veraltet. Testen Sie Ihr Plugin vor jedem größeren WordPress-Release mit der Beta-Version, halten Sie die Angabe Tested up to in der readme.txt aktuell und prefixen Sie alle Funktions-, Klassen- und Optionsnamen, damit sie nicht mit anderen Plugins kollidieren.
Anleitungen zu WordPress-Plugins
- Plugin erstellen
Vom leeren Ordner zum funktionierenden Plugin: Header, Ordnerstruktur, Aktivierungs-Hook, ein Shortcode mit Einstellung und eine saubere uninstall.php.
- Actions und Filter
Actions führen Code aus, Filter verändern Werte: wie add_action und add_filter funktionieren, was Priorität und Argumentzahl bewirken und wie Sie eigene Hooks anbieten.
- Gutenberg-Block
Mit einem Befehl zum lauffähigen Block: was create-block erzeugt, wie block.json, Edit- und Save-Funktion zusammenspielen und wann ein dynamischer Block besser ist.
- Plugin absichern
Rechteprüfung, Nonces, Sanitizing und Escaping: welche WordPress-Funktion wann greift, mit Beispielen für Formulare, AJAX, REST-Endpunkte und Datenbankabfragen.
Fragen und Antworten
- Plugin oder Code in der functions.php des Themes?
- Alles, was mit der Funktion der Website zu tun hat, gehört in ein Plugin, etwa eigene Inhaltstypen, Shortcodes oder Schnittstellen. Die functions.php ist für Darstellungsfragen des Themes gedacht. Wechselt man das Theme, verschwindet ihr Code, ein Plugin bleibt erhalten.
- Welche PHP-Version sollte mein Plugin unterstützen?
- Orientieren Sie sich an den Mindestanforderungen, die WordPress selbst aktuell angibt, und an den Versionen, die Ihre Zielgruppe tatsächlich nutzt. Im Plugin-Header legen Sie mit Requires PHP fest, ab welcher Version Ihr Plugin aktiviert werden darf.
- Muss ein Plugin im offiziellen Verzeichnis kostenlos sein?
- Der Eintrag selbst ist kostenlos und der dort angebotene Code muss vollständig nutzbar sein. Erlaubt ist ein kostenloses Plugin, zu dem es außerhalb des Verzeichnisses eine kostenpflichtige Erweiterung gibt. Nicht erlaubt sind künstlich gesperrte Funktionen im kostenlosen Code, die erst nach Bezahlung freigeschaltet werden.
Weiterlesen
- Veröffentlichen
Stores und Prüfprozesse, Versionsnummern und Changelog, Lizenzen und Bezahlmodelle: was nach dem letzten Commit kommt und warum ein Add-on nie ganz fertig ist.
- Grundlagen
Sprachen, Schnittstellen, Build-Werkzeuge, Versionskontrolle und Tests: das Handwerkszeug, das für Erweiterungen jeder Plattform gebraucht wird.
- Sicherheit
Welche Berechtigungen heikel sind, woran Sie bösartige Erweiterungen erkennen, warum Updates und Übernahmen ein Risiko sind und was im Ernstfall zu tun ist.