{"id":20879,"date":"2026-10-27T15:09:00","date_gmt":"2026-10-27T14:09:00","guid":{"rendered":"https:\/\/www.lukaswojcik.com\/blog\/?p=20879"},"modified":"2026-10-25T22:34:29","modified_gmt":"2026-10-25T21:34:29","slug":"wordpress-playground-blueprints-fur-plugin-vorschau-und-tests","status":"publish","type":"post","link":"https:\/\/www.lukaswojcik.com\/blog\/de\/wordpress-plugins-tricks-de\/tutorials-de-wordpress-plugins-tricks-de\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\/","title":{"rendered":"WordPress Playground: Blueprints f\u00fcr Plugin-Vorschau und Tests"},"content":{"rendered":"<p>Die Schaltfl\u00e4che \u201ePreview\u201c auf einer WordPress.org-Pluginseite \u00f6ffnet eine vor\u00fcbergehende Testwebsite im Browser. PHP und Datenbank laufen dort mithilfe von WebAssembly. Eine Datei namens Blueprint beschreibt die Einrichtung: etwa die PHP-Version, ben\u00f6tigte Plugins und Demowerte. Dieselbe Datei l\u00e4sst sich f\u00fcr die Verzeichnis-Vorschau, lokale Playground-L\u00e4ufe und den Playground-Teil automatischer Tests verwenden.<\/p>\n<p>Das Beispiel erg\u00e4nzt Contact Form 7 um ein kleines Demonstrationsplugin. Eine zweite Teststrecke l\u00e4uft mit Docker und <code>wp-env<\/code>. Diese Strecke verwendet eine eigene <code>.wp-env.json<\/code> und f\u00fchrt den Blueprint nicht aus. Der Unterschied ist sichtbar: Der Blueprint setzt eine Option auf 14, die reine Aktivierung ohne Blueprint auf 30. Der Beitrag zeigt diese zwei Wege und benennt genau, was die Tests pr\u00fcfen. Die urspr\u00fcnglichen Laufzeitbelege stammen vom 29.09.2026; Schema, Quellen und isolierte Pr\u00fcfungen wurden am 25.10.2026 erneut abgeglichen.<\/p>\n<h2>Playground, Blueprints und die wichtigen Schritte<\/h2>\n<p>Im Browser ben\u00f6tigt Playground keinen eigenen PHP-Webserver. PHP l\u00e4uft als WebAssembly, die Datenbank verwendet SQLite. Die Kommandozeilenfassung nutzt diese Laufzeit unter Node.js. Der hier verwendete Blueprint im Format V1 ist eine JSON-Datei: <code>landingPage<\/code> bestimmt die erste ge\u00f6ffnete Seite, <code>preferredVersions<\/code> enth\u00e4lt <code>php<\/code> und <code>wp<\/code>, und <code>steps<\/code> nennt die Einrichtungsschritte in Reihenfolge. <code>features.networking<\/code> wird im Beispiel ausdr\u00fccklich aktiviert. <code>$schema<\/code> verweist auf die Regeln, gegen die ein Editor die Datei pr\u00fcfen kann.<\/p>\n<p>Die unterst\u00fctzten Versionen h\u00e4ngen vom jeweiligen Playground-Stand ab. Das aktuelle Schema akzeptiert unter anderem PHP 7.4 und 8.0 bis 8.5 sowie <code>latest<\/code> und <code>next<\/code>; zus\u00e4tzlich existieren besondere Legacy-Eintr\u00e4ge. F\u00fcr den Beispielablauf sind konkrete Kombinationen wichtiger als eine dauerhafte Vollst\u00e4ndigkeitsliste. Die Testmatrix nennt deshalb WordPress 6.7.9, 7.0.6 und 7.1.2. Das sind festgelegte Pr\u00fcfst\u00e4nde, keine Aussage \u00fcber die heute neueste Version.<\/p>\n<p>F\u00fcr die Einrichtung des Beispiels werden drei Schritte ben\u00f6tigt:<\/p>\n<ul>\n<li><code>installPlugin<\/code> erwartet eine Ressource in <code>pluginData<\/code>, etwa <code>{\"resource\": \"wordpress.org\/plugins\", \"slug\": \"contact-form-7\"}<\/code>, eine <code>url<\/code> auf eine ZIP-Datei oder einen Verweis vom Typ <code>git:directory<\/code>. Die Aktivierung steuert <code>options.activate<\/code>; der Schl\u00fcssel geh\u00f6rt in <code>options<\/code>, nicht in <code>pluginData<\/code>. Ohne diese Angabe gilt im Quellcode true.<\/li>\n<li><code>login<\/code> braucht nur <code>username<\/code>, Standard ist <code>admin<\/code>. Das Feld <code>password<\/code> ist im Schema als veraltet markiert.<\/li>\n<li><code>setSiteOptions<\/code> speichert die Werte aus <code>options<\/code> als WordPress-Optionen. Das Beispiel setzt damit den Website-Titel und den Demowert 14.<\/li>\n<\/ul>\n<p>Weitere Schritte k\u00f6nnen PHP-Code ausf\u00fchren, Sprachpakete installieren oder Einstellungen in <code>wp-config.php<\/code> setzen. Alte Beispiele enthalten noch <code>pluginZipFile<\/code> und <code>phpExtensionBundles<\/code>; das aktuelle Schema markiert diese Angaben als veraltet beziehungsweise nicht mehr verwendet. Bei Abh\u00e4ngigkeiten steht die Reihenfolge ausdr\u00fccklich in <code>steps<\/code>. Ein \u00f6ffentlich erreichbarer Blueprint l\u00e4sst sich \u00fcber <code>?blueprint-url=<\/code> \u00f6ffnen; auch ein JSON-Fragment nach <code>https:\/\/playground.wordpress.net\/#<\/code> ist m\u00f6glich. Das Diagramm trennt den gemeinsamen Playground-Blueprint von der eigenen Docker-Konfiguration.<\/p>\n<figure class=\"lw-diagram\">\n<img loading=\"lazy\" decoding=\"async\" alt=\"Der Blueprint versorgt Vorschau, lokale Playground-L\u00e4ufe und Playground-CI. Docker verwendet separat .wp-env.json und im Beispiel den Standardwert 30 statt des Demo-Werts 14.\" height=\"580\" src=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/diagrams\/playground-reviewed-20879-de-20261025.png\" width=\"1120\"\/>\n<figcaption>Der Blueprint versorgt Vorschau, lokale Playground-L\u00e4ufe und Playground-CI. Docker verwendet separat .wp-env.json und im Beispiel den Standardwert 30 statt des Demo-Werts 14.<\/figcaption>\n<\/figure>\n<h2>Der Blueprint f\u00fcr die Vorschau im Verzeichnis<\/h2>\n<p>F\u00fcr eine \u00f6ffentliche Vorschau braucht das Plugin eine g\u00fcltige Datei unter <code>assets\/blueprints\/blueprint.json<\/code> im SVN-Verzeichnis. Zus\u00e4tzlich muss ein Committer, also ein Konto mit Schreibrecht f\u00fcr dieses Plugin, die Vorschau unter \u201eAdvanced\u201c auf \u201epublic\u201c stellen. Davor ist \u201eTest Preview\u201c nur f\u00fcr diese Konten sichtbar. Ein automatisch erzeugter Test-Blueprint kann als Ausgangspunkt dienen.<\/p>\n<p>Der gepr\u00fcfte Importcode \u00fcbernimmt passende Blueprint-Dateien aus diesem Ordner bis zu 102.400 Byte je Datei und beh\u00e4lt h\u00f6chstens zehn. F\u00fcr die normale Vorschau wird <code>blueprint.json<\/code> verwendet. Ung\u00fcltiges JSON wird verworfen. Beim Beispielplugin erg\u00e4nzt der Import die Installation des eigenen Slugs am Ende, falls kein passender Schritt vorhanden ist, und erzwingt die Aktivierung. Passende ZIP-Adressen von <code>downloads.wordpress.org<\/code> werden in Slug-Ressourcen umgeschrieben. Eine im Dateinamen enthaltene Versionsbindung kann dabei verloren gehen. Der Import ist somit keine unver\u00e4nderte Weitergabe der Datei.<\/p>\n<p>Der Blueprint installiert deshalb Contact Form 7 und setzt Demowerte, enth\u00e4lt aber keinen Download des eigenen Add-ons. Das Verzeichnis erg\u00e4nzt diesen Download. Die lokale Playground-CLI bindet stattdessen den Arbeitsordner ein und aktiviert das Add-on nach den Blueprint-Schritten. Ein eigener Downloadschritt k\u00f6nnte bei einem unver\u00f6ffentlichten Plugin scheitern oder mit der Standardoption <code>overwrite<\/code> den eingebundenen Arbeitsordner ersetzen. Der Docker-Weg verwendet unabh\u00e4ngig davon seine Pluginliste.<\/p>\n<p>Im Git-Projekt liegt die Datei hier unter <code>.wordpress-org\/blueprints\/blueprint.json<\/code>. Dieser Ordnername ist eine Konvention des Beispiels. Erst der Releaseablauf kopiert die Datei nach <code>assets\/blueprints\/<\/code> in SVN. Ein Punkt am Ordneranfang schlie\u00dft Dateien nicht automatisch aus einer Plugin-ZIP aus; das Packskript muss den Ausschluss tats\u00e4chlich vornehmen.<\/p>\n<figure style=\"--cbb-digits:2\" class=\"cbb cbb--wrap cbb--numbers wp-block-code-beautifier-block-code\" data-lang=\"json\"><figcaption class=\"cbb-head\"><span class=\"cbb-lang\">JSON<\/span><span class=\"cbb-actions\"><button type=\"button\" class=\"cbb-button cbb-button--wrap\" data-cbb-action=\"wrap\" aria-pressed=\"true\" title=\"Wrap long lines\"><svg aria-hidden=\"true\" focusable=\"false\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><path d=\"M2 4h12M2 8h9.5a2.5 2.5 0 0 1 0 5H8m0 0 1.5-1.5M8 13l1.5 1.5M2 12h3\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/><\/svg><span class=\"cbb-sr\">Wrap long lines<\/span><\/button><button type=\"button\" class=\"cbb-button cbb-button--copy\" data-cbb-action=\"copy\" data-cbb-done=\"Copied\" data-cbb-failed=\"Press Ctrl+C to copy\"><svg aria-hidden=\"true\" focusable=\"false\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><rect x=\"5.5\" y=\"5.5\" width=\"8\" height=\"8.5\" rx=\"1.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"\/><path d=\"M10.5 3.5V3A1.5 1.5 0 0 0 9 1.5H4A1.5 1.5 0 0 0 2.5 3v6.5A1.5 1.5 0 0 0 4 11h.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"\/><\/svg><span class=\"cbb-button-label\" aria-live=\"polite\">Copy<\/span><\/button><\/span><\/figcaption><pre class=\"cbb-pre\" tabindex=\"0\"><code class=\"cbb-code language-json\" style=\"counter-reset:cbb-line 0;\"><span class=\"cbb-line\">{\n<\/span><span class=\"cbb-line\">\t<span class=\"cbb-attr\">\"$schema\"<\/span>: <span class=\"cbb-string\">\"https:\/\/playground.wordpress.net\/blueprint-schema.json\"<\/span>,\n<\/span><span class=\"cbb-line\">\t<span class=\"cbb-attr\">\"landingPage\"<\/span>: <span class=\"cbb-string\">\"\/wp-admin\/plugins.php\"<\/span>,\n<\/span><span class=\"cbb-line\">\t<span class=\"cbb-attr\">\"preferredVersions\"<\/span>: {\n<\/span><span class=\"cbb-line\">\t\t<span class=\"cbb-attr\">\"php\"<\/span>: <span class=\"cbb-string\">\"8.3\"<\/span>,\n<\/span><span class=\"cbb-line\">\t\t<span class=\"cbb-attr\">\"wp\"<\/span>: <span class=\"cbb-string\">\"latest\"<\/span>\n<\/span><span class=\"cbb-line\">\t},\n<\/span><span class=\"cbb-line\">\t<span class=\"cbb-attr\">\"features\"<\/span>: {\n<\/span><span class=\"cbb-line\">\t\t<span class=\"cbb-attr\">\"networking\"<\/span>: <span class=\"cbb-constant\">true<\/span>\n<\/span><span class=\"cbb-line\">\t},\n<\/span><span class=\"cbb-line\">\t<span class=\"cbb-attr\">\"steps\"<\/span>: &#91;\n<\/span><span class=\"cbb-line\">\t\t{\n<\/span><span class=\"cbb-line\">\t\t\t<span class=\"cbb-attr\">\"step\"<\/span>: <span class=\"cbb-string\">\"login\"<\/span>,\n<\/span><span class=\"cbb-line\">\t\t\t<span class=\"cbb-attr\">\"username\"<\/span>: <span class=\"cbb-string\">\"admin\"<\/span>\n<\/span><span class=\"cbb-line\">\t\t},\n<\/span><span class=\"cbb-line\">\t\t{\n<\/span><span class=\"cbb-line\">\t\t\t<span class=\"cbb-attr\">\"step\"<\/span>: <span class=\"cbb-string\">\"installPlugin\"<\/span>,\n<\/span><span class=\"cbb-line\">\t\t\t<span class=\"cbb-attr\">\"pluginData\"<\/span>: {\n<\/span><span class=\"cbb-line\">\t\t\t\t<span class=\"cbb-attr\">\"resource\"<\/span>: <span class=\"cbb-string\">\"wordpress.org\/plugins\"<\/span>,\n<\/span><span class=\"cbb-line\">\t\t\t\t<span class=\"cbb-attr\">\"slug\"<\/span>: <span class=\"cbb-string\">\"contact-form-7\"<\/span>\n<\/span><span class=\"cbb-line\">\t\t\t},\n<\/span><span class=\"cbb-line\">\t\t\t<span class=\"cbb-attr\">\"options\"<\/span>: {\n<\/span><span class=\"cbb-line\">\t\t\t\t<span class=\"cbb-attr\">\"activate\"<\/span>: <span class=\"cbb-constant\">true<\/span>\n<\/span><span class=\"cbb-line\">\t\t\t}\n<\/span><span class=\"cbb-line\">\t\t},\n<\/span><span class=\"cbb-line\">\t\t{\n<\/span><span class=\"cbb-line\">\t\t\t<span class=\"cbb-attr\">\"step\"<\/span>: <span class=\"cbb-string\">\"setSiteOptions\"<\/span>,\n<\/span><span class=\"cbb-line\">\t\t\t<span class=\"cbb-attr\">\"options\"<\/span>: {\n<\/span><span class=\"cbb-line\">\t\t\t\t<span class=\"cbb-attr\">\"blogname\"<\/span>: <span class=\"cbb-string\">\"LW Form Archive Demo\"<\/span>,\n<\/span><span class=\"cbb-line\">\t\t\t\t<span class=\"cbb-attr\">\"lw_form_archive_retention_days\"<\/span>: <span class=\"cbb-number\">14<\/span>\n<\/span><span class=\"cbb-line\">\t\t\t}\n<\/span><span class=\"cbb-line\">\t\t}\n<\/span><span class=\"cbb-line\">\t&#93;\n<\/span><span class=\"cbb-line\">}<\/span><\/code><\/pre><\/figure>\n<p>Als Startseite dient die Pluginliste. Dort zeigt WordPress ab Version 6.5 die Beziehung zwischen dem Add-on und Contact Form 7. Das \u00e4ltere Handbook-Beispiel enth\u00e4lt noch veraltete Blueprint-Felder und \u00e4ltere Laufzeitversionen. Der hier gezeigte Blueprint verwendet <code>pluginData<\/code> und wurde gegen das am 25.10.2026 abgerufene Schema gepr\u00fcft.<\/p>\n<h2>Requires Plugins: die Abh\u00e4ngigkeit erkl\u00e4ren<\/h2>\n<p>Der Header <code>Requires Plugins<\/code> nennt seit WordPress 6.5 die ben\u00f6tigten Plugins. Erwartet werden durch Kommas getrennte WordPress.org-Slugs wie <code>contact-form-7<\/code>, keine Dateipfade. Ein Slug ist der kurze Verzeichnisname des Plugins. Ung\u00fcltige Schreibweisen k\u00f6nnen aus der Abh\u00e4ngigkeitsliste fallen. Das folgende Add-on demonstriert nur diesen Header und eine gespeicherte Option. Trotz des Namens \u201eForm Archive\u201c archiviert der Code keine Formulare und l\u00f6scht auch keine Daten nach der angegebenen Tageszahl.<\/p>\n<figure style=\"--cbb-digits:2\" class=\"cbb cbb--wrap cbb--numbers wp-block-code-beautifier-block-code\" data-lang=\"php\"><figcaption class=\"cbb-head\"><span class=\"cbb-lang\">PHP<\/span><span class=\"cbb-actions\"><button type=\"button\" class=\"cbb-button cbb-button--wrap\" data-cbb-action=\"wrap\" aria-pressed=\"true\" title=\"Wrap long lines\"><svg aria-hidden=\"true\" focusable=\"false\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><path d=\"M2 4h12M2 8h9.5a2.5 2.5 0 0 1 0 5H8m0 0 1.5-1.5M8 13l1.5 1.5M2 12h3\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/><\/svg><span class=\"cbb-sr\">Wrap long lines<\/span><\/button><button type=\"button\" class=\"cbb-button cbb-button--copy\" data-cbb-action=\"copy\" data-cbb-done=\"Copied\" data-cbb-failed=\"Press Ctrl+C to copy\"><svg aria-hidden=\"true\" focusable=\"false\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><rect x=\"5.5\" y=\"5.5\" width=\"8\" height=\"8.5\" rx=\"1.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"\/><path d=\"M10.5 3.5V3A1.5 1.5 0 0 0 9 1.5H4A1.5 1.5 0 0 0 2.5 3v6.5A1.5 1.5 0 0 0 4 11h.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"\/><\/svg><span class=\"cbb-button-label\" aria-live=\"polite\">Copy<\/span><\/button><\/span><\/figcaption><pre class=\"cbb-pre\" tabindex=\"0\"><code class=\"cbb-code language-php\" style=\"counter-reset:cbb-line 0;\"><span class=\"cbb-line\"><span class=\"cbb-meta\">&lt;?php<\/span>\n<\/span><span class=\"cbb-line\"><span class=\"cbb-comment\">\/**<\/span>\n<\/span><span class=\"cbb-line\"><span class=\"cbb-comment\"> * Plugin Name:       LW Form Archive<\/span>\n<\/span><span class=\"cbb-line\"><span class=\"cbb-comment\"> * Description:       Example add-on for Contact Form 7 (dependency and Blueprint demo).<\/span>\n<\/span><span class=\"cbb-line\"><span class=\"cbb-comment\"> * Version:           1.0.0<\/span>\n<\/span><span class=\"cbb-line\"><span class=\"cbb-comment\"> * Requires at least: 6.7<\/span>\n<\/span><span class=\"cbb-line\"><span class=\"cbb-comment\"> * Requires PHP:      7.4<\/span>\n<\/span><span class=\"cbb-line\"><span class=\"cbb-comment\"> * Requires Plugins:  contact-form-7<\/span>\n<\/span><span class=\"cbb-line\"><span class=\"cbb-comment\"> * Author:            Lukas Wojcik<\/span>\n<\/span><span class=\"cbb-line\"><span class=\"cbb-comment\"> * License:           GPL-2.0-or-later<\/span>\n<\/span><span class=\"cbb-line\"><span class=\"cbb-comment\"> * License URI:       https:\/\/www.gnu.org\/licenses\/gpl-2.0.html<\/span>\n<\/span><span class=\"cbb-line\"><span class=\"cbb-comment\"> * Text Domain:       lw-form-archive<\/span>\n<\/span><span class=\"cbb-line\"><span class=\"cbb-comment\"> *<\/span>\n<\/span><span class=\"cbb-line\"><span class=\"cbb-comment\"> * @package LW_Form_Archive<\/span>\n<\/span><span class=\"cbb-line\"><span class=\"cbb-comment\"> *\/<\/span>\n<\/span><span class=\"cbb-line\">\n<\/span><span class=\"cbb-line\"><span class=\"cbb-function\">defined<\/span>( <span class=\"cbb-string\">'ABSPATH'<\/span> ) || exit;\n<\/span><span class=\"cbb-line\">\n<\/span><span class=\"cbb-line\"><span class=\"cbb-comment\">\/**<\/span>\n<\/span><span class=\"cbb-line\"><span class=\"cbb-comment\"> * Stores the default retention period on activation.<\/span>\n<\/span><span class=\"cbb-line\"><span class=\"cbb-comment\"> *<\/span>\n<\/span><span class=\"cbb-line\"><span class=\"cbb-comment\"> * add_option() leaves an existing value untouched, so a value that a<\/span>\n<\/span><span class=\"cbb-line\"><span class=\"cbb-comment\"> * Blueprint wrote earlier with setSiteOptions survives activation.<\/span>\n<\/span><span class=\"cbb-line\"><span class=\"cbb-comment\"> *\/<\/span>\n<\/span><span class=\"cbb-line\"><span class=\"cbb-keyword\">function<\/span> <span class=\"cbb-function\">lw_form_archive_activate<\/span>() {\n<\/span><span class=\"cbb-line\">\t<span class=\"cbb-function\">add_option<\/span>( <span class=\"cbb-string\">'lw_form_archive_retention_days'<\/span>, <span class=\"cbb-number\">30<\/span> );\n<\/span><span class=\"cbb-line\">}\n<\/span><span class=\"cbb-line\"><span class=\"cbb-function\">register_activation_hook<\/span>( __FILE__, <span class=\"cbb-string\">'lw_form_archive_activate'<\/span> );\n<\/span><span class=\"cbb-line\">\n<\/span><span class=\"cbb-line\"><span class=\"cbb-comment\">\/**<\/span>\n<\/span><span class=\"cbb-line\"><span class=\"cbb-comment\"> * Returns the retention period in days.<\/span>\n<\/span><span class=\"cbb-line\"><span class=\"cbb-comment\"> *<\/span>\n<\/span><span class=\"cbb-line\"><span class=\"cbb-comment\"> * @return int<\/span>\n<\/span><span class=\"cbb-line\"><span class=\"cbb-comment\"> *\/<\/span>\n<\/span><span class=\"cbb-line\"><span class=\"cbb-keyword\">function<\/span> <span class=\"cbb-function\">lw_form_archive_retention_days<\/span>() {\n<\/span><span class=\"cbb-line\">\t<span class=\"cbb-keyword\">return<\/span> <span class=\"cbb-function\">absint<\/span>( <span class=\"cbb-function\">get_option<\/span>( <span class=\"cbb-string\">'lw_form_archive_retention_days'<\/span>, <span class=\"cbb-number\">30<\/span> ) );\n<\/span><span class=\"cbb-line\">}<\/span><\/code><\/pre><\/figure>\n<p>Die Pluginverwaltung pr\u00fcft Abh\u00e4ngigkeiten bei Installation und Aktivierung. Eine ben\u00f6tigte Erweiterung muss vor der Aktivierung des Add-ons vorhanden und aktiv sein. Die Oberfl\u00e4che verhindert au\u00dferdem bestimmte L\u00f6sch- und Deaktivierungsschritte, solange abh\u00e4ngige Plugins betroffen w\u00e4ren. Das ist keine Dateisystemsperre: FTP kann Dateien weiterhin entfernen. Auch WP-CLI kann ein Plugin zun\u00e4chst ohne Abh\u00e4ngigkeiten installieren; die anschlie\u00dfende Aktivierung kann dann scheitern.<\/p>\n<p>F\u00fcr diesen Ablauf ist <code>activate_plugin()<\/code> entscheidend. WordPress pr\u00fcft dabei Anforderungen an WordPress, PHP und abh\u00e4ngige Plugins. Bei einem Fehler entsteht ein <code>WP_Error<\/code>. Playground pr\u00fcft nach der Aktivierung, ob das Plugin tats\u00e4chlich aktiv ist. Fehlt Contact Form 7 oder verlangt die heruntergeladene Fassung eine neuere Umgebung, schl\u00e4gt der Einrichtungslauf fehl. Ein erfolgreicher Lauf beweist dagegen zun\u00e4chst nur, dass diese Einrichtung gelang.<\/p>\n<p><code>add_option()<\/code> l\u00e4sst eine bereits gespeicherte Option unver\u00e4ndert. Deshalb bleiben die 14 Tage aus dem Blueprint erhalten; eine frische Installation ohne Blueprint erh\u00e4lt den Standardwert 30. Das sind Beispielwerte ohne nachgelagerte L\u00f6schfunktion. <a href=\"https:\/\/www.lukaswojcik.com\/blog\/de\/wordpress-plugins-tricks-de\/plugin-lebenszyklus-aktivierung-deaktivierung-deinstallation\/\">Ein eigener Beitrag dieser Reihe<\/a> erl\u00e4utert den Lebenszyklus. Der Abh\u00e4ngigkeitseintrag nennt weder Mindestversionen des anderen Plugins noch eine Ladereihenfolge. Code, der eine bestimmte Klasse oder Funktion ben\u00f6tigt, muss deren Verf\u00fcgbarkeit zus\u00e4tzlich pr\u00fcfen.<\/p>\n<h2>Lokale L\u00e4ufe mit der Playground CLI<\/h2>\n<p>Die Beispiele verwenden fest <code>@wp-playground\/cli@3.1.56<\/code>, den Stand der dokumentierten urspr\u00fcnglichen Tests. <code>start<\/code> bewahrt eine Entwicklungswebsite f\u00fcr sp\u00e4tere Aufrufe auf. <code>server<\/code> startet den lokalen Webzugang; <code>run-blueprint<\/code> f\u00fchrt die Einrichtung ohne dauerhaft laufenden Webserver aus. Daneben gibt es Export und einzelne PHP-Aufrufe. Frische Standardl\u00e4ufe eignen sich besser f\u00fcr vergleichbare Tests als eine bereits ver\u00e4nderte Entwicklungswebsite. Eingebundene Arbeitsordner bleiben allerdings echte lokale Dateien und werden dadurch nicht automatisch zur\u00fcckgesetzt.<\/p>\n<figure style=\"--cbb-digits:2\" class=\"cbb cbb--wrap cbb--numbers wp-block-code-beautifier-block-code\" data-lang=\"javascript\"><figcaption class=\"cbb-head\"><span class=\"cbb-lang\">JavaScript<\/span><span class=\"cbb-actions\"><button type=\"button\" class=\"cbb-button cbb-button--wrap\" data-cbb-action=\"wrap\" aria-pressed=\"true\" title=\"Wrap long lines\"><svg aria-hidden=\"true\" focusable=\"false\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><path d=\"M2 4h12M2 8h9.5a2.5 2.5 0 0 1 0 5H8m0 0 1.5-1.5M8 13l1.5 1.5M2 12h3\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/><\/svg><span class=\"cbb-sr\">Wrap long lines<\/span><\/button><button type=\"button\" class=\"cbb-button cbb-button--copy\" data-cbb-action=\"copy\" data-cbb-done=\"Copied\" data-cbb-failed=\"Press Ctrl+C to copy\"><svg aria-hidden=\"true\" focusable=\"false\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><rect x=\"5.5\" y=\"5.5\" width=\"8\" height=\"8.5\" rx=\"1.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"\/><path d=\"M10.5 3.5V3A1.5 1.5 0 0 0 9 1.5H4A1.5 1.5 0 0 0 2.5 3v6.5A1.5 1.5 0 0 0 4 11h.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"\/><\/svg><span class=\"cbb-button-label\" aria-live=\"polite\">Copy<\/span><\/button><\/span><\/figcaption><pre class=\"cbb-pre\" tabindex=\"0\"><code class=\"cbb-code language-javascript\" style=\"counter-reset:cbb-line 0;\"><span class=\"cbb-line\"># <span class=\"cbb-type\">Run<\/span> <span class=\"cbb-keyword\">from<\/span> the plugin <span class=\"cbb-function\">folder<\/span> (the folder name must match the slug).\n<\/span><span class=\"cbb-line\">cd lw-form-archive\n<\/span><span class=\"cbb-line\">\n<\/span><span class=\"cbb-line\"># <span class=\"cbb-type\">Interactive<\/span>: fresh site on http:<span class=\"cbb-comment\">\/\/127.0.0.1:9400 with the working copy mounted.<\/span>\n<\/span><span class=\"cbb-line\"># PHP and <span class=\"cbb-type\">WordPress<\/span> come <span class=\"cbb-keyword\">from<\/span> preferredVersions <span class=\"cbb-keyword\">in<\/span> the <span class=\"cbb-function\">Blueprint<\/span> (<span class=\"cbb-number\">8.3<\/span>, latest);\n<\/span><span class=\"cbb-line\"># --php and --wp have no effect together <span class=\"cbb-keyword\">with<\/span> a <span class=\"cbb-type\">Blueprint<\/span> <span class=\"cbb-function\">file<\/span> (CLI 3.1.56).\n<\/span><span class=\"cbb-line\">npx @wp-playground\/cli@3.1.56 server --auto-mount \\\n<\/span><span class=\"cbb-line\">  --blueprint=.wordpress-org\/blueprints\/blueprint.json\n<\/span><span class=\"cbb-line\">\n<\/span><span class=\"cbb-line\"># <span class=\"cbb-type\">Smoke<\/span> test on the oldest tested <span class=\"cbb-function\">branch<\/span> (patched release): a copy <span class=\"cbb-keyword\">with<\/span> other preferredVersions,\n<\/span><span class=\"cbb-line\"># run without a server, non-zero exit code on failure.\n<\/span><span class=\"cbb-line\">node -e \"<span class=\"cbb-keyword\">const<\/span> fs = <span class=\"cbb-function\">require<\/span>(<span class=\"cbb-string\">'fs'<\/span>);\n<\/span><span class=\"cbb-line\">  <span class=\"cbb-keyword\">const<\/span> b = JSON.<span class=\"cbb-function\">parse<\/span>(fs.<span class=\"cbb-function\">readFileSync<\/span>(<span class=\"cbb-string\">'.wordpress-org\/blueprints\/blueprint.json'<\/span>, <span class=\"cbb-string\">'utf8'<\/span>));\n<\/span><span class=\"cbb-line\">  b.preferredVersions = { php: <span class=\"cbb-string\">'7.4'<\/span>, wp: <span class=\"cbb-string\">'6.7.9'<\/span> };\n<\/span><span class=\"cbb-line\">  fs.<span class=\"cbb-function\">writeFileSync<\/span>(<span class=\"cbb-string\">'\/tmp\/blueprint-min.json'<\/span>, JSON.<span class=\"cbb-function\">stringify<\/span>(b));\"\n<\/span><span class=\"cbb-line\">npx @wp-playground\/cli@3.1.56 run-blueprint --auto-mount \\\n<\/span><span class=\"cbb-line\">  --blueprint=\/tmp\/blueprint-min.json<\/span><\/code><\/pre><\/figure>\n<p><code>--auto-mount<\/code> bindet ohne weiteren Wert den aktuellen Ordner ein. Die CLI erkennt den Plugin-Header und verwendet den Ordnernamen unter <code>\/wordpress\/wp-content\/plugins\/<\/code>. Nach den Blueprint-Schritten folgt die Aktivierung. Der Ordner hei\u00dft deshalb <code>lw-form-archive<\/code>, passend zum Plugin-Slug. Die Einbindung ist kein schreibgesch\u00fctzter Schnappschuss; Tests geh\u00f6ren in eine entbehrliche Arbeitskopie.<\/p>\n<p>Im dokumentierten Test mit CLI 3.1.56 hatten <code>--wp<\/code> und <code>--php<\/code> bei einer Blueprint-Datei nicht den erwarteten Vorrang. Tats\u00e4chlich liefen die Werte aus <code>preferredVersions<\/code>, obwohl eine Startmeldung andere Werte zeigte. Das Beispiel schreibt deshalb f\u00fcr jeden Test eine Kopie mit der gew\u00fcnschten Kombination. Ein Fehler beendet <code>run-blueprint<\/code> mit einem Fehlerstatus. Dieser kurze Einrichtungstest pr\u00fcft noch keine Formularverarbeitung. F\u00fcr Browsertests \u00fcber <code>?blueprint-url=<\/code> braucht die Datei au\u00dferdem einen erreichbaren Speicherort und passende CORS-Freigaben f\u00fcr den Abruf.<\/p>\n<h2>wp-env: feste Versionen in Docker<\/h2>\n<p>Der zweite Weg verwendet <code>@wordpress\/env@11.16.0<\/code> mit Docker und MariaDB. Das ist besonders f\u00fcr Datenbankabfragen hilfreich, deren Verhalten von SQLite abweichen kann. <code>.wp-env.json<\/code> nennt die WordPress-Version, PHP und die zu installierenden Plugins. Die Variablen <code>WP_ENV_CORE<\/code> und <code>WP_ENV_PHP_VERSION<\/code> setzen in der Testmatrix andere Versionen. Der Blueprint wird dabei nicht geladen; Demowerte daraus fehlen also zun\u00e4chst.<\/p>\n<figure style=\"--cbb-digits:2\" class=\"cbb cbb--wrap cbb--numbers wp-block-code-beautifier-block-code\" data-lang=\"json\"><figcaption class=\"cbb-head\"><span class=\"cbb-lang\">JSON<\/span><span class=\"cbb-actions\"><button type=\"button\" class=\"cbb-button cbb-button--wrap\" data-cbb-action=\"wrap\" aria-pressed=\"true\" title=\"Wrap long lines\"><svg aria-hidden=\"true\" focusable=\"false\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><path d=\"M2 4h12M2 8h9.5a2.5 2.5 0 0 1 0 5H8m0 0 1.5-1.5M8 13l1.5 1.5M2 12h3\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/><\/svg><span class=\"cbb-sr\">Wrap long lines<\/span><\/button><button type=\"button\" class=\"cbb-button cbb-button--copy\" data-cbb-action=\"copy\" data-cbb-done=\"Copied\" data-cbb-failed=\"Press Ctrl+C to copy\"><svg aria-hidden=\"true\" focusable=\"false\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><rect x=\"5.5\" y=\"5.5\" width=\"8\" height=\"8.5\" rx=\"1.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"\/><path d=\"M10.5 3.5V3A1.5 1.5 0 0 0 9 1.5H4A1.5 1.5 0 0 0 2.5 3v6.5A1.5 1.5 0 0 0 4 11h.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"\/><\/svg><span class=\"cbb-button-label\" aria-live=\"polite\">Copy<\/span><\/button><\/span><\/figcaption><pre class=\"cbb-pre\" tabindex=\"0\"><code class=\"cbb-code language-json\" style=\"counter-reset:cbb-line 0;\"><span class=\"cbb-line\">{\n<\/span><span class=\"cbb-line\">\t<span class=\"cbb-attr\">\"$schema\"<\/span>: <span class=\"cbb-string\">\"https:\/\/schemas.wp.org\/trunk\/wp-env.json\"<\/span>,\n<\/span><span class=\"cbb-line\">\t<span class=\"cbb-attr\">\"core\"<\/span>: <span class=\"cbb-string\">\"WordPress\/WordPress#7.1.2\"<\/span>,\n<\/span><span class=\"cbb-line\">\t<span class=\"cbb-attr\">\"phpVersion\"<\/span>: <span class=\"cbb-string\">\"8.3\"<\/span>,\n<\/span><span class=\"cbb-line\">\t<span class=\"cbb-attr\">\"plugins\"<\/span>: &#91;\n<\/span><span class=\"cbb-line\">\t\t<span class=\"cbb-string\">\"https:\/\/downloads.wordpress.org\/plugin\/contact-form-7.6.1.7.zip\"<\/span>,\n<\/span><span class=\"cbb-line\">\t\t<span class=\"cbb-string\">\".\"<\/span>\n<\/span><span class=\"cbb-line\">\t&#93;,\n<\/span><span class=\"cbb-line\">\t<span class=\"cbb-attr\">\"config\"<\/span>: {\n<\/span><span class=\"cbb-line\">\t\t<span class=\"cbb-attr\">\"WP_DEBUG_LOG\"<\/span>: <span class=\"cbb-constant\">true<\/span>\n<\/span><span class=\"cbb-line\">\t}\n<\/span><span class=\"cbb-line\">}<\/span><\/code><\/pre><\/figure>\n<p>Im gepr\u00fcften wp-env-Stand werden die Plugins in der angegebenen Reihenfolge aktiviert. Deshalb steht Contact Form 7 vor dem Add-on. Die versionierte ZIP-Adresse nennt hier 6.1.7. Der Parser entfernt die Versionsendung aus dem Dateinamen und erh\u00e4lt den erwarteten Ordner <code>contact-form-7<\/code>. Die Form <code>.latest-stable.zip<\/code> hat in diesem Parser ein anderes Ergebnis und ist daher kein gleichwertiger Ersatz. Die feste ZIP reduziert \u00c4nderungen an der Abh\u00e4ngigkeit, garantiert aber weder verf\u00fcgbare Downloads noch identische Ergebnisse der gesamten Testumgebung.<\/p>\n<p><code>WordPress\/WordPress#7.1.2<\/code> bezeichnet ein genaues Tag im GitHub-Spiegel. Ein Tag <code>7.1<\/code> bezeichnet nicht automatisch 7.1.2. Innerhalb der Docker-Umgebung startet <code>wp-env run cli<\/code> einen angegebenen Befehl. Die alternative Playground-Laufzeit von wp-env verwendet SQLite und unterst\u00fctzt laut aktueller Dokumentation den Befehl <code>run<\/code> nicht. Der folgende Workflow bleibt deshalb ausdr\u00fccklich beim Docker-Weg.<\/p>\n<h2>Eine CI-Matrix \u00fcber WordPress- und PHP-Versionen<\/h2>\n<p>Eine Testmatrix wiederholt einen Ablauf mit mehreren Kombinationen. Hier verwenden beide Jobs genau WordPress 6.7.9\/PHP 7.4, WordPress 7.0.6\/PHP 8.2 und WordPress 7.1.2\/PHP 8.4. Die erste Zeile pr\u00fcft einen gepflegten Stand des \u00e4ltesten ausgew\u00e4hlten Zweigs, nicht jede fr\u00fchere 6.7-Ausgabe. Die Playground-Werte werden in eine Blueprint-Kopie geschrieben; wp-env erh\u00e4lt dieselben Versionsnummern \u00fcber Umgebungsvariablen. Die Action-Tags <code>v7<\/code> und Node 24 sind im Beispiel ausdr\u00fccklich angegeben.<\/p>\n<figure style=\"--cbb-digits:2\" class=\"cbb cbb--wrap cbb--numbers wp-block-code-beautifier-block-code\" data-lang=\"javascript\"><figcaption class=\"cbb-head\"><span class=\"cbb-lang\">JavaScript<\/span><span class=\"cbb-actions\"><button type=\"button\" class=\"cbb-button cbb-button--wrap\" data-cbb-action=\"wrap\" aria-pressed=\"true\" title=\"Wrap long lines\"><svg aria-hidden=\"true\" focusable=\"false\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><path d=\"M2 4h12M2 8h9.5a2.5 2.5 0 0 1 0 5H8m0 0 1.5-1.5M8 13l1.5 1.5M2 12h3\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/><\/svg><span class=\"cbb-sr\">Wrap long lines<\/span><\/button><button type=\"button\" class=\"cbb-button cbb-button--copy\" data-cbb-action=\"copy\" data-cbb-done=\"Copied\" data-cbb-failed=\"Press Ctrl+C to copy\"><svg aria-hidden=\"true\" focusable=\"false\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><rect x=\"5.5\" y=\"5.5\" width=\"8\" height=\"8.5\" rx=\"1.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"\/><path d=\"M10.5 3.5V3A1.5 1.5 0 0 0 9 1.5H4A1.5 1.5 0 0 0 2.5 3v6.5A1.5 1.5 0 0 0 4 11h.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"\/><\/svg><span class=\"cbb-button-label\" aria-live=\"polite\">Copy<\/span><\/button><\/span><\/figcaption><pre class=\"cbb-pre\" tabindex=\"0\"><code class=\"cbb-code language-javascript\" style=\"counter-reset:cbb-line 0;\"><span class=\"cbb-line\"># .github\/workflows\/compatibility.yml\n<\/span><span class=\"cbb-line\">name: <span class=\"cbb-type\">Compatibility<\/span>\n<\/span><span class=\"cbb-line\">\n<\/span><span class=\"cbb-line\">on:\n<\/span><span class=\"cbb-line\">  push:\n<\/span><span class=\"cbb-line\">    branches: &#91; trunk &#93;\n<\/span><span class=\"cbb-line\">  pull_request:\n<\/span><span class=\"cbb-line\">\n<\/span><span class=\"cbb-line\">permissions:\n<\/span><span class=\"cbb-line\">  contents: read\n<\/span><span class=\"cbb-line\">\n<\/span><span class=\"cbb-line\">jobs:\n<\/span><span class=\"cbb-line\">  playground:\n<\/span><span class=\"cbb-line\">    name: <span class=\"cbb-type\">Playground<\/span> \/ WP ${{ matrix.wp }} \/ PHP ${{ matrix.php }}\n<\/span><span class=\"cbb-line\">    runs-on: ubuntu-latest\n<\/span><span class=\"cbb-line\">    strategy:\n<\/span><span class=\"cbb-line\">      fail-fast: <span class=\"cbb-constant\">false<\/span>\n<\/span><span class=\"cbb-line\">      matrix:\n<\/span><span class=\"cbb-line\">        include:\n<\/span><span class=\"cbb-line\">          - { wp: <span class=\"cbb-string\">'6.7.9'<\/span>, php: <span class=\"cbb-string\">'7.4'<\/span> }\n<\/span><span class=\"cbb-line\">          - { wp: <span class=\"cbb-string\">'7.0.6'<\/span>, php: <span class=\"cbb-string\">'8.2'<\/span> }\n<\/span><span class=\"cbb-line\">          - { wp: <span class=\"cbb-string\">'7.1.2'<\/span>, php: <span class=\"cbb-string\">'8.4'<\/span> }\n<\/span><span class=\"cbb-line\">    steps:\n<\/span><span class=\"cbb-line\">      # <span class=\"cbb-type\">Check<\/span> out into a folder named like the slug: auto-mount uses the folder name.\n<\/span><span class=\"cbb-line\">      - uses: actions\/checkout@v7\n<\/span><span class=\"cbb-line\">        <span class=\"cbb-keyword\">with<\/span>:\n<\/span><span class=\"cbb-line\">          path: lw-form-archive\n<\/span><span class=\"cbb-line\">      - uses: actions\/setup-node@v7\n<\/span><span class=\"cbb-line\">        <span class=\"cbb-keyword\">with<\/span>:\n<\/span><span class=\"cbb-line\">          node-version: <span class=\"cbb-number\">24<\/span>\n<\/span><span class=\"cbb-line\">      # <span class=\"cbb-type\">For<\/span> a <span class=\"cbb-type\">Blueprint<\/span> file the CLI ignores --wp and --<span class=\"cbb-function\">php<\/span> (CLI 3.1.56),\n<\/span><span class=\"cbb-line\">      # so the matrix versions go into preferredVersions <span class=\"cbb-keyword\">of<\/span> a copy.\n<\/span><span class=\"cbb-line\">      - name: <span class=\"cbb-type\">Write<\/span> the matrix versions into a copy <span class=\"cbb-keyword\">of<\/span> the <span class=\"cbb-type\">Blueprint<\/span>\n<\/span><span class=\"cbb-line\">        working-directory: lw-form-archive\n<\/span><span class=\"cbb-line\">        run: &gt;-\n<\/span><span class=\"cbb-line\">          node -e \"<span class=\"cbb-keyword\">const<\/span> fs = <span class=\"cbb-function\">require<\/span>(<span class=\"cbb-string\">'fs'<\/span>);\n<\/span><span class=\"cbb-line\">          <span class=\"cbb-keyword\">const<\/span> b = JSON.<span class=\"cbb-function\">parse<\/span>(fs.<span class=\"cbb-function\">readFileSync<\/span>(<span class=\"cbb-string\">'.wordpress-org\/blueprints\/blueprint.json'<\/span>, <span class=\"cbb-string\">'utf8'<\/span>));\n<\/span><span class=\"cbb-line\">          b.preferredVersions = { php: <span class=\"cbb-string\">'${{ matrix.php }}'<\/span>, wp: <span class=\"cbb-string\">'${{ matrix.wp }}'<\/span> };\n<\/span><span class=\"cbb-line\">          fs.<span class=\"cbb-function\">writeFileSync<\/span>(process.env.RUNNER_TEMP + <span class=\"cbb-string\">'\/blueprint.json'<\/span>, JSON.<span class=\"cbb-function\">stringify<\/span>(b));\"\n<\/span><span class=\"cbb-line\">      - name: <span class=\"cbb-type\">Run<\/span> the <span class=\"cbb-type\">Blueprint<\/span> against the working copy\n<\/span><span class=\"cbb-line\">        working-directory: lw-form-archive\n<\/span><span class=\"cbb-line\">        run: &gt;-\n<\/span><span class=\"cbb-line\">          npx --yes @wp-playground\/cli@3.1.56 run-blueprint\n<\/span><span class=\"cbb-line\">          --auto-mount\n<\/span><span class=\"cbb-line\">          --blueprint=${{ runner.temp }}\/blueprint.json\n<\/span><span class=\"cbb-line\">\n<\/span><span class=\"cbb-line\">  wp-env:\n<\/span><span class=\"cbb-line\">    name: wp-env \/ WP ${{ matrix.wp }} \/ PHP ${{ matrix.php }}\n<\/span><span class=\"cbb-line\">    runs-on: ubuntu-latest\n<\/span><span class=\"cbb-line\">    strategy:\n<\/span><span class=\"cbb-line\">      fail-fast: <span class=\"cbb-constant\">false<\/span>\n<\/span><span class=\"cbb-line\">      matrix:\n<\/span><span class=\"cbb-line\">        include:\n<\/span><span class=\"cbb-line\">          - { wp: <span class=\"cbb-string\">'6.7.9'<\/span>, php: <span class=\"cbb-string\">'7.4'<\/span> }\n<\/span><span class=\"cbb-line\">          - { wp: <span class=\"cbb-string\">'7.0.6'<\/span>, php: <span class=\"cbb-string\">'8.2'<\/span> }\n<\/span><span class=\"cbb-line\">          - { wp: <span class=\"cbb-string\">'7.1.2'<\/span>, php: <span class=\"cbb-string\">'8.4'<\/span> }\n<\/span><span class=\"cbb-line\">    env:\n<\/span><span class=\"cbb-line\">      # <span class=\"cbb-type\">Override<\/span> core and phpVersion <span class=\"cbb-keyword\">from<\/span> .wp-env.json <span class=\"cbb-keyword\">for<\/span> <span class=\"cbb-constant\">this<\/span> matrix cell.\n<\/span><span class=\"cbb-line\">      WP_ENV_CORE: <span class=\"cbb-type\">WordPress<\/span>\/<span class=\"cbb-type\">WordPress<\/span>#${{ matrix.wp }}\n<\/span><span class=\"cbb-line\">      WP_ENV_PHP_VERSION: ${{ matrix.php }}\n<\/span><span class=\"cbb-line\">    steps:\n<\/span><span class=\"cbb-line\">      - uses: actions\/checkout@v7\n<\/span><span class=\"cbb-line\">        <span class=\"cbb-keyword\">with<\/span>:\n<\/span><span class=\"cbb-line\">          path: lw-form-archive\n<\/span><span class=\"cbb-line\">      - uses: actions\/setup-node@v7\n<\/span><span class=\"cbb-line\">        <span class=\"cbb-keyword\">with<\/span>:\n<\/span><span class=\"cbb-line\">          node-version: <span class=\"cbb-number\">24<\/span>\n<\/span><span class=\"cbb-line\">      - name: <span class=\"cbb-type\">Install<\/span> wp-env\n<\/span><span class=\"cbb-line\">        run: npm install -g @wordpress\/env@11.16.0\n<\/span><span class=\"cbb-line\">      - name: <span class=\"cbb-type\">Start<\/span> <span class=\"cbb-function\">WordPress<\/span> (activates the plugins <span class=\"cbb-keyword\">from<\/span> .wp-env.json)\n<\/span><span class=\"cbb-line\">        working-directory: lw-form-archive\n<\/span><span class=\"cbb-line\">        run: wp-env start\n<\/span><span class=\"cbb-line\">      - name: <span class=\"cbb-type\">Check<\/span> activation and the <span class=\"cbb-keyword\">default<\/span> option\n<\/span><span class=\"cbb-line\">        working-directory: lw-form-archive\n<\/span><span class=\"cbb-line\">        run: |\n<\/span><span class=\"cbb-line\">          wp-env run cli wp plugin is-active contact-form-7\n<\/span><span class=\"cbb-line\">          wp-env run cli wp plugin is-active lw-form-archive\n<\/span><span class=\"cbb-line\">          wp-env run cli wp eval <span class=\"cbb-string\">'if (lw_form_archive_retention_days() !== 30) { WP_CLI::error(\"Unexpected default retention value\"); }'<\/span><\/span><\/code><\/pre><\/figure>\n<p>Der Playground-Job pr\u00fcft die Einrichtung mit der aktuell vom Pluginverzeichnis gelieferten stabilen Contact-Form-7-Fassung. Der Docker-Job verwendet dagegen die feste Fassung 6.1.7. Zus\u00e4tzlich kontrolliert dieser Job, ob beide Plugins aktiv sind und die Funktion des Beispiels den Standardwert 30 liefert. <code>wp plugin is-active<\/code> meldet bei einem inaktiven Plugin einen Fehlerstatus. Das ist eine gezielte Kontrolle von Aktivierung und Option, kein umfassender Funktionstest und keine Zusage gleichbleibender Ergebnisse.<\/p>\n<p>Der historische Test zeigt den Nutzen der zwei Wege: Contact Form 7 6.1.7 lief mit den \u00e4lteren Anforderungen, w\u00e4hrend der damalige Entwicklungsstand 6.2-rc h\u00f6here WordPress- und PHP-Versionen verlangte. Eine k\u00fcnftig ausgelieferte stabile Fassung mit h\u00f6heren Anforderungen kann daher den Playground-Job scheitern lassen, obwohl der Docker-Job mit der \u00e4lteren festen Abh\u00e4ngigkeit weiter funktioniert. Das Signal betrifft zun\u00e4chst diese getesteten Kombinationen. Ob das eigentliche Add-on fachlich korrekt arbeitet, braucht zus\u00e4tzliche Tests.<\/p>\n<p>Eine PR-Vorschau kann zus\u00e4tzlich \u00fcber <code>WordPress\/action-wp-playground-pr-preview@v4<\/code> eingerichtet werden. F\u00fcr echte PHPUnit-Tests muss im Projekt eine Testsuite vorliegen. Ein vollst\u00e4ndiger Aufruf nennt auch das Programm, etwa <code>wp-env run cli --env-cwd=wp-content\/plugins\/lw-form-archive phpunit<\/code>. Nur Container und Arbeitsordner anzugeben f\u00fchrt noch keinen Test aus. <a href=\"https:\/\/www.lukaswojcik.com\/blog\/de\/wordpress-plugins-tricks-de\/tutorials-de-wordpress-plugins-tricks-de\/plugin-check-lokal-und-in-der-ci-befunde-vor-dem-review\/\">Ein eigener Beitrag dieser Reihe<\/a> behandelt die statische Pr\u00fcfung mit Plugin Check.<\/p>\n<h2>Grenzen und offene Punkte<\/h2>\n<ul>\n<li>Der historische Bericht dokumentiert drei erfolgreiche lokale Playground-Zellen mit CLI 3.1.56. Ein GitHub- oder Docker-Lauf wurde damals nicht belegt. F\u00fcr die hier korrigierte Fassung wurden JSON, YAML, Shell- und PHP-Syntax, vier Blueprint-Kombinationen gegen das aktuelle Schema sowie die Optionswerte 14 und 30 mit isolierten Ersatzfunktionen gepr\u00fcft. Die erg\u00e4nzten Docker-Pr\u00fcfschritte wurden nicht in einer echten WordPress-Umgebung ausgef\u00fchrt.<\/li>\n<li>Playground nutzt SQLite. Plugins mit eigenen Tabellen oder handgeschriebenem SQL k\u00f6nnen sich anders verhalten als unter MySQL; f\u00fcr eigene Tabellen ist der wp-env-Job die aussagekr\u00e4ftigere Pr\u00fcfung. Zum Thema passt <a href=\"https:\/\/www.lukaswojcik.com\/blog\/de\/web-entwicklung\/wordpress-datenbank-leistungsgrenzen-von-wp_postmeta-und-der-aufbau-eigener-tabellen\/\">der Beitrag \u00fcber Leistungsgrenzen von <code>wp_postmeta<\/code> und eigene Tabellen<\/a>.<\/li>\n<li>Das Schema l\u00e4sst f\u00fcr Ressourcen vom Typ <code>wordpress.org\/plugins<\/code> kein Feld <code>version<\/code> zu (nur <code>resource<\/code> und <code>slug<\/code>), und f\u00fcr einen einfachen Slug baut der Quellcode die Download-Adresse mit <code>latest-stable<\/code>. Ein Slug, der bereits auf <code>.zip<\/code> endet, etwa <code>contact-form-7.6.1.7.zip<\/code>, dient unver\u00e4ndert als Dateiname: Im Test mit Version 6.1.5 installierte die Playground CLI genau diese Version, und der Import des Verzeichnisses schreibt nur Ressourcen vom Typ <code>url<\/code> um. Ob die Vorschau im Verzeichnis diese Form annimmt, ist nicht gepr\u00fcft.<\/li>\n<li>Feste Werkzeugversionen reduzieren \u00c4nderungen zwischen Testl\u00e4ufen. Action-Tags, Node-Versionen, Images, Downloads und externe Dienste k\u00f6nnen sich trotzdem \u00e4ndern. Ein Paket-Lockfile und dokumentierte Laufzeitversionen verbessern die Nachvollziehbarkeit; eine garantierte Gleichheit aller Ergebnisse entsteht daraus nicht.<\/li>\n<li>Das Verzeichnis importiert bis zu zehn Blueprint-Dateien, verwendet aber nur <code>blueprint.json<\/code>. Mehrere Dateien stellt das Handbook als m\u00f6glichen sp\u00e4teren Schritt in Aussicht, ohne Termin.<\/li>\n<li>Der Ordnername <code>.wordpress-org\/blueprints\/<\/code> und die \u00dcbertragung in die SVN-Assets sind Konventionen dieses Beitrags; den SVN-Aufbau selbst behandelt <a href=\"https:\/\/www.lukaswojcik.com\/blog\/de\/wordpress-plugins-tricks-de\/readme-txt-plugin-header-und-svn-wie-wordpress-org-ein-plugin-liest\/\">ein eigener Beitrag dieser Reihe<\/a>.<\/li>\n<\/ul>\n<div class=\"lw-faq\">\n<h2>Fragen und Antworten<\/h2>\n<h3>Warum erscheint die Schaltfl\u00e4che \u201ePreview\u201c nicht, obwohl blueprint.json im SVN liegt?<\/h3>\n<p>Eine g\u00fcltige Datei unter <code>assets\/blueprints\/blueprint.json<\/code> erm\u00f6glicht zun\u00e4chst den internen Test f\u00fcr Committer. F\u00fcr die \u00f6ffentliche Schaltfl\u00e4che braucht die Vorschau zus\u00e4tzlich die Einstellung \u201epublic\u201c unter \u201eAdvanced\u201c. Der gepr\u00fcfte Import verwirft ung\u00fcltiges JSON und Dateien \u00fcber 102.400 Byte. Ein erfolgreicher Import ersetzt au\u00dferdem nicht die Laufzeitpr\u00fcfung des Blueprints.<\/p>\n<h3>L\u00e4sst sich eine Abh\u00e4ngigkeit in der Verzeichnis-Vorschau auf eine bestimmte Version festlegen?<\/h3>\n<p>Der einfache Slug <code>contact-form-7<\/code> l\u00e4dt \u00fcber <code>wordpress.org\/plugins<\/code> die stabile Fassung. Ein zus\u00e4tzliches Feld <code>version<\/code> ist f\u00fcr diese Ressource im gepr\u00fcften Schema nicht erlaubt. Der Verzeichnisimport kann versionierte Downloadadressen au\u00dferdem in einen einfachen Slug umschreiben.<\/p>\n<p>Ein historischer CLI-Test best\u00e4tigte eine ZIP-Dateiangabe im Slug wie <code>contact-form-7.6.1.5.zip<\/code>. Damit lie\u00df sich eine bestimmte Fassung laden. Dieser Umweg wurde nicht in der \u00f6ffentlichen Verzeichnis-Vorschau getestet und ist hier keine Garantie f\u00fcr diesen Einsatzort. Der Docker-Test verwendet stattdessen eine ausdr\u00fccklich versionierte ZIP-Adresse in <code>.wp-env.json<\/code>.<\/p>\n<h3>Ersetzt Requires Plugins die Pr\u00fcfung mit class_exists() im Plugin-Code?<\/h3>\n<p>Nein. Der Header unterst\u00fctzt WordPress bei der Pr\u00fcfung, ob ein ben\u00f6tigtes Plugin vorhanden und aktiv ist. Eine Mindestversion der Abh\u00e4ngigkeit und eine feste Ladereihenfolge legt der Header nicht fest. Vor dem Aufruf einer bestimmten Klasse oder Funktion bleibt deshalb eine passende Verf\u00fcgbarkeitspr\u00fcfung n\u00f6tig.<\/p>\n<\/div>\n<div class=\"lw-quellen\">\n<h2>Quellen<\/h2>\n<ul>\n<li><a href=\"https:\/\/developer.wordpress.org\/plugins\/wordpress-org\/previews-and-blueprints\/\" rel=\"noopener noreferrer\" target=\"_blank\">Plugin Handbook: Previews and Blueprints<\/a> (abgerufen am 29.09.2026)<\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/playground\/blueprints\/data-format\" rel=\"noopener noreferrer\" target=\"_blank\">Playground: Blueprint data format<\/a> (abgerufen am 29.09.2026)<\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/playground\/blueprints\/steps\/\" rel=\"noopener noreferrer\" target=\"_blank\">Playground: Blueprint steps<\/a> (abgerufen am 29.09.2026)<\/li>\n<li><a href=\"https:\/\/playground.wordpress.net\/blueprint-schema.json\" rel=\"noopener noreferrer\" target=\"_blank\">JSON-Schema f\u00fcr Blueprints<\/a> (abgerufen am 29.09.2026)<\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/playground\/developers\/local-development\/wp-playground-cli\/\" rel=\"noopener noreferrer\" target=\"_blank\">Playground CLI<\/a> (abgerufen am 29.09.2026)<\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/playground\/developers\/apis\/query-api\/\" rel=\"noopener noreferrer\" target=\"_blank\">Playground Query API<\/a> (abgerufen am 29.09.2026)<\/li>\n<li><a href=\"https:\/\/github.com\/WordPress\/wordpress-playground\" rel=\"noopener noreferrer\" target=\"_blank\">GitHub: WordPress\/wordpress-playground (CLI, Schritte, Ressourcen, Versionsliste)<\/a> (abgerufen am 29.09.2026)<\/li>\n<li><a href=\"https:\/\/github.com\/WordPress\/wordpress.org\/tree\/trunk\/wordpress.org\/public_html\/wp-content\/plugins\/plugin-directory\" rel=\"noopener noreferrer\" target=\"_blank\">GitHub: Quellcode des Plugin-Verzeichnisses (Blueprint-Import und Endpunkt)<\/a> (abgerufen am 29.09.2026)<\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/block-editor\/reference-guides\/packages\/packages-env\/\" rel=\"noopener noreferrer\" target=\"_blank\">Dokumentation zu @wordpress\/env<\/a> (abgerufen am 29.09.2026)<\/li>\n<li><a href=\"https:\/\/github.com\/WordPress\/gutenberg\/tree\/trunk\/packages\/env\" rel=\"noopener noreferrer\" target=\"_blank\">GitHub: Quellcode von packages\/env<\/a> (abgerufen am 29.09.2026)<\/li>\n<li><a href=\"https:\/\/make.wordpress.org\/core\/2024\/03\/05\/introducing-plugin-dependencies-in-wordpress-6-5\/\" rel=\"noopener noreferrer\" target=\"_blank\">Make WordPress Core: Introducing Plugin Dependencies in WordPress 6.5<\/a> (abgerufen am 29.09.2026)<\/li>\n<li><a href=\"https:\/\/github.com\/WordPress\/wordpress-develop\/blob\/trunk\/src\/wp-includes\/class-wp-plugin-dependencies.php\" rel=\"noopener noreferrer\" target=\"_blank\">wordpress-develop: class-wp-plugin-dependencies.php<\/a> (abgerufen am 29.09.2026)<\/li>\n<li><a href=\"https:\/\/github.com\/WordPress\/wordpress-develop\/blob\/trunk\/src\/wp-admin\/includes\/plugin.php\" rel=\"noopener noreferrer\" target=\"_blank\">wordpress-develop: wp-admin\/includes\/plugin.php (validate_plugin_requirements)<\/a> (abgerufen am 29.09.2026)<\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/add_option\/\" rel=\"noopener noreferrer\" target=\"_blank\">Code Reference: add_option()<\/a> (abgerufen am 29.09.2026)<\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/cli\/commands\/plugin\/is-active\/\" rel=\"noopener noreferrer\" target=\"_blank\">WP-CLI: wp plugin is-active<\/a> (abgerufen am 29.09.2026)<\/li>\n<li><a href=\"https:\/\/api.wordpress.org\/core\/version-check\/1.7\/\" rel=\"noopener noreferrer\" target=\"_blank\">Versions-API von WordPress.org<\/a> und <a href=\"https:\/\/github.com\/WordPress\/WordPress\/tags\" rel=\"noopener noreferrer\" target=\"_blank\">Tags des WordPress-Spiegels auf GitHub<\/a> (abgerufen am 29.09.2026)<\/li>\n<li><a href=\"https:\/\/plugins.svn.wordpress.org\/contact-form-7\/\" rel=\"noopener noreferrer\" target=\"_blank\">Contact Form 7 im Plugin-SVN (tags\/6.1.7 und trunk)<\/a> (abgerufen am 29.09.2026)<\/li>\n<li><a href=\"https:\/\/github.com\/WordPress\/wordpress-playground\/blob\/trunk\/packages\/docs\/site\/docs\/main\/guides\/github-action-pr-preview.md\" rel=\"noopener noreferrer\" target=\"_blank\">Playground-Anleitung: PR-Vorschau mit GitHub Actions<\/a> (abgerufen am 29.09.2026)<\/li>\n<li><a href=\"https:\/\/github.com\/actions\/checkout\" rel=\"noopener noreferrer\" target=\"_blank\">actions\/checkout<\/a> und <a href=\"https:\/\/github.com\/actions\/setup-node\" rel=\"noopener noreferrer\" target=\"_blank\">actions\/setup-node<\/a> (abgerufen am 29.09.2026)<\/li>\n<\/ul>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>Ein Blueprint richtet die Verzeichnis-Vorschau und Playground-Tests ein. Docker verwendet eine eigene Konfiguration. Das Beispiel erkl\u00e4rt die Reihenfolge der Abh\u00e4ngigkeiten, feste Pr\u00fcfversionen und die Grenzen von Aktivierungstests.<\/p>\n","protected":false},"author":1,"featured_media":20937,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[92644],"tags":[92214,92235,92759,92277],"class_list":["post-20879","post","type-post","status-publish","format-standard","hentry","category-tutorials-de-wordpress-plugins-tricks-de","tag-devops-de","tag-tutorial-de","tag-web-development-de","tag-wordpress-de"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>WordPress Playground: Blueprints f\u00fcr Plugin-Vorschau und Tests | Lukas Wojcik<\/title>\n<meta name=\"description\" content=\"Ein Blueprint f\u00fcr die Live-Vorschau im WordPress.org-Verzeichnis, f\u00fcr Playground CLI und wp-env lokal sowie f\u00fcr eine CI-Matrix \u00fcber WP- und PHP-Versionen.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.lukaswojcik.com\/blog\/de\/wordpress-plugins-tricks-de\/tutorials-de-wordpress-plugins-tricks-de\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"WordPress Playground: Blueprints f\u00fcr Plugin-Vorschau und Tests | Lukas Wojcik\" \/>\n<meta property=\"og:description\" content=\"Ein Blueprint f\u00fcr die Live-Vorschau im WordPress.org-Verzeichnis, f\u00fcr Playground CLI und wp-env lokal sowie f\u00fcr eine CI-Matrix \u00fcber WP- und PHP-Versionen.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.lukaswojcik.com\/blog\/de\/wordpress-plugins-tricks-de\/tutorials-de-wordpress-plugins-tricks-de\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\/\" \/>\n<meta property=\"og:site_name\" content=\"Lukas Wojcik - Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-10-27T14:09:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/fi-20879-playground-blueprints-plugin-vorschau-tests.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Lukas Wojcik\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Lukas Wojcik\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"15 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/wordpress-plugins-tricks-de\\\/tutorials-de-wordpress-plugins-tricks-de\\\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/wordpress-plugins-tricks-de\\\/tutorials-de-wordpress-plugins-tricks-de\\\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\\\/\"},\"author\":{\"name\":\"Lukas Wojcik\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"headline\":\"WordPress Playground: Blueprints f\u00fcr Plugin-Vorschau und Tests\",\"datePublished\":\"2026-10-27T14:09:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/wordpress-plugins-tricks-de\\\/tutorials-de-wordpress-plugins-tricks-de\\\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\\\/\"},\"wordCount\":2252,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"image\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/wordpress-plugins-tricks-de\\\/tutorials-de-wordpress-plugins-tricks-de\\\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/fi-20879-playground-blueprints-plugin-vorschau-tests.png\",\"keywords\":[\"DevOps\",\"Tutorial\",\"Web Development\",\"WordPress\"],\"articleSection\":[\"Tutorials\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/wordpress-plugins-tricks-de\\\/tutorials-de-wordpress-plugins-tricks-de\\\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/wordpress-plugins-tricks-de\\\/tutorials-de-wordpress-plugins-tricks-de\\\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\\\/\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/wordpress-plugins-tricks-de\\\/tutorials-de-wordpress-plugins-tricks-de\\\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\\\/\",\"name\":\"WordPress Playground: Blueprints f\u00fcr Plugin-Vorschau und Tests | Lukas Wojcik\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/wordpress-plugins-tricks-de\\\/tutorials-de-wordpress-plugins-tricks-de\\\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/wordpress-plugins-tricks-de\\\/tutorials-de-wordpress-plugins-tricks-de\\\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/fi-20879-playground-blueprints-plugin-vorschau-tests.png\",\"datePublished\":\"2026-10-27T14:09:00+00:00\",\"description\":\"Ein Blueprint f\u00fcr die Live-Vorschau im WordPress.org-Verzeichnis, f\u00fcr Playground CLI und wp-env lokal sowie f\u00fcr eine CI-Matrix \u00fcber WP- und PHP-Versionen.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/wordpress-plugins-tricks-de\\\/tutorials-de-wordpress-plugins-tricks-de\\\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/wordpress-plugins-tricks-de\\\/tutorials-de-wordpress-plugins-tricks-de\\\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/wordpress-plugins-tricks-de\\\/tutorials-de-wordpress-plugins-tricks-de\\\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/fi-20879-playground-blueprints-plugin-vorschau-tests.png\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/fi-20879-playground-blueprints-plugin-vorschau-tests.png\",\"width\":1200,\"height\":630,\"caption\":\"WordPress Playground: Blueprints f\u00fcr Plugin-Vorschau und Tests\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/wordpress-plugins-tricks-de\\\/tutorials-de-wordpress-plugins-tricks-de\\\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"WordPress Playground: Blueprints f\u00fcr Plugin-Vorschau und Tests\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\",\"name\":\"Lukas Wojcik - Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\",\"name\":\"Lukas Wojcik\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"width\":424,\"height\":636,\"caption\":\"Lukas Wojcik\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\"},\"sameAs\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"WordPress Playground: Blueprints f\u00fcr Plugin-Vorschau und Tests | Lukas Wojcik","description":"Ein Blueprint f\u00fcr die Live-Vorschau im WordPress.org-Verzeichnis, f\u00fcr Playground CLI und wp-env lokal sowie f\u00fcr eine CI-Matrix \u00fcber WP- und PHP-Versionen.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.lukaswojcik.com\/blog\/de\/wordpress-plugins-tricks-de\/tutorials-de-wordpress-plugins-tricks-de\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\/","og_locale":"en_US","og_type":"article","og_title":"WordPress Playground: Blueprints f\u00fcr Plugin-Vorschau und Tests | Lukas Wojcik","og_description":"Ein Blueprint f\u00fcr die Live-Vorschau im WordPress.org-Verzeichnis, f\u00fcr Playground CLI und wp-env lokal sowie f\u00fcr eine CI-Matrix \u00fcber WP- und PHP-Versionen.","og_url":"https:\/\/www.lukaswojcik.com\/blog\/de\/wordpress-plugins-tricks-de\/tutorials-de-wordpress-plugins-tricks-de\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\/","og_site_name":"Lukas Wojcik - Blog","article_published_time":"2026-10-27T14:09:00+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/fi-20879-playground-blueprints-plugin-vorschau-tests.png","type":"image\/png"}],"author":"Lukas Wojcik","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Lukas Wojcik","Est. reading time":"15 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/wordpress-plugins-tricks-de\/tutorials-de-wordpress-plugins-tricks-de\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\/#article","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/wordpress-plugins-tricks-de\/tutorials-de-wordpress-plugins-tricks-de\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\/"},"author":{"name":"Lukas Wojcik","@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"headline":"WordPress Playground: Blueprints f\u00fcr Plugin-Vorschau und Tests","datePublished":"2026-10-27T14:09:00+00:00","mainEntityOfPage":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/wordpress-plugins-tricks-de\/tutorials-de-wordpress-plugins-tricks-de\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\/"},"wordCount":2252,"commentCount":0,"publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"image":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/wordpress-plugins-tricks-de\/tutorials-de-wordpress-plugins-tricks-de\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\/#primaryimage"},"thumbnailUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/fi-20879-playground-blueprints-plugin-vorschau-tests.png","keywords":["DevOps","Tutorial","Web Development","WordPress"],"articleSection":["Tutorials"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.lukaswojcik.com\/blog\/de\/wordpress-plugins-tricks-de\/tutorials-de-wordpress-plugins-tricks-de\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/wordpress-plugins-tricks-de\/tutorials-de-wordpress-plugins-tricks-de\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\/","url":"https:\/\/www.lukaswojcik.com\/blog\/de\/wordpress-plugins-tricks-de\/tutorials-de-wordpress-plugins-tricks-de\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\/","name":"WordPress Playground: Blueprints f\u00fcr Plugin-Vorschau und Tests | Lukas Wojcik","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/wordpress-plugins-tricks-de\/tutorials-de-wordpress-plugins-tricks-de\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\/#primaryimage"},"image":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/wordpress-plugins-tricks-de\/tutorials-de-wordpress-plugins-tricks-de\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\/#primaryimage"},"thumbnailUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/fi-20879-playground-blueprints-plugin-vorschau-tests.png","datePublished":"2026-10-27T14:09:00+00:00","description":"Ein Blueprint f\u00fcr die Live-Vorschau im WordPress.org-Verzeichnis, f\u00fcr Playground CLI und wp-env lokal sowie f\u00fcr eine CI-Matrix \u00fcber WP- und PHP-Versionen.","breadcrumb":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/wordpress-plugins-tricks-de\/tutorials-de-wordpress-plugins-tricks-de\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.lukaswojcik.com\/blog\/de\/wordpress-plugins-tricks-de\/tutorials-de-wordpress-plugins-tricks-de\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/wordpress-plugins-tricks-de\/tutorials-de-wordpress-plugins-tricks-de\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\/#primaryimage","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/fi-20879-playground-blueprints-plugin-vorschau-tests.png","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/fi-20879-playground-blueprints-plugin-vorschau-tests.png","width":1200,"height":630,"caption":"WordPress Playground: Blueprints f\u00fcr Plugin-Vorschau und Tests"},{"@type":"BreadcrumbList","@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/wordpress-plugins-tricks-de\/tutorials-de-wordpress-plugins-tricks-de\/wordpress-playground-blueprints-fur-plugin-vorschau-und-tests\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.lukaswojcik.com\/blog\/"},{"@type":"ListItem","position":2,"name":"WordPress Playground: Blueprints f\u00fcr Plugin-Vorschau und Tests"}]},{"@type":"WebSite","@id":"https:\/\/www.lukaswojcik.com\/blog\/#website","url":"https:\/\/www.lukaswojcik.com\/blog\/","name":"Lukas Wojcik - Blog","description":"","publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.lukaswojcik.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9","name":"Lukas Wojcik","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","width":424,"height":636,"caption":"Lukas Wojcik"},"logo":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg"},"sameAs":["https:\/\/www.lukaswojcik.com\/blog"]}]}},"_links":{"self":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts\/20879","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/comments?post=20879"}],"version-history":[{"count":3,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts\/20879\/revisions"}],"predecessor-version":[{"id":25944,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts\/20879\/revisions\/25944"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media\/20937"}],"wp:attachment":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media?parent=20879"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/categories?post=20879"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/tags?post=20879"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}