Wie wäre es mit einer kleinen Berlin-Karte, auf der man ein paar Punkte setzen kann, etwa für Filialen eines Unternehmens?
Beim WP-Meetup am 17. Juni 2026 in Berlin konnte ich die Umsetzungen mit relativ simplen Mitteln vorführen und schließe nun diesen Blogbeitrag nochmal an.
Teil 1: Grundlagen anhand des WP-Beispielblocks erlernen
Dieser Teil folgt in großen Teilen diesem Tutorial, das ich aber für meinen Vortrag etwas einsteigerfreundlicher und auf deutsch anpasste.
Teil 2: Die eigenen Blocks – Berlin-Karte und Punkte (ab 6.7.2026)
Bist du bereit, loszulegen?
Die Welt der Gutenberg-Blocks
Wie in einem Baukasten können WP-Nutzer*innen seit Winter 2018 ihre Seiten zusammenbasteln. Wenn sie im Editor einfach darauf lostippen, bekommen sie nicht viel mit 🙂 , aber sobald sie die linke „Schublade“ öffnen sehen sie eine riesige Auswahl an Möglichkeiten:

Warum sollte ich einen Gutenberg-Block selbst entwickeln?
- Eine Sonderlösung für mich oder meinen Kunden steht an
- Datensparksamkeit (i.d.R. kein Datentransfer ins Ausland + keine Cookies nötig)
- Unabhängigkeit von jedwedem Pagebuilder bzw. Verzicht und Nutzung des nativen Gutenberg-Editors
- Performance – die Kompatibilität mit gängigen WordPress-Optimierungs-Plugins wie Autoptimize und WP Rocket ist quasi selbstverständlich
- Freude am Programmieren. Und übrigens ein guter Effekt auf die persönliche Lernkurve, wenn man sich sowieso mal mit React befassen wollte..
- Perfekte Dokumentation von den WordPress-Core-Entwicklern
Die Entwicklungs- Umgebung
…wählt man am besten selbst. Insbesondere für Windows und macOS gibt es viele fensterbasierte Lösungen wie bspw. MAMP, XAMPP und Local WP.
Für Linux- und Kommandozeilen-Fans empfehle ich hier nochmal einen Blick auf meinen vorigen Beitrag.
NodeJS installieren
Du hast nun also für eine Entwicklungsumgebung für Webanwendungen (s.o.) entschieden. Weiter geht es mit der Installation von NodeJS. NodeJS führt JavaScript außerhalb des Browsers aus – in unserem Falle zur Herstellung des Blocks während dessen Bearbeitung im Code-Editor deiner Wahl.
Anleitungen zur NodeJS-Installation:
Windows | macOS | Ubuntu Linux; sollte auch in Debian funktionieren
Den Demo-Block installieren
Öffne nun einen Code-Editor deiner Wahl. Ich habe mich für diesen Post für VSCodium entschieden. Wichtig wäre, dass er ordner- bzw. projektbezogen arbeiten kann, und nicht nur jede Datei einzeln betrachtet. Die eingebauten Texteditoren von Windows und macOS sind damit „raus“.
Lege einen neuen Ordner in dem WordPress-Plugin-Verzeichnis d.h. /wp-content/plugins auf deinem Computer an und öffne ihn in bspw. in VSCodium:

Vertraue dem Ordner, falls eine entsprechende Abfrage erscheint.
Drücke nun Strg + J bzw. Cmd + J, um unten ein Panel mit einem Terminal zu öffnen:

Führe nacheinander diese Befehle aus (und gedulde dich bitte etwas):
npx @wordpress/create-block@latest copyright-date-block —variant=dynamic
cd copyright-date-block
npm startWarum eigentlich -variant=dynamic ? Im Beispiel der WordPress-Entwickler wird eine Jahreszahl ausgegeben, und diese möchte man nicht fest in der Datenbank des Servers unterbringen, sondern regelmäßig neu generieren lassen. Mindestens 1mal pro Jahr!
Der Blick in den Dateibaum

Im Dateibaum deines Editors siehst du nun die verschiedenen Bestandteile des Beispiel-Blocks. Wir als Entwickler*innen arbeiten nahezu ausschließlich mit dem src-Ordner. Der Build-Ordner ist für den Einsatz in produktiven Webumgebungen, also etwa auf der Website deines Kunden, bestimmt. Die ständige Übertragung der src-Eingaben hin zum Build-Ordner hast du vorhin mit dem npm start-Befehl initiiert.
Blick in die block.json
Blick in die Datei:
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "create-block/copyright-date-block",
"version": "0.1.0",
"title": "Copyright Date Block",
"category": "widgets",
"icon": "smiley",
"description": "Example block scaffolded with Create Block tool.",
"example": {},
"supports": {
"html": false
},
"textdomain": "copyright-date-block",
"editorScript": "file:./index.js",
"editorStyle": "file:./index.css",
"style": "file:./style-index.css",
"render": "file:./render.php",
"viewScript": "file:./view.js"
}Ein Smiley-grinst dich an, sowie wir du Block über die linke Seitenleiste in den Editor einfügen willst. In der Datei oben ist er bei icon hinterlegt worden. Ein anderes Symbol könntest du dir über diesen Link aussuchen:
https://developer.wordpress.org/resource/dashicons/
Die description wiederum beschreibt den Zweck des Blocks, u.a. vor dem Einfügen beim Berühren mit dem Mauszeiger.
Nun ein Blick auf den Abschnitt „supports“
"supports": {
"html": false
},Okay, der/die Autor*in soll also nichts am HTML-Markup ändern können. Allerdings hätten wir gerne eine mögliche Änderung der Schriftfarbe und der Schriftgröße.
Ändere den Abschnitt also so:
"supports": {
"color": {
"background": false,
"text": true
},
"html": false,
"typography": {
"fontSize": true
}
},Schaue nun im in der rechten Seitenleiste in WP nach, was im Block nun gemacht werden darf:

Aah, andere Textfarben und Schriftgrößen sind nun möglich!
Blick in die edit.js
Die edit.js bestimmt, wie der unser Block im WordPress-Backend dargestellt wird
Schauen wir mal rein:
export default function Edit() {
return (
{ __( 'Copyright Date Block – hello from the editor!', 'copyright-date-block-demo' ) }
);
}Hier wird also nur ein Text dargestellt, der uns mit Hallo begrüßt. Dahinter folgt die Textdomain copyright-date-block-demo; das macht den Text leicht auf Deutsch übersetzbar
Wenn wir allerdings nur schnell ein Jahr ausgeben möchten, gibt es keinen Grund, in eine andere Sprache zu übersetzen 😉
Füge das ein:
export default function Edit() {
const currentYear = new Date().getFullYear().toString();
return (
<p { ...useBlockProps() }>© { currentYear }</p>
);
}.. und im Browser sehen wir nach einem Neuladen der Seite nun

Blick in die render.php
Es fehlt nun das ganze noch im Frontend; im öffentlichen teil deines Blog. Hier kommt immer noch der Hallo-Spruch von oben.
Deswegen ändern wir hier
<p <?php echo get_block_wrapper_attributes(); ?>>
<?php esc_html_e( 'Copyright Date Block
– hello from a dynamic block!', 'copyright-date-block' ); ?>
</p>zu dem hier:
<p <?php echo get_block_wrapper_attributes(); ?>>© <?php echo date( "Y" ); ?></p>Bemerke folgenden Unterschied zur edit.js: Hier wird das Jahr tatsächlich nicht in deinem Browser per Javascript, sondern auf deinem lokalen Webserver berechnet.
Bitte noch das Anfangsjahr !

Um ein Anfangsjahr hinzufügen zu können, müssen wir im rechten Panel von WordPress ein Eingabefeld und natürlich etwas Logik ergänzen.
Zurück zum Abschnitt supports in der block.json. Bislang sieht sie so aus:
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "create-block/copyright-date-block",
"version": "0.1.0",
"title": "Copyright Date Block",
"category": "widgets",
"description": "Display your site's copyright date.",
"example": {},
"supports": {
"color": {
"background": false,
"text": true
},
"html": false,
"typography": {
"fontSize": true
}
},
"textdomain": "copyright-date-block",
"editorScript": "file:./index.js",
"render": "file:./render.php"
}Ergänze ihn um einen Anfangsjahr-Einschalter und das Startjahr:
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "create-block/copyright-date-block",
"version": "0.1.0",
"title": "Copyright Date Block",
"category": "widgets",
"description": "Display your site's copyright date.",
"example": {},
"supports": {
"color": {
"background": false,
"text": true
},
"html": false,
"typography": {
"fontSize": true
}
},
"textdomain": "copyright-date-block",
"editorScript": "file:./index.js",
"render": "file:./render.php",
"attributes": {
"showStartingYear": {
"type": "boolean"
},
"startingYear": {
"type": "string"
}
},
}In der edit.js benötigen wir eine Anpassung der rechten Seitenleiste:
import { useBlockProps } from '@wordpress/block-editor';ganz oben wird ersetzt durch
import { PanelBody, TextControl, ToggleControl }
from '@wordpress/components';und die export-Funktion, die bislang so aussieht:
export default function Edit() {
const currentYear = new Date().getFullYear().toString();
return (
<p { ...useBlockProps() }>© { currentYear }</p>
);
}änderst du so:
export default function Edit() {
const currentYear = new Date().getFullYear().toString();
return (
<>
<InspectorControls>
Testing
</InspectorControls>
<p { ...useBlockProps() }>© { currentYear }</p>
</>
);
}Ggf. ungewohnt ist für dich die Kurschreibeweise eines unsichtbaren React Wrappers, also <> . Einerseits müssen wir und innerhalb von return hier in einem Container verwenden, andererseits ist dieser nur logisch zu betrachten. Ein <div>…</div> lohnt sich demnach nicht.
Nun, wie sieht’s in WordPress jetzt aus ?

Gratulation ! Du hast nun gelernt, die Blockeigenschaften im rechten Panel zu überschrieben!
Das Textfeld für das Anfangsjahr
Diese Neuerung ist aber noch nicht im mittleren Editor-Teil angekommen. Passe das bisherige JavaScript in der edit.js
export default function Edit() {
const currentYear = new Date().getFullYear().toString();nun bitte so an:
export default function Edit( { attributes, setAttributes } ) {
const { showStartingYear, startingYear } = attributes;
const currentYear = new Date().getFullYear().toString();Widme dich anschließend wieder dem return-Abschnitt. Jetzt sieht er so aus
export default function Edit() {
const currentYear = new Date().getFullYear().toString();
return (
<>
<InspectorControls>
Testing
</InspectorControls>
<p { ...useBlockProps() }>© { currentYear }</p>
</>
);
}Ändere ihn so:
return (
<>
<InspectorControls>
<PanelBody title={ __( 'Settings', 'copyright-date-block' ) }>
<TextControl
__next40pxDefaultSize
label={ __(
'Starting year',
'copyright-date-block'
) }
value={ startingYear || '' }
onChange={ ( value ) =>
setAttributes( { startingYear: value } )
}
/>
</PanelBody>
</InspectorControls>
<p { ...useBlockProps() }>© { currentYear }</p>
</>
);Ist dir das Oder-Zeichen || aufgefallen ? An dieser Stelle verhindert man praktisch nur Warnungen von Seiten von React in den Entwicklertools des Browsers. WordPress soll sich also über deinen Block nicht beschweren, falls du dich gegen ein Anfangsjahr entscheidest.
Nun, wie sieht das rechte Panel in WP jetzt aus ?

Unser Textfeld ist da!
Der Schiebeschalter für das Anfangsjahr
Wir möchten ja noch einen Schiebeschalter, der über das Verwenden eines Startjahres bestimmt. Wenn er ausgeschaltet ist, soll das Textfeld für das Startjahr erst gar nicht erscheinen.
Passe PanelBody in der edit.js an. Bisher ist ja das der Code:
<PanelBody title={ __( 'Settings', 'copyright-date-block' ) }>
<TextControl
__next40pxDefaultSize
label={ __(
'Starting year',
'copyright-date-block'
) }
value={ startingYear || '' }
onChange={ ( value ) =>
setAttributes( { startingYear: value } )
}
/>
</PanelBody>Passe ihn jetzt so an:
<PanelBody title={ __( 'Settings', 'copyright-date-block' ) }>
<ToggleControl
checked={ !! showStartingYear }
label={ __(
'Show starting year',
'copyright-date-block'
) }
onChange={ () =>
setAttributes( {
showStartingYear: ! showStartingYear,
} )
}
/>
{ showStartingYear && (
<TextControl
__next40pxDefaultSize
label={ __(
'Starting year',
'copyright-date-block'
) }
value={ startingYear || '' }
onChange={ ( value ) =>
setAttributes( { startingYear: value } )
}
/>
) }
</PanelBody>Die Zeile checked={ !! showStartingYear } bestimmt, dass der Abschnitt showStartingYear nur bei eingeschaltetem Schalter angezeigt wird. Wir möchten showStartingYear also zu einem Boolean-Wert machen, d.h. soll er true oder false annehmen können – naturgemäß sehr passend zu einem Ein-/Aus-Schalter.

Jetzt sehen wir das Eingabefeld für das Startjahr tatsächlich nur bei aktiviertem Schalter!
Das Anfangsjahr im WP-Editorbereich
Bis jetzt passiert mittig beim eigentlichen Block noch nichts; die passende Logik muss ergänzt werden.
Schreibe vor den return-Block in der edit.js nun diese Zeilen:
let displayDate;
if ( showStartingYear && startingYear ) {
displayDate = startingYear + '–' + currentYear;
} else {
displayDate = currentYear;
}und unten, direkt nach </InspectorControls> schreibst du diese Zeile
<p { ...useBlockProps() }>© { currentYear }</p>folgendermaßen um:
<p { ...useBlockProps() }>© { displayDate }</p>Schön, dass es praktisch im Backend geht, aber …

Die letzten Schritte: Rendern im Frontend und das Startdatum in der Datenbank speichern
Nun müssen wir die render.php sehr abändern, und zwar von
<p <?php echo get_block_wrapper_attributes(); ?>>© <?php echo date( "Y" ); ?></p>zu
<?php
$current_year = date( "Y" );
if ( ! empty( $attributes['startingYear'] ) && ! empty( $attributes['showStartingYear'] ) ) {
$display_date = $attributes['startingYear'] . '–' . $current_year;
} else {
$display_date = $current_year;
}
?>
<p <?php echo get_block_wrapper_attributes(); ?>>
© <?php echo esc_html( $display_date ); ?>
</p>Die vorige Logik, die das Startjahr im Falle eines Definierens im Backend anzeigt (oder eben nicht), wird hier erneuert in PHP übertragen.
Ein Novum ist jetzt weiterhin, dass wir zum ersten Mal eine save.js anlegen müssen – das Startjahr muss in die Datenbank gelangen.
Zuvor jetzt erstmal ein Blick in die index.js:
import Edit from "./edit";
import metadata from "./block.json";
registerBlockType(metadata.name, {
edit: Edit,
});Hier wird der Import der Save-Funktion nun ergänzt:
import Edit from "./edit";
import metadata from "./block.json";
import save from "./save";
registerBlockType(metadata.name, {
edit: Edit,
save
});Nun also diesen Code in die save.js einfügen. Lege sie im src-Ordner an, wenn du sie noch vermisst.
import { useBlockProps } from '@wordpress/block-editor';
export default function save( { attributes } ) {
const { showStartingYear, startingYear } = attributes;
const currentYear = new Date().getFullYear().toString();
let displayDate;
if ( showStartingYear && startingYear ) {
displayDate = startingYear + '–' + currentYear;
} else {
displayDate = currentYear;
}
return (
<p { ...useBlockProps.save() }>© { displayDate }</p>
);
}Kurzer Test mit Entwicklertools im Browser – klappt es jetzt ?

Oje, das sieht noch nicht gut aus .. Wir müssen neben der index.js auch die block.json mit den Attributen ergänzen:
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "create-block/copyright-date-block",
"version": "0.1.0",
"title": "Copyright Date Block",
"category": "widgets",
"icon": "smiley",
"description": "Example block scaffolded with Create Block tool.",
"example": {},
"supports": {
"color": {
"background": false,
"text": true
},
"html": false,
"typography": {
"fontSize": true
}
},
"textdomain": "copyright-date-block",
"editorScript": "file:./index.js",
"editorStyle": "file:./index.css",
"style": "file:./style-index.css",
"render": "file:./render.php",
"viewScript": "file:./view.js",
"attributes": {
"fallbackCurrentYear": {
"type": "string"
},
"showStartingYear": {
"type": "boolean"
},
"startingYear": {
"type": "string"
}
}
}
Endlich fertig! 🙂
Der Block funktioniert im Back- und Frontend.
Schreibe einen Kommentar