Benutzerdefinierte Blöcke nur mit PHP erstellen. Tschüss alte Shortcodes 🥳
Gutenberg-Blöcke zu erstellen hat seit WordPress 5.0 React, Node.js und eine Build-Pipeline bedeutet. Wenn deine Stärken in PHP liegen – wie bei mir und der Mehrheit der WordPress-Entwickler –, hat diese Hürde dich fast ein Jahrzehnt lang ausgebremst. WordPress 7.0 ändert das. PHP-only Blocks ermöglichen es dir, einen vollständig funktionsfähigen Gutenberg-Block mit einer einzigen PHP-Datei und dem Flag autoRegister zu registrieren.
Du schreibst PHP. Du bekommst einen Block. Kein Tooling. Kein Build. 🥳 In diesem Artikel siehst du, wie PHP-only Blocks funktionieren, und gehst ein praxisnahes Beispiel durch, das einen klassischen Shortcode durch sein Block-Äquivalent ersetzt.
Was sind PHP-only Blocks?
Bisher bedeutete das Erstellen eines benutzerdefinierten Gutenberg-Blocks das Einrichten einer JavaScript-Toolchain: npm install, eine block.json-Datei, einen Build-Schritt mit webpack.config.js oder @wordpress/scripts und eine edit.js-Komponente in JSX. Jede Änderung erforderte einen Compile-Schritt, bevor du sie im Editor sehen konntest. Für einen PHP-Entwickler, der einfach nur einen simplen Anzeigeblock registrieren möchte, fühlte sich dieser Aufwand immer unverhältnismäßig zur eigentlichen Aufgabe an.
PHP-only Blocks schneiden durch all das durch. Jetzt musst du in register_block_type() nur 'autoRegister' => true übergeben, und WordPress kümmert sich mit ServerSideRender automatisch um alles auf der JavaScript-Seite. Der Block erscheint im Inserter, zeigt eine Live-Vorschau auf der Canvas und generiert Inspector Controls in der Seitenleiste – alles ohne eine einzige Zeile JavaScript von dir.
Die Controls werden automatisch basierend auf dem Attributtyp generiert:
| Attributtyp | Generiertes Inspector Control |
|---|---|
string | Texteingabe |
integer / number | Zahleneingabe |
boolean | Toggle |
string + enum | Dropdown-Auswahl |
Automatisch generierte Controls decken vorerst nur die vier oben genannten Typen ab. Alles Komplexere wie Bild-Picker, Medien-Uploads oder verschachtelte Daten wird noch nicht unterstützt und würde einen per JavaScript registrierten Block erfordern. Entwickler können einzelne Attribute auch mit einer local-Rolle markieren, um sie als internen Zustand zu kennzeichnen; WordPress überspringt diese beim Aufbau der Seitenleisten-Controls.
PHP-only Blocks sind heute in WordPress 7.0 ohne zusätzliche Abhängigkeiten verfügbar. Lies mehr in der offiziellen Dev-Note auf Make WordPress Core.
Für wen ist das gedacht?
Kleinere Agenturen und Freelancer ohne tiefgreifende JavaScript-Kenntnisse können jetzt Block-Editor-Lösungen entwickeln, die die nativen WordPress-Funktionen vollständig nutzen, ohne eine Build-Pipeline anzufassen. Wenn du themenspezifische benutzerdefinierte Gutenberg-Blöcke wie Autoren-Boxen, Pull-Quotes, Testimonials, CTA-Banner, Hinweise und ähnliche Elemente liefern möchtest, anstatt auf Shortcodes zurückzugreifen, helfen PHP-only Blocks dabei, diese Hürde deutlich zu senken.
Sie sind kein Ersatz für per JavaScript registrierte Blöcke, wenn du In-Canvas-Rich-Text-Bearbeitung, eine reaktive Echtzeit-UI oder verschachtelte Inner Blocks benötigst – aber für eine große Klasse strukturierter Anzeigeblöcke treffen sie genau den richtigen Punkt.
Die alte Methode: Shortcodes
Vor PHP-only Blocks war der praktische PHP-Entwickler-Ansatz ein Shortcode. Hier ist ein einfacher Testimonial-Shortcode mit drei Attributen: Autorname, Unternehmen, Sternebewertung, plus Innerem Inhalt für den Rezensionstext:
function testimonial_shortcode( $atts, $content = '' ) {
$atts = shortcode_atts( [
'name' => '',
'company' => '',
'stars' => 5,
], $atts );
$stars_count = max( 1, min( 5, intval( $atts['stars'] ) ) );
$stars_html = str_repeat( '★', $stars_count )
. str_repeat( '☆', 5 - $stars_count );
return sprintf(
'<blockquote class="testimonial">
<p class="testimonial__stars">%s</p>
<p class="testimonial__body">%s</p>
<footer class="testimonial__attribution">
<strong>%s</strong>%s
</footer>
</blockquote>',
esc_html( $stars_html ),
wp_kses_post( $content ),
esc_html( $atts['name'] ),
$atts['company'] ? ', ' . esc_html( $atts['company'] ) : ''
);
}
add_shortcode( 'testimonial', 'testimonial_shortcode' );Verwendung:
[testimonial name="Sarah K." company="Acme Corp" stars="4"]
Saved us hours every week.
[/testimonial]Es funktioniert ... aber es ist nur ein Shortcode 🤷🏻♂️
Hier sind nur einige der Probleme mit Shortcodes:
- Im Editor unsichtbar. Der Autor sieht
[testimonial name="Sarah K." ...]im Editor, nicht die gerenderte Karte. Es gibt keine Vorschau. - Nicht auffindbar. Du musst wissen, dass der Shortcode existiert, und dir seine Parameternamen merken. Nichts zeigt ihn in der UI an.
- Keine nativen Stil-Controls. Das Anpassen von Farbe, Abstand oder Typografie erfordert benutzerdefiniertes CSS oder manuell verdrahtete zusätzliche Attribute.
- Der innere Inhalt ist kein Rich Text. Der Rezensionstext wird als einfacher String in
$contentübergeben – kein bearbeitbarer Rich-Text-Bereich.
Shortcodes waren das richtige Werkzeug für ihre Zeit. Der Block-Editor bietet etwas Besseres, war aber schwer zu nutzen. WordPress 7.0 bietet mit PHP-only Blocks eine Abkürzung.
Um es klar zu sagen: Der richtige neue Weg, einen Gutenberg-Block zu erstellen, ist nach wie vor ein per JavaScript registrierter Block mit einer vollständigen edit-Komponente. PHP-only Blocks sind ein vereinfachter Weg – bewusst auf serverseitig gerenderte Blöcke beschränkt, die keine Rich-In-Canvas-Bearbeitung benötigen. Sie sind kein Ersatz für JavaScript-Blöcke, sondern eine neue Option für einfachere Anwendungsfälle, bei denen der Aufwand einer Build-Pipeline und React-Komponenten nicht gerechtfertigt ist.
Eine einfachere Option: PHP-only Blocks
Lass uns dasselbe Testimonial als benutzerdefinierten WordPress-Block nur mit PHP bauen. Das Rezept: register_block_type() mit 'autoRegister' => true in supports, plus einem render_callback.
Hier ist der vollständige Code für den Block:
function my_plugin_register_testimonial_block() {
register_block_type(
'my-plugin/testimonial', // Block name: namespace/slug
array(
'title' => 'Testimonial', // Shown in the block inserter
'attributes' => array(
// string attributes generate a text input in the sidebar
'name' => array(
'type' => 'string',
'default' => '',
),
'company' => array(
'type' => 'string',
'default' => '',
),
// integer attributes generate a number input
'stars' => array(
'type' => 'integer',
'default' => 5,
),
'body' => array(
'type' => 'string',
'default' => '',
),
),
// render_callback is the PHP function that outputs the block's HTML
'render_callback' => function ( $attributes ) {
$stars_count = max( 1, min( 5, intval( $attributes['stars'] ) ) );
$stars_html = str_repeat( '★', $stars_count )
. str_repeat( '☆', 5 - $stars_count );
// Translatable string for screen readers — standard WordPress i18n, nothing extra needed
/* translators: %d: star rating out of 5 */
$stars_label = sprintf( __( '%d out of 5 stars', 'my-plugin' ), $stars_count );
return sprintf(
'<blockquote %s>
<p class="testimonial__stars" aria-label="%s">%s</p>
<p class="testimonial__body">%s</p>
<cite class="testimonial__attribution">
<strong>%s</strong>%s
</cite>
</blockquote>',
// Merges your class with editor-added colour, spacing, and typography styles
get_block_wrapper_attributes( array( 'class' => 'testimonial wp-block-quote' ) ),
esc_attr( $stars_label ),
esc_html( $stars_html ),
wp_kses_post( $attributes['body'] ),
esc_html( $attributes['name'] ),
$attributes['company'] ? ', ' . esc_html( $attributes['company'] ) : ''
);
},
'supports' => array(
// The key flag — tells WordPress to handle JS registration automatically
'autoRegister' => true,
// The rest unlock native colour, typography, and spacing panels in the sidebar
'color' => array(
'background' => true,
'text' => true,
),
'typography' => array(
'fontSize' => true,
),
'spacing' => array(
'padding' => true,
'margin' => true,
),
),
)
);
}
add_action( 'init', 'my_plugin_register_testimonial_block' );Das Ergebnis:

Ein paar Dinge sind hier zu beachten. Erstens hat der innere Inhalt eines Shortcodes kein direktes Äquivalent in PHP-only Blocks. Der Rezensionstext wird zu einem string-Attribut, das über die Inspector Controls in der Seitenleiste bearbeitet wird – ein einzeiliges Textfeld, kein In-Canvas-Rich-Text-Bereich. Für ein kurzes Testimonial-Zitat ist das in Ordnung. Für längere Texte würdest du einen per JavaScript registrierten Block mit einer RichText-Komponente bevorzugen.
Zweitens kombiniert get_block_wrapper_attributes() deine Klasse mit allem, was der Editor für Farbe, Typografie und Abstand hinzufügt – so funktionieren die nativen Stil-Panels ohne zusätzliche CSS-Verdrahtung. Der render_callback erhält ein $attributes-Array, das nur die vom Benutzer gesetzten Werte enthält; kein $content-Parameter, da innerer Inhalt nicht unterstützt wird.
Was du gegenüber der Shortcode-Version gewinnst:
- Live-Vorschau auf der Editor-Canvas. Keine rohe Shortcode-Syntax mehr – der Autor sieht die gerenderte Testimonial-Karte während er bearbeitet.
- Automatisch generierte Controls. Name, Unternehmen, Text (Texteingaben) und Sterne (Zahleneingabe) erscheinen automatisch in den Inspector Controls der Seitenleiste.
- Native Farb-, Schrift- und Abstand-Panels. Kommt von
supports– kein benutzerdefiniertes CSS nötig. - Auffindbar. Der Block erscheint im Inserter unter seinem Namen, mit einem Icon.
Von Anfang an übersetzungsbereit
Es gibt zwei unterschiedliche Übersetzungsaspekte bei der Arbeit mit PHP-only Blocks, und es lohnt sich, beide klar zu unterscheiden.
Der erste betrifft statische Strings, die in dein PHP-Template eingebaut sind – Labels, Button-Texte, UI-Copy. Diese werden von __() und _e() behandelt, genau wie in jeder anderen WordPress-PHP-Datei. Im obigen Block ist das Stars-Label ein Beispiel dafür:
/* translators: %d: star rating out of 5 */
$stars_label = sprintf( __( '%d out of 5 stars', 'my-plugin' ), $stars_count );Standard-WordPress-Werkzeuge erkennen diese automatisch. Nichts Zusätzliches nötig.
Der zweite Aspekt betrifft vom Benutzer eingegebene Inhalte, die als Block-Attribute gespeichert sind – der Testimonial-Text, der Name des Rezensenten, das Unternehmen. Das ist der Inhalt, den deine Redakteure tatsächlich in den Block eintippen, und __() berührt ihn nicht. Auf einer mehrsprachigen Website müssen diese Attributwerte separat in jede Sprache übersetzt werden, und das ist nichts, was WordPress von sich aus erledigt.
Gato AI Translations for Polylang unterstützt PHP-only Blocks von Anfang an, genauso wie es Gutenberg, Bricks, Elementor und andere Page Builder unterstützt. Es ist keine zusätzliche Einrichtung erforderlich.
Alle String-Attribute werden automatisch für die Übersetzung registriert. Wenn ein bestimmtes Feld nicht übersetzt werden soll – eine interne Referenz, eine URL, ein numerischer Code, der als String gespeichert ist –, kannst du es mit einem Filter ausschließen.
Für den Testimonial-Block in diesem Artikel werden Rezensenten-Name, Unternehmen und Textkörper alle automatisch übersetzt – keine Konfiguration außer der Plugin-Installation.
Was PHP-only Blocks (noch) nicht können
Die aktuellen Einschränkungen von PHP-only Blocks:
- Keine Inner Blocks oder Verschachtelung. Du kannst keine anderen Blöcke in einen PHP-only Block einfügen.
- Keine In-Canvas-Rich-Text-Bearbeitung. Die
RichText-Komponente erfordert JavaScript. Text-Controls werden nur als Seitenleisten-Textfeld gerendert. - Seitenleisten-String-Felder sind einzeilig. Ein
string-Attribut wird zu einemTextControl, nicht zu einemTextareaControl– nicht ideal für längere Texte. - Keine Bild- oder Medien-Picker-Attribute. Unterstützung für Bild-/Datei-Uploads ist für eine spätere Version über die Block Fields API geplant.
- Die Editor-Vorschau hat eine Round-Trip-Verzögerung. Attributänderungen lösen eine REST-API-Anfrage aus, um serverseitig neu zu rendern, daher aktualisiert sich die Vorschau nicht sofort.
Für einfache strukturierte Blöcke – Testimonials, CTAs, Hinweise, Autoren-Biografien, Unternehmenslistings – treffen PHP-only Blocks genau den richtigen Punkt. Für alles, was Rich-In-Canvas-Bearbeitung erfordert, bleibt die JavaScript-Registrierung das richtige Werkzeug.
Was kommt als Nächstes
WordPress 7.0s PHP-only Blocks bringen die Block-Entwicklung in Reichweite jedes PHP-Entwicklers. Eine PHP-Datei, ein register_block_type()-Aufruf, und du hast einen vollständig funktionsfähigen Gutenberg-Block mit Seitenleisten-Controls, einer Live-Canvas-Vorschau und nativem Stil-Support. Du schreibst PHP. Du bekommst einen Block. Kein Tooling. Kein Build. Kein JavaScript.
Wenn du mehrsprachige Websites erstellst, funktioniert Gato AI Translations nahtlos mit PHP-only Blocks – dein Inhalt ist von Tag eins an übersetzbar.
Bereit für mehr?
- Developing WordPress blocks without JSX or a build process — für Entwickler, die minimales JavaScript ohne eine vollständige Build-Pipeline hinzufügen möchten
- Beginner WordPress Developer course — eine vollständige Grundlage für die Block-Entwicklung