Block-Themes mit theme.json: Templates, Parts und Child-Theme

Management Summary
Ein Block-Theme gestaltet eine WordPress-Website mit Seitenvorlagen, wiederverwendbaren Bereichen sowie gemeinsamen Farben und Schriften. Ein Child-Theme bewahrt eigene Anpassungen getrennt vom ursprünglichen Design auf. Im Website-Editor gespeicherte Änderungen können jedoch Vorrang vor den passenden Dateien haben. Das erklärt, warum Dateiänderungen manchmal unsichtbar bleiben. Das Beispiel zeigt die Zusammenhänge, damit ein einheitliches Design gezielt angepasst werden kann und die wirksamen Einstellungen nachvollziehbar bleiben.
Inhalt
- Welche Dateien nötig sind
- Farben und Schriften mit theme.json festlegen
- Listen und vollständige Beiträge anzeigen
- Warum eine geänderte Datei manchmal nicht sichtbar wird
- Welche Vorlage gewinnt?
- Ein Child-Theme ergänzen
- Welche Einstellungen übernimmt das Child?
- Prüfgrenzen und praktische Gegenprobe
- Fragen und Antworten
- Quellen
Ein Block-Theme legt fest, wie eine WordPress-Website aussieht. Templates sind Vorlagen für ganze Seiten. Template Parts sind wiederverwendbare Teile wie Kopf- und Fußbereich. Die Datei theme.json bestimmt Farben, Schriften und weitere Gestaltungsmöglichkeiten.
Das Beispiel baut ein kleines Theme und anschließend ein Child-Theme, also eine Erweiterung des ursprünglichen Themes. Änderungen bleiben dadurch in einem eigenen Ordner. Im Mittelpunkt stehen drei Fragen: Welche Vorlage erscheint? Wo speichert der Website-Editor Änderungen? Welche Einstellungen übernimmt das Child-Theme? Die beschriebenen Abläufe beziehen sich auf WordPress 7.1; historische Tests liefen am 30.09.2026 mit Version 7.1.2.
Welche Dateien nötig sind
Ein eigenständiges Block-Theme benötigt style.css und templates/index.html. Die erste Datei enthält mindestens den Theme-Namen. Die zweite ist die Ersatzvorlage, falls keine passendere Vorlage existiert. Eine theme.json ist für die Erkennung nicht erforderlich, erleichtert aber die Gestaltung. Das folgende Starter-Theme ergänzt außerdem singular.html, damit einzelne Beiträge und Seiten den vollständigen Inhalt anzeigen.
lw-base/
├── style.css
├── theme.json
├── templates/
│ ├── index.html
│ └── singular.html
├── parts/
│ ├── header.html
│ └── footer.html
├── patterns/
│ └── footer-credits.php
└── styles/
└── night.jsonDer Kommentar am Anfang der style.css beschreibt das Theme. Zusätzliche Angaben sind unter anderem für eine Veröffentlichung im WordPress-Theme-Verzeichnis wichtig. Eigene CSS-Regeln sind hier nicht nötig, weil das Beispiel die Gestaltung über theme.json festlegt. Requires at least: 6.6 kennzeichnet die Mindestversion für das verwendete JSON-Format 3.
/*
Theme Name: LW Base
Theme URI: https://example.com/lw-base
Author: Lukas Wojcik
Author URI: https://lukaswojcik.com
Description: Minimal block theme with templates, template parts, a pattern and a style variation.
Version: 1.0.0
Requires at least: 6.6
Tested up to: 7.1
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: lw-base
*/Die Ordner haben feste Aufgaben: templates/ enthält ganze Seitenvorlagen, parts/ wiederverwendbare Seitenteile, patterns/ vorbereitete Blockgruppen und styles/ alternative Gestaltungen. Die älteren Ordnernamen block-templates/ und block-template-parts/ bleiben für ältere Themes unterstützt.
Farben und Schriften mit theme.json festlegen
settings legt fest, welche Farben, Schriftgrößen und Werkzeuge im Editor verfügbar sind. styles wendet konkrete Werte an. Das Beispiel bietet drei Farben an und verwendet die Farbe base als Hintergrund. slug ist dabei der kurze technische Name eines Eintrags, etwa accent für die Akzentfarbe.
Formatversion 3 gibt es seit WordPress 6.6. Damit eigene Schriftgrößen die Standardnamen small, medium und large verwenden können, steht defaultFontSizes auf false. Für eigene Abstandsgrößen gilt entsprechend defaultSpacingSizes. Ältere JSON-Formatversionen bleiben unterstützt.
$schema verweist auf die Beschreibung der erlaubten Eigenschaften. Schreibprogramme können damit Fehler anzeigen und Eingaben vervollständigen. Der Link für WordPress 7.1 passt zur hier beschriebenen Version; der Link mit trunk folgt dagegen der laufenden Entwicklung und kann neuere Funktionen enthalten.
{
"$schema": "https://schemas.wp.org/wp/7.1/theme.json",
"version": 3,
"settings": {
"appearanceTools": true,
"layout": {
"contentSize": "720px",
"wideSize": "1200px"
},
"color": {
"defaultPalette": false,
"palette": [
{ "slug": "base", "color": "#ffffff", "name": "Base" },
{ "slug": "contrast", "color": "#111827", "name": "Contrast" },
{ "slug": "accent", "color": "#0369a1", "name": "Accent" }
]
},
"typography": {
"defaultFontSizes": false,
"fontSizes": [
{ "slug": "small", "size": "0.875rem", "name": "Small" },
{ "slug": "medium", "size": "1rem", "name": "Medium" },
{ "slug": "large", "size": "1.5rem", "name": "Large" }
],
"fontFamilies": [
{
"slug": "system",
"name": "System",
"fontFamily": "-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif"
}
]
}
},
"styles": {
"color": {
"background": "var(--wp--preset--color--base)",
"text": "var(--wp--preset--color--contrast)"
},
"typography": {
"fontFamily": "var(--wp--preset--font-family--system)",
"fontSize": "var(--wp--preset--font-size--medium)",
"lineHeight": "1.6"
},
"spacing": {
"padding": { "top": "1.5rem", "right": "1.5rem", "bottom": "1.5rem", "left": "1.5rem" }
},
"elements": {
"link": {
"color": { "text": "var(--wp--preset--color--accent)" }
}
}
},
"templateParts": [
{ "name": "header", "title": "Header", "area": "header" },
{ "name": "footer", "title": "Footer", "area": "footer" }
]
}templateParts gibt Kopf- und Fußbereich einen Namen und einen Bereich. WordPress kennt header, footer und uncategorized, ab 7.0 zusätzlich navigation-overlay. Ohne eigenes tagName bestimmt der Bereich auch das umschließende HTML-Element.
Listen und vollständige Beiträge anzeigen
Die folgende templates/index.html zeigt Titel und Auszüge. Der Query-Loop-Block wiederholt diese Ausgabe für die gefundenen Beiträge. Mit "inherit":true übernimmt der Block die Auswahl der aufgerufenen Seite, beispielsweise Suchergebnisse oder Beiträge einer Kategorie.
<!-- wp:template-part {"slug":"header","tagName":"header"} /-->
<!-- wp:group {"tagName":"main","layout":{"type":"constrained"}} -->
<main class="wp-block-group">
<!-- wp:query {"queryId":1,"query":{"perPage":10,"pages":0,"offset":0,"postType":"post","order":"desc","orderBy":"date","inherit":true}} -->
<div class="wp-block-query">
<!-- wp:post-template -->
<!-- wp:post-title {"isLink":true} /-->
<!-- wp:post-excerpt /-->
<!-- /wp:post-template -->
<!-- wp:query-pagination -->
<!-- wp:query-pagination-previous /-->
<!-- wp:query-pagination-numbers /-->
<!-- wp:query-pagination-next /-->
<!-- /wp:query-pagination -->
</div>
<!-- /wp:query -->
</main>
<!-- /wp:group -->
<!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->Für einzelne Beiträge und Seiten ergänzt templates/singular.html den Block post-content. Dieser Block zeigt den vollständigen Inhalt. Ohne diese Zusatzvorlage würde die obige Ersatzvorlage auch dort nur Titel und Auszug ausgeben. Kommentare, eine besondere Fehlerseite und weitere Gestaltungen gehören nicht zu diesem kleinen Starter-Beispiel.
<!-- wp:template-part {"slug":"header","tagName":"header"} /-->
<!-- wp:group {"tagName":"main","layout":{"type":"constrained"}} -->
<main class="wp-block-group">
<!-- wp:post-title {"level":1} /-->
<!-- wp:post-content {"layout":{"type":"constrained"}} /-->
</main>
<!-- /wp:group -->
<!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->Die Seitenteile werden über den Namen header beziehungsweise footer eingebunden. Das Attribut theme fehlt bewusst: WordPress sucht dadurch beim aktiven Theme. Ein fest eingetragenes "theme":"lw-base" verhindert beim aktiven Child-Theme die normale Ausgabe dieses Seitenteils; bei eingeschalteter Debug-Ausgabe kann stattdessen ein Fehlerhinweis erscheinen.
<!-- wp:group {"layout":{"type":"flex","justifyContent":"space-between"}} -->
<div class="wp-block-group">
<!-- wp:site-title /-->
<!-- wp:navigation /-->
</div>
<!-- /wp:group --><!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group">
<!-- wp:pattern {"slug":"lw-base/footer-credits"} /-->
</div>
<!-- /wp:group -->Der Footer lädt ein Pattern, also eine vorbereitete Gruppe von Blöcken. WordPress registriert PHP-Dateien aus patterns/ automatisch, wenn der Dateikopf Title und Slug enthält. Die PHP-Funktion esc_html_e() ermöglicht hier eine Übersetzung des sichtbaren Texts mit der Text-Domain lw-base, der Kennung für die Theme-Übersetzungen.
/**
* Title: Footer credits
* Slug: lw-base/footer-credits
* Categories: footer
* Block Types: core/template-part/footer
* Description: Short credit line for the site footer.
*
* @package lw-base
*/
<!-- wp:paragraph {"fontSize":"small"} -->
<p class="has-small-font-size"> esc_html_e( 'Published with a block theme.', 'lw-base' ); </p>
<!-- /wp:paragraph -->Die Datei styles/night.json bietet eine dunkle Farbvariante an. Nach Auswahl und Speicherung im Website-Editor liegen die gewählten Werte als Anpassung in der Datenbank. Ein späteres Update der Datei ändert diese gespeicherten Werte daher nicht automatisch.
{
"$schema": "https://schemas.wp.org/wp/7.1/theme.json",
"version": 3,
"title": "Night",
"settings": {
"color": {
"palette": [
{ "slug": "base", "color": "#0a0e14", "name": "Base" },
{ "slug": "contrast", "color": "#e5e7eb", "name": "Contrast" },
{ "slug": "accent", "color": "#38bdf8", "name": "Accent" }
]
}
}
}Warum eine geänderte Datei manchmal nicht sichtbar wird
Der Website-Editor speichert angepasste Vorlagen in der Datenbank: ganze Seiten als wp_template, Seitenteile als wp_template_part und globale Gestaltung als wp_global_styles. Ein solcher Datensatz ist kein öffentlich sichtbarer Blogbeitrag. Ein leerer Datensatz für globale Stile kann bereits beim Öffnen des Editors entstehen.
Jede Anpassung gehört zum aktiven Theme. Die Zuordnung wp_theme enthält dessen Ordnernamen, beim Child also lw-child. Eine Vorlagenkennung wie lw-child//index verbindet diesen Namen mit dem Vorlagennamen.
Eine gespeicherte Anpassung von index hat Vorrang vor templates/index.html desselben Themes. Deshalb bleibt ein Datei-Update zunächst unsichtbar. Das Entfernen dieser Anpassung stellt die Dateifassung wieder her, sofern die Datei vorhanden ist. Eine reine Dateivorlage lässt sich auf diesem Weg nicht löschen. Die folgenden lesenden WP-CLI-Befehle zeigen Datensätze und die Theme-Zuordnung eines Beispieldatensatzes; die ID 123 steht für eine tatsächlich vorhandene ID.
# Which templates, template parts and global styles live in the database?
wp post list --post_type=wp_template,wp_template_part,wp_global_styles --post_status=any --fields=ID,post_type,post_name,post_modified
# Which theme (stylesheet) does a customization belong to? 123 = an ID from the list above.
wp post term list 123 wp_theme --fields=nameBeim Theme-Wechsel bleiben alte Anpassungen gespeichert, gehören aber weiterhin zum vorherigen Theme. Nach dem Rückwechsel können diese Anpassungen wieder wirken. Der Export des Website-Editors erstellt dagegen eine ZIP-Datei mit Theme-Dateien und den übernommenen Anpassungen, einschließlich zusammengeführter Gestaltungseinstellungen.
Welche Vorlage gewinnt?
WordPress sucht zuerst nach der passendsten Vorlage. Für einen normalen einzelnen Beitrag kann die Reihenfolge single-post-hallo-welt, single-post, single, singular, index lauten. Links stehen genauere Namen, rechts allgemeinere Ersatzvorlagen.
Für denselben Namen gilt: zuerst die gespeicherte Anpassung, dann die Datei im Child-Theme, danach die Datei im Eltern-Theme. Fehlt eine passende Theme-Datei, kommen außerdem registrierte Plugin-Vorlagen infrage, seit WordPress 6.7 über register_block_template(). Ohne Treffer folgt der nächste Name aus der Liste. Filter von Erweiterungen können diese Standardsuche verändern.
Beispiel: Eine single.html im Eltern-Theme gewinnt vor einer gespeicherten Anpassung von index. Der genauere Vorlagenname entscheidet zuerst; die Herkunft entscheidet erst bei gleichem Namen. Seitenteile wie header verwenden dagegen keine solche Liste von immer allgemeineren Namen: Hier gilt für den angeforderten Namen Datenbank, Child-Datei, Eltern-Datei. Die Plugin-Registry für ganze Vorlagen ist kein zusätzlicher Schritt dieser Seitenteil-Suche.
template-canvas.php gibt die ausgewählten Blöcke aus. Bei einer leeren gespeicherten Vorlage zeigt WordPress seit 6.8 angemeldeten Konten einen Hinweis. Ohne Anmeldung wird nach Möglichkeit die Dateifassung verwendet.
Ein Child-Theme ergänzen
Ein Child-Theme benötigt eine style.css mit Theme Name und Template. Der Wert von Template muss exakt dem Ordnernamen des Eltern-Themes entsprechen. Eine eigene index.html ist nicht erforderlich, weil WordPress die Datei des Eltern-Themes finden kann.
lw-child/
├── style.css
├── theme.json
└── parts/
└── header.html/*
Theme Name: LW Child
Template: lw-base
Description: Child theme of LW Base with its own palette and header.
Version: 1.0.0
Requires at least: 6.6
Tested up to: 7.1
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: lw-child
*/Gleichnamige Dateien in templates/ und parts/ ersetzen die Eltern-Dateien. Für Patterns entscheidet der Slug im Dateikopf, für Gestaltungsvarianten der Dateiname in styles/. Nicht ersetzte Dateien bleiben vom Eltern-Theme verfügbar. Der folgende Child-Header ergänzt den Website-Untertitel:
<!-- wp:group {"layout":{"type":"flex","justifyContent":"space-between"}} -->
<div class="wp-block-group">
<!-- wp:group {"layout":{"type":"flex","orientation":"vertical"}} -->
<div class="wp-block-group">
<!-- wp:site-title /-->
<!-- wp:site-tagline /-->
</div>
<!-- /wp:group -->
<!-- wp:navigation /-->
</div>
<!-- /wp:group -->Editor-Anpassungen des Eltern-Themes gelten nach dem Wechsel zum Child nicht weiter. Bereits früher gespeicherte Anpassungen dieses Child-Themes können allerdings sofort wieder wirken. Nur ohne solche Anpassungen bestimmt allein die neue Dateifassung das Ergebnis.
Welche Einstellungen übernimmt das Child?
WordPress verbindet Einstellungen in dieser Reihenfolge: eigene Grundwerte, Vorgaben registrierter Blöcke, Theme-Werte und zuletzt gespeicherte Anpassungen. Bei derselben Eigenschaft gewinnt der spätere Wert. Innerhalb der Theme-Werte ergänzt oder ersetzt das Child die Werte des Eltern-Themes. Einstellungen aus theme.json haben außerdem Vorrang vor entsprechenden Vorgaben aus add_theme_support().
{
"$schema": "https://schemas.wp.org/wp/7.1/theme.json",
"version": 3,
"settings": {
"color": {
"palette": [
{ "slug": "base", "color": "#f4f6f9", "name": "Base" },
{ "slug": "contrast", "color": "#111827", "name": "Contrast" },
{ "slug": "accent", "color": "#c2410c", "name": "Accent" }
]
}
},
"styles": {
"elements": {
"heading": {
"typography": { "fontWeight": "700" }
}
}
}
}Im Beispiel bleiben Layoutbreiten, Schriftgrößen und Linkfarbe des Eltern-Themes erhalten. Das Child ergänzt fette Überschriften. Bei Farbpaletten gilt eine wichtige Ausnahme: Die Child-Palette ersetzt die vollständige Eltern-Palette. Entsprechendes gilt für andere vordefinierte Listen wie Schriftgrößen, Schriftfamilien und Schatten, jeweils innerhalb derselben Einstellungsquelle.
Darum enthält das Child alle drei Farben. Mit nur accent fehlten hier die Variablen für base und contrast. Hintergrund- und Textregeln könnten dann nicht mehr die vorgesehenen Farben einsetzen. Die folgende Abfrage zeigt die Theme-Palette ohne gespeicherte Nutzeranpassungen:
wp eval 'echo wp_json_encode( wp_get_global_settings( array( "color", "palette", "theme" ), array( "origin" => "base" ) ), JSON_PRETTY_PRINT );'"origin" => "base" lässt die gespeicherten Anpassungen weg. Die übrigen Grund-, Block- und Theme-Daten werden weiterhin verarbeitet; auch Erweiterungsfilter können wirken. Der abgefragte Pfad color → palette → theme begrenzt die Ausgabe auf die Theme-Palette.
Prüfgrenzen und praktische Gegenprobe
Die Archivprüfung vom 30.09.2026 mit WordPress 7.1.2 dokumentiert Aktivierung, Child-Vererbung, Editor-Validierung, Vorlagenvorrang und Palettenersetzung für das damalige Beispiel. Die ergänzte Vorlage für vollständige Inhalte gehört zur jetzigen Überarbeitung. Vor Einsatz in einer Website sind Listenansicht, Einzelbeitrag und Seite sowie ein gespeicherter Editor-Eingriff auf einer getrennten Testinstallation zu prüfen.
Zwei technische Grenzen bleiben wichtig: Ein PHP-Template im Child kann ein gleichnamiges Block-Template des Eltern-Themes verdrängen. Der Filter wp_theme_json_data_theme läuft außerdem vor dem Zusammenführen einer eigenen Child-JSON-Datei mit der Parent-Datei; an dieser Stelle sind die vollständigen geerbten Werte noch nicht verfügbar.
Ergänzend behandelt ein eigener Beitrag das Sicherheitsupdate für Seitenvorlagen in WordPress 7.1.2.
Fragen und Antworten
Braucht das Child eine eigene index.html?
Nein. Die Ersatzvorlage des Eltern-Themes reicht aus. Eine eigene Datei ist nur für eine abweichende Darstellung nötig.
Warum bleibt eine Dateiänderung unsichtbar?
Eine gespeicherte Editor-Anpassung kann die gleichnamige Datei überlagern. Nach Sicherung und Entfernung der betreffenden Anpassung gilt wieder die Datei. Auch die gewählte Vorlage und vorhandene Caches sind zu prüfen.
Erweitert die Child-Palette die Eltern-Palette?
Nein. Eine eigene Child-Palette ersetzt diese Liste. Alle weiterhin benötigten Farben müssen deshalb in der Child-Palette enthalten sein.
Quellen
- Theme Handbook: Introduction to templates (abgerufen am 29.09.2026)
- Theme Handbook: Template parts (abgerufen am 29.09.2026)
- Theme Handbook: Registering patterns (abgerufen am 29.09.2026)
- Theme Handbook: Style variations (abgerufen am 29.09.2026)
- Theme Handbook: Child themes (abgerufen am 29.09.2026)
- Theme Handbook: Template hierarchy (abgerufen am 29.09.2026)
- Theme Handbook: Main stylesheet (style.css) (abgerufen am 29.09.2026)
- Block Editor Handbook: Theme.json version 3 reference (abgerufen am 29.09.2026)
- Block Editor Handbook: Global settings and styles (theme.json) (abgerufen am 29.09.2026)
- Make WordPress Core: Theme.json version 3 (abgerufen am 29.09.2026)
- JSON-Schema theme.json für WordPress 7.1 (abgerufen am 29.09.2026)
- wordpress-develop 7.1: class-wp-theme-json-resolver.php (abgerufen am 29.09.2026)
- wordpress-develop 7.1: class-wp-theme-json.php (abgerufen am 29.09.2026)
- wordpress-develop 7.1: block-template-utils.php (abgerufen am 29.09.2026)
- wordpress-develop 7.1: block-template.php (abgerufen am 29.09.2026)
- wordpress-develop 7.1: blocks/template-part.php (abgerufen am 29.09.2026)
- wordpress-develop 7.1: block-patterns.php (abgerufen am 29.09.2026)
- wordpress-develop 7.1: class-wp-theme.php (abgerufen am 29.09.2026)
- wordpress-develop 7.1: class-wp-rest-templates-controller.php (abgerufen am 29.09.2026)
- WP-CLI: wp post list (abgerufen am 29.09.2026)
- Versions-API von WordPress.org (aktuelle Version) (abgerufen am 29.09.2026)