Die meiste WordPress-Plugin-Entwicklung verläuft nach demselben Muster. Jemand braucht ein Buchungsformular, einen Feed-Importer oder ein zusätzliches Feld an der Kasse, ein Entwickler schreibt es, es funktioniert, alle machen weiter. Zwei Jahre später hängt die Website auf einer alten WordPress-Version fest, weil niemand sicher ist, dass dieses Plugin ein Update überlebt, und wer es geschrieben hat, ist längst weg.

Die Ursache ist selten, dass Core sich zu schnell bewegt. WordPress geht sehr behutsam damit um, Dinge zu brechen, und viele gut geschriebene Plugins von vor fünf Jahren laufen unverändert auf WordPress 7.1. Plugins gehen wegen Entscheidungen aus der ersten Woche kaputt: Funktionalität im Theme, bearbeitete Core-Dateien statt Hooks, Daten in der Struktur abgelegt, die gerade am nächsten lag, und niemand, der jemals gegen einen Release Candidate testet.

Was lässt ein individuelles WordPress-Plugin Core-Updates überstehen? Vier Dinge. Der Code liegt in einem Plugin und nicht im Theme. Er erweitert WordPress über Actions und Filter, statt Core-Dateien zu bearbeiten. Er legt jede Art von Daten in der Struktur ab, die zu ihrer Form passt. Und jemand testet ihn gegen jeden Release Candidate, bevor diese Version ausgeliefert wird.


Warum WordPress-Plugin-Entwicklung in ein Plugin gehört und nicht ins Theme

Die Standardheimat für individuellen Code ist die functions.php des Themes, weil sie schon da ist und ohnehin ausgeführt wird. Es ist auch die Datei, die beim nächsten Redesign verschwindet.

Ein Theme ist Präsentation. Wechseln Sie das Theme, und alles, was das alte Theme getan hat, hört auf. Custom Post Types werden nicht mehr registriert, also liegen die Inhalte ohne Verwaltungsansicht und ohne Permalink in der Datenbank. Shortcodes erscheinen mitten auf der Seite als reiner Text. Das Analytics-Snippet, das Schema-Markup und der nächtliche Aufruf an das CRM sind weg, und nichts meldet einen Fehler.

Die Regel ist einfach genug für ein Briefing. Alles, was nach einem Redesign noch gelten muss, gehört in ein Plugin: Custom Post Types und Taxonomien, Integrationen mit allem Externen, Shortcodes und Blöcke, Geschäftsregeln, geplante Aufgaben und alles, was in die Datenbank schreibt. Das Theme behält Templates, Styles und Template-Teile.

Der Preis kommt spät. Beim nächsten Redesign zahlen Sie entweder erneut dafür, das Vorhandene neu zu bauen, oder Sie schleppen die alte functions.php mit. Auf einer Website mit jahrelang gewachsenen Snippets sind das mehrere tausend Pfund vermeidbarer Arbeit, und genau deshalb kommt ein Redesign-Angebot doppelt so hoch zurück, wie der Kunde erwartet hat. Ein Child-Theme ist immer noch ein Theme.

Das Erweiterungsmodell und die eine Regel, auf die es ankommt

WordPress ist darauf gebaut, von außen verändert zu werden. Der Mechanismus sind Hooks, und die Dokumentation zu Hooks beschreibt sie als die vordefinierten Stellen, an denen ein Stück Code mit einem anderen interagieren oder es verändern kann. Eine Action feuert zu einem definierten Zeitpunkt und lässt Sie etwas tun: eine Benachrichtigung senden, nachdem ein Beitrag veröffentlicht wurde, oder einen Post Type registrieren. Ein Filter reicht Ihnen einen Wert, erwartet, dass Sie ihn ändern oder in Ruhe lassen, und erwartet ihn zurück.

Die Regel, die daraus folgt, ist absolut. Wenn Sie eine Datei in wp-admin, wp-includes oder im Verzeichnis eines anderen Plugins bearbeiten, haben Sie bereits verloren. Diese Änderungen werden vom nächsten Update gelöscht, ohne Warnung, ohne Fehler und meist ohne Entdeckung, bis ein Kunde meldet, dass etwas nicht mehr funktioniert. Fragen Sie einen Entwickler das direkt, bevor Sie ihn beauftragen.

Wenn der Hook, den Sie brauchen, nicht existiert, umhüllen Sie das Verhalten, statt es zu ersetzen, weichen Sie auf einen breiteren Hook aus, forken Sie das fremde Plugin unter Versionskontrolle mit dokumentierter Abweichung, oder bitten Sie upstream um den Hook, denn so sind die meisten entstanden.

Namen, Präfixe und ein sehr voller Namensraum

PHP läuft in WordPress in einem einzigen globalen Namensraum, den sich Core, das aktive Theme und jedes andere aktive Plugin teilen. Zwei Plugins, die beide eine Funktion get_settings() deklarieren, einigen sich nicht höflich: Das zweite ist ein fataler Fehler, und die Website ist weiß.

Präfixe sind länger, als Sie denken

Die Seite zu Best Practices für Plugins im Handbuch verlangt ein eindeutiges Präfix für alles global Zugängliche, mindestens vier Zeichen und besser fünf, ohne gebräuchliche englische Wörter und niemals wp_, _ oder WordPress selbst. Bei Zehntausenden Plugins im Umlauf sind drei Buchstaben aus den Initialen des Kunden ein Münzwurf.

Namensräume und Autoloading

Moderne Praxis löst die Hälfte des Problems. Deklarieren Sie einen PHP-Namensraum, legen Sie eine Klasse in eine Datei und lassen Sie einen PSR-4-Autoloader sie finden, dann gibt es keine manuellen require-Anweisungen und keine Chance, dass ein Klassenname mit dem eines anderen Plugins kollidiert. Es macht den Code außerdem testbar, weil Klassen mit Konstruktorabhängigkeiten instanziiert werden können, ohne dass WordPress geladen ist.

Autoloading behebt nicht, dass zwei Plugins unterschiedliche Versionen derselben Bibliothek ausliefern. Wer zuerst lädt, gewinnt. Präfixieren Sie Vendor-Namensräume zur Build-Zeit für alles, was verteilt wird.

Die Zeichenketten, bei denen Namensräume nicht helfen

Ein Namensraum deckt PHP-Symbole ab. Vieles, was ein Plugin registriert, ist aber kein PHP-Symbol, sondern eine Zeichenkette in einer geteilten Registry, und dort gilt weiterhin die alte Präfixkonvention: Hook-Namen, Options- und Transient-Schlüssel, Post-Meta-Schlüssel, Namen von Post Types und Taxonomien, Shortcode-Tags, Namen von Cron-Ereignissen, REST-Namensräume und eigene Tabellennamen. Sie leben in einem flachen Raum, in dem die letzte Registrierung gewinnt oder zwei Plugins sich stillschweigend einen Zustand teilen.

Zwei Grenzen sollten Sie kennen, bevor Sie irgendetwas benennen. Ein Schlüssel für einen Post Type darf 20 Zeichen nicht überschreiten und ein Taxonomie-Schlüssel nicht 32, beide kleingeschrieben alphanumerisch mit Bindestrichen und Unterstrichen. Ein Präfix aus fünf Zeichen lässt 15 Zeichen für den Namen eines Post Types, und das ist weniger Platz, als es klingt.

Die Wahl, wo die Daten liegen

Das ist die Entscheidung mit dem längsten Nachhall. Trifft man sie falsch, funktioniert das Plugin zum Start einwandfrei, wird mit wachsender Datenmenge jeden Monat langsamer, und bis es jemandem auffällt, ist die Korrektur eine Migration und keine Änderung.

Optionen und Transients

Optionen sind für seitenweite Einstellungen gedacht: eine Handvoll Schlüssel, kleine Werte, bei den meisten Anfragen gelesen. Die Falle ist das Autoloading, denn jede autogeladene Option wird bei jeder einzelnen Anfrage geholt, auch bei admin-ajax- und REST-Aufrufen, ob sie jemand benutzt oder nicht.

WordPress 6.6 hat die Mechanik geändert, wie im Beitrag im Make-WordPress-Core-Blog zum Abschalten von Autoload für große Optionen beschrieben. Der gespeicherte Wert ist jetzt on, off oder auto, und eine Option, die größer als 150.000 Bytes ist, wird standardmäßig nicht autogeladen, wobei der Schwellenwert über den Filter wp_max_autoloaded_option_size anpassbar ist. Behandeln Sie das als Obergrenze, nicht als Ziel. Transients sind Optionen mit Ablauf und die richtige Heimat für alles, was von anderswo geholt wird.

Post-Meta ist kein Key-Value-Store

Post-Meta ist für Attribute eines einzelnen Beitrags: ein Untertitel, ein Preis, eine Lieferantenreferenz. Es ist kein Allzweck-Key-Value-Store, und der Grund steht in der Tabellendefinition. Die Tabelle wp_postmeta hat vier Spalten und drei Schlüssel. Indiziert sind nur post_id und die ersten 191 Zeichen von meta_key. Die Spalte meta_value ist ein longtext ganz ohne Index.

Eine Abfrage, die auf einen Meta-Wert filtert, kann deshalb keinen Index nutzen. Jede Klausel in einer Meta-Abfrage fügt einen weiteren Join hinzu, und auf einer Website mit 50.000 Beiträgen mit je 20 Meta-Zeilen enthält die Tabelle eine Million Zeilen. Drei Klauseln bedeuten drei Joins gegen eine Million Zeilen bei jedem Seitenaufruf. Es ist einer der häufigsten Gründe, warum eine Website, die im ersten Jahr schnell war, im dritten unbenutzbar ist, und es taucht ständig in der Arbeit an der WooCommerce-Performance auf.

Custom Post Types und Taxonomien

Ein Custom Post Type ist richtig, wenn die Sache Inhalt ist. Sie braucht eine eigene Listenansicht, Permalinks, Revisionen und einen redaktionellen Ablauf, und sie ergibt als Seite Sinn, die jemand besuchen könnte. Eine eigene Taxonomie ist richtig, wenn Sie ein gemeinsames Vokabular brauchen, das diese Dinge gruppiert und eigene Archivseiten verdient.

Beide bringen kostenlose Mechanik mit: Verwaltungsansichten, Berechtigungen, Suche, den Block-Editor und die REST-API. Setzen Sie show_in_rest auf true, sonst behandelt der Block-Editor den Typ nicht, und registrieren Sie beide am Hook init, niemals davor.

Wann Sie wirklich eine eigene Tabelle brauchen

Eine eigene Tabelle ist richtig, wenn die Daten kein Inhalt sind: Datensätze mit hohem Volumen, die nur angehängt werden, etwa Ereignisprotokolle, Importwarteschlangen, Preisverläufe oder Prüfpfade, oder alles, was Sie nach einem Feld filtern und sortieren, das keine Beitragsspalte ist. Jenseits einiger hunderttausend Zeilen, die über ihre eigenen Felder abgefragt werden, schlägt eine Tabelle mit den richtigen Indizes Post-Meta um Größenordnungen und bleibt beim Wachsen berechenbar.

Der Preis ist, dass Ihnen alles gehört: Tabellenerstellung und versionierte Migrationen, Aufräumen in uninstall.php, eigene Verwaltungsansichten, REST-Endpunkte und Caching. Deshalb lautet die ehrliche Antwort für die meisten Plugins immer noch: ein Custom Post Type.

Sicherheit sind vier Gewohnheiten, und drei davon werden übersprungen

Das Sicherheitshandbuch von WordPress formuliert das Prinzip unmissverständlich: Vertrauen Sie weder Benutzereingaben noch fremden APIs noch Daten, die bereits in Ihrer Datenbank liegen. Vier Gewohnheiten tragen fast das gesamte Risiko, und in den Plugins, die wir prüfen, werden sie in einer immer gleichen Reihenfolge übersprungen. Berechtigungsprüfungen zuerst, Nonces als Zweites, Ausgabemaskierung als Drittes. Prepared Statements kommen zuletzt, weil ein fehlendes im Review auffällt.

Berechtigungsprüfungen

Jeder Handler, der etwas verändert, muss fragen, ob dieser Benutzer das darf, und das heißt current_user_can() mit der konkreten Berechtigung, geprüft im Handler selbst und nicht nur um den Button herum, der ihn aufruft.

is_admin() ist keine Berechtigungsprüfung. Die Funktion meldet, auf welcher Seite der Website die Anfrage stattfindet, und liefert true für jeden angemeldeten Abonnenten, der einen admin-ajax-Endpunkt aufruft. Eine admin_post_- oder wp_ajax_-Action ohne Berechtigungsprüfung ist für jeden registrierten Benutzer erreichbar, was in einem Shop jeden Kunden bedeutet, der jemals bestellt hat. Unsere Checkliste zur WordPress-Sicherheitshärtung behandelt die Kontrollen auf Seitenebene rund um dieses Thema.

Nonces

Ein Nonce schützt ein Formular oder eine URL gegen eine Anfrage, die der Benutzer nicht auslösen wollte. Verwenden Sie wp_nonce_field() im Formular und check_admin_referer() im Handler, oder check_ajax_referer() für AJAX. Trotz des Namens sind sie nicht einmalig: Es sind Hashes, die für ein Zeitfenster gültig sind, standardmäßig einen Tag lang, unter einem Zwei-Tick-Schema, das die tatsächliche Lebensdauer zwischen zwölf und vierundzwanzig Stunden legt.

Die Dokumentation zu Nonces ist ausdrücklich: Man darf sich für Authentifizierung, Autorisierung oder Zugriffskontrolle niemals auf sie verlassen. Ein Nonce belegt, dass die Anfrage aus Ihrem Formular kam. Er sagt nichts darüber, ob diese Person die Sache tun dürfen sollte.

Auf dem Weg hinein bereinigen, auf dem Weg hinaus maskieren

Validieren Sie, wo Sie können, denn Validierung ist konkret: Eine Postleitzahl passt entweder zum Muster oder nicht. Bereinigen Sie, wo Sie nicht validieren können, je nach Feld mit sanitize_text_field(), sanitize_email(), sanitize_key(), absint() oder wp_kses_post().

Maskieren Sie dann an der Stelle der Ausgabe, jedes Mal, mit esc_html(), esc_attr(), esc_url() oder wp_kses_post(). Die Dokumentation zum Escaping verlangt das so spät wie möglich, damit ein Prüfer Maskierung und Ausgabe in derselben Zeile sieht. Escaping wird häufiger übersprungen als alles andere, weil nichts falsch aussieht, wenn man es überspringt. Die Seite rendert perfekt, bis jemand ein Script-Tag in ein Feld schreibt.

Prepared Statements

Jede Abfrage, die Sie selbst schreiben, geht durch $wpdb->prepare(), das %d für Ganzzahlen, %f für Fließkommazahlen, %s für Zeichenketten und %i für Bezeichner wie Tabellen- und Spaltennamen nimmt. Platzhalter bleiben unquotiert, ein wörtliches Prozentzeichen wird doppelt geschrieben, und ein LIKE-Platzhalter wird im Ersetzungsargument übergeben statt in die Abfrage getippt. Eine Variable in SQL zu konkatenieren ist keine Stilfrage, es ist die Schwachstelle.

Die REST-API und der Block-Editor

Ein Plugin, das in diesem Jahr geschrieben wird, sollte seine Daten über die REST-API bereitstellen und seine Einstellungen über den Editor, nicht über eine handgebaute Optionsseite.

Routen werden mit register_rest_route() am Hook rest_api_init registriert. Seit WordPress 5.5 ist ein Argument permission_callback Pflicht, und wer es weglässt, löst eine _doing_it_wrong()-Meldung aus, die die Route benennt. Ein wirklich öffentlicher Endpunkt nutzt __return_true, und genau das ist der Sinn des Entwurfs: Eine Route öffentlich zu machen wird zu einer bewussten Codezeile statt zu einem Versäumnis. Die Dokumentation zu eigenen Endpunkten behandelt auch das Argumentschema, in das die Callbacks für Bereinigung und Validierung gehören, damit schlechte Eingaben Ihren Handler nie erreichen.

Einstellungen werden mit register_setting() und show_in_rest auf true registriert. Das legt sie auf den Einstellungs-Endpunkt von Core, sodass der Block-Editor oder ein externes Skript sie über eine Schnittstelle lesen und schreiben kann, die Authentifizierung, Berechtigungen und Validierung bereits erledigt. Es entfernt eine Optionsseite, ihren Nonce, ihren Formular-Handler und die Fehler, die darin wohnen.

Blöcke werden aus einer Datei block.json registriert, seit WordPress 5.8 die empfohlene kanonische Methode. Die Dokumentation zu Block-Metadaten nennt den Vorteil: Dort deklarierte Assets laden nur auf Seiten, auf denen der Block vorkommt, statt seitenweit, nur weil ein Plugin aktiv ist.

Performance-Disziplin innerhalb eines Plugins

Vier Dinge machen den größten Teil der von Plugins verursachten Langsamkeit aus, die wir in Audits finden, und alle vier sind billig zu vermeiden und teuer nachzurüsten. Das erste sind autogeladene Optionen, weil sie bei jeder Anfrage für immer etwas kosten.

Das zweite sind ungecachte entfernte Anfragen während eines Seitenaufbaus. Ein wp_remote_get() an die API eines Lieferanten ohne Caching bedeutet, dass jeder Besucher auf diesen Lieferanten wartet. Ist der Lieferant langsam, ist Ihre Website langsam, und ist er offline, hängt Ihre Website, bis das Timeout abläuft. Cachen Sie die Antwort in einem Transient, setzen Sie ein explizites Timeout, und entscheiden Sie vorab, was die Seite anzeigt, wenn der Aufruf fehlschlägt.

Das dritte sind Abfragen innerhalb einer Schleife. get_post_meta() für jede von 200 Zeilen aufzurufen sind 200 Roundtrips, sofern der Meta-Cache nicht vorgewärmt wurde, und WP_Query wärmt ihn für Sie vor, wenn Sie es zulassen. Die Korrektur besteht meist darin, etwas nicht mehr abzuschalten, was auf die meisten Befunde in einem Core-Web-Vitals-Audit zutrifft.

Das vierte ist Arbeit, die in der Anfrage eines Besuchers erledigt wird. WP-Cron ist kein System-Cron: Es wird beim Seitenaufruf ausgelöst, also läuft eine geplante Aufgabe innerhalb der Anfrage eines Besuchers, und auf einer ruhigen Website läuft der Job von zwei Uhr erst, wenn um fünf jemand vorbeikommt. Definieren Sie DISABLE_WP_CRON, treiben Sie wp-cron.php aus einem echten Systemplaner an, und halten Sie Jobs kurz und idempotent.

Core-Updates überstehen: der Teil, den niemand einplant

Core löscht selten etwas ersatzlos. Funktionen werden als veraltet markiert, funktionieren weiter und geben eine Meldung aus, und deshalb ist ein Staging-System mit aktiviertem WP_DEBUG das billigste Frühwarnsystem, das es gibt. Eine Veraltungsmeldung ist eine datierte Einladung, etwas zu reparieren, solange es noch günstig ist.

Der Prozess, der Überraschungen verhindert, kostet etwa eine Stunde pro Quartal. Verfolgen Sie den Core-Entwicklungsblog, damit Sie wissen, wann eine Beta und dann ein Release Candidate existiert. Lesen Sie den Field Guide, der während der Release-Candidate-Phase erscheint und die entwicklerrelevanten Neuerungen und brechenden Änderungen dieser Version auflistet. Spielen Sie dann den Release Candidate auf eine Staging-Kopie und führen Sie einen schriftlichen Smoke-Test der echten Funktionen des Plugins aus.

Die Versionsunterstützung zählt ebenso viel wie der Code. WordPress verlangt PHP 7.4 als absolute Untergrenze und empfiehlt 8.3 oder neuer, dazu MariaDB 10.11 oder MySQL 8.0. Deklarieren Sie Requires PHP und Requires at least im Plugin-Header ehrlich und testen Sie dann auf der niedrigsten Version, die Sie angegeben haben, statt auf dem, was auf dem Laptop des Entwicklers läuft.

Versionieren Sie Ihr eigenes Plugin semantisch und meinen Sie es ernst. Ein Patch repariert etwas, eine Minor-Version ergänzt Verhalten, ohne etwas zu brechen, und eine Major-Version darf brechen, sofern sie sagt, was sie gebrochen hat. Kunden mit automatischen Updates verlassen sich auf dieses Versprechen.

Verbreitung, Lizenzierung und wie Updates zur Website kommen

WordPress erscheint unter der GPL Version 2 oder später, und die Lizenzseite von wordpress.org legt die Position des Projekts dar, dass Plugins und Themes abgeleitete Werke sind, die die Lizenz erben, räumt dabei aber eine juristische Grauzone darüber ein, was als abgeleitet gilt.

Sie bekommen den Quellcode, immer, und Sie können jeden anderen mit Änderungen beauftragen. Was die GPL nicht tut, ist Sie zur Veröffentlichung zu zwingen, ein für ein Unternehmen gebautes Plugin darf also privat bleiben. Sie hindert den Entwickler auch nicht daran, dieselbe Arbeit an jemand anderen zu verkaufen. Wenn Exklusivität zählt, ist das eine Vertragsklausel und keine Lizenzfrage.

Geht das Plugin in das öffentliche Verzeichnis, muss es die Richtlinien des Plugin-Verzeichnisses erfüllen, achtzehn an der Zahl. Die erste verlangt GPL-kompatible Lizenzierung für alles im Paket, Bilder eingeschlossen. Andere schließen Trialware aus, also hinter Zahlung oder Upgrade verschlossene Funktionalität, verbieten verschleierten Code, untersagen das Tracking von Nutzern ohne Einwilligung und verbieten Links oder Credits, die ohne Erlaubnis auf der öffentlichen Website ergänzt werden.

Bleibt es privat, werden Updates Ihr Problem. Setzen Sie den Header Update URI, den es gibt, damit ein privates Plugin nicht von einem ähnlich benannten aus dem Verzeichnis überschrieben wird, und liefern Sie Updates von Ihrem eigenen Endpunkt aus. Das ans Ende zu schieben ist der Weg, auf dem ein Kunde am Ende per FTP aktualisiert.

Was ein individuelles WordPress-Plugin kostet

Die folgenden Bänder sind Preise britischer Agenturen in Pfund, für Arbeit nach dem hier beschriebenen Standard: mit Tests, Dokumentation und einer namentlich benannten Person, die nach dem Start zuständig ist. Ein fähiger WordPress- und PHP-Entwickler berechnet grob 400 bis 600 Pfund pro Tag, das sind also Aussagen über den Umfang und nicht über den Satz.

Ein kleines Hilfsplugin liegt bei 1.500 bis 3.000 Pfund. Eine Aufgabe, ein paar Hooks, vielleicht ein Einstellungsschalter: Weiterleitungen, ein zusätzliches Feld an einer Bestellung, ein nächtlicher Export an einen Lieferanten.

Eine mittelgroße Integration liegt bei 3.000 bis 15.000 Pfund. Eine fremde API mit Authentifizierung, Wiederholungen und Fehlerbehandlung, ein Custom Post Type, Verwaltungsansichten und Hintergrundverarbeitung. Das ist die am häufigsten beauftragte Größe und die am häufigsten unterschätzte, denn die Integration ist eine Woche und die Fehlerbehandlung sind zwei Wochen.

Ein umfangreiches Produkt-Plugin liegt bei 20.000 bis 75.000 Pfund und darüber. Eigene Tabellen, Oberflächen im Block-Editor, Lizenzierung und Update-Infrastruktur, Multisite-Unterstützung und eine Supportlast, die am Tag der Auslieferung beginnt.

Am unteren Ende zu zahlen ist nicht automatisch falsch. Falsch ist es, wenn der Preis aus einem Umfang stammt, der die untenstehenden Ergebnisse stillschweigend ausgeschlossen hat. Unser Leitfaden zu Sätzen von WordPress-Entwicklern und den richtigen Fragen erklärt, wie man ein Angebot liest, und unsere Seite zur WordPress-Entwicklung beschreibt, wie wir diese Arbeit zuschneiden.

Was im Liefergegenstand enthalten sein sollte

Verlangen Sie all das schriftlich, bevor die Arbeit beginnt, denn jeder einzelne Punkt ist günstig mitzuliefern und teuer nachzurüsten. Den Quellcode, in einem Repository, das Ihnen gehört, mit intakter Historie, statt einer ZIP-Datei, die am letzten Tag gemailt wird. Unit-Tests für die Geschäftsregeln und einen Integrationstest für alles, was in die Datenbank schreibt oder einen externen Dienst aufruft, denn genau das macht es in zwei Jahren für jemanden sicher änderbar, der damals nicht dabei war.

Eine Readme, die sagt, was das Plugin tut, wo es sich einhängt, was es wo speichert, welche externen Dienste es aufruft und was passiert, wenn jeder davon ausfällt. Zwei Seiten reichen, und ihr Fehlen ist der Grund, warum Plugins ersetzt statt gepflegt werden. Eine uninstall.php, die Optionen, Tabellen, Cron-Ereignisse und Meta entfernt. Und eine benannte Supportvereinbarung, die das Testen gegen jede Core-Version und das Beheben der Funde abdeckt.

Wie es gebaut wird

Mecanik baut Plugins in allen drei genannten Größen und übernimmt Plugins, die jemand anderes geschrieben hat, oft das nützlichere Mandat. Unsere Seiten zu WordPress-Entwickler und Softwareentwicklung erklären, wie wir zuschneiden und liefern. Wenn Sie bereits ein Plugin haben, das niemand anfassen will, dauert ein Audit gegen die obigen Praktiken etwa einen Tag und sagt Ihnen, ob es reparierbar oder ersetzbar ist.



Häufig gestellte Fragen

Gehört individuelle Funktionalität in ein Plugin oder ins Theme? In ein Plugin, sofern sie nicht rein gestalterisch ist. Ein Theme wird beim nächsten Redesign ausgetauscht, und alles, was es getan hat, hört auf: Custom Post Types verlieren ihre Verwaltungsansichten, Shortcodes erscheinen als reiner Text, und Integrationen laufen stillschweigend nicht mehr. Alles, was nach einem Redesign noch gelten muss, gehört in ein Plugin.

Was kostet ein individuelles WordPress-Plugin im Vereinigten Königreich? Ein kleines Hilfsplugin kostet typischerweise 1.500 bis 3.000 Pfund, eine mittelgroße Integration mit fremder API und Verwaltungsansichten 3.000 bis 15.000 Pfund, und ein umfangreiches Produkt-Plugin mit eigenen Tabellen und Update-Infrastruktur 20.000 bis 75.000 Pfund oder mehr. Entwickler, die diese Arbeit können, berechnen grob 400 bis 600 Pfund pro Tag.

Ist es jemals vertretbar, WordPress-Core oder die Dateien eines anderen Plugins zu bearbeiten? Nein. Diese Änderungen werden vom nächsten Update gelöscht, ohne Fehler und meist ohne Entdeckung, bis etwas nicht mehr funktioniert. Verwenden Sie stattdessen Actions und Filter. Wenn der Hook, den Sie brauchen, nicht existiert, umhüllen Sie das Verhalten, forken Sie das Plugin unter Versionskontrolle, oder bitten Sie upstream um den Hook.

Gehört mir ein Plugin, dessen Entwicklung ich bezahlt habe? Ihnen gehört Ihre Kopie und das, was der Vertrag sagt. Die GPL gibt Ihnen den Quellcode, das Recht, ihn zu ändern, und das Recht, jeden anderen mit der Pflege zu beauftragen, und sie verlangt keine Veröffentlichung, ein für ein Unternehmen gebautes Plugin darf also privat bleiben. Sie hindert den Entwickler nicht daran, dieselbe Arbeit weiterzuverkaufen, halten Sie Exklusivität also im Vertrag fest, wenn sie zählt.

Wie verhindert man, dass ein Plugin bei einem WordPress-Update kaputtgeht? Testen Sie es gegen jeden Release Candidate auf einer Staging-Kopie, bevor diese Version ausgeliefert wird, betreiben Sie Staging mit aktiviertem WP_DEBUG, damit Veraltungsmeldungen früh auffallen, und deklarieren Sie die unterstützten PHP- und WordPress-Versionen im Header des Plugins. WordPress verlangt PHP 7.4 als Untergrenze und empfiehlt 8.3 oder neuer.