Architektur¶
Vier Ideen tragen TWtheme. Wer sie kennt, findet sich im Rest der Dokumentation zurecht.
Die Ebenen¶
graph TB
subgraph child [Child-Theme: das Projekt]
ChildJson["theme.json — Marke"]
ChildTpl["Template-Overrides"]
ChildAssets["eigenes CSS und JS"]
ChildHooks["Hooks und eigene Inhaltstypen"]
end
subgraph parent [Parent-Theme: TWtheme]
Tokens["theme.json — neutrale Tokens"]
Templates["Block-Templates und Parts"]
Module["50 Module"]
Engine["Feld-Engine"]
end
WP["WordPress-Kern"]
child --> parent
parent --> WP
Module --> Engine
Der Parent ist die Grundlage und wird nie projektspezifisch geändert. Das Child liegt darüber und bringt alles mit, was nur dieses eine Projekt betrifft.
Ein Block-Theme¶
Kopf- und Fußbereich, Archive, Einzelansichten und Seiten sind Block-Templates — HTML-Dateien im Theme, die im Site-Editor bearbeitbar sind. Bearbeitet man ein Template dort, landet die Fassung in der Datenbank und hat Vorrang vor der Datei im Theme.
Alle Gestaltungswerte kommen aus der theme.json. WordPress erzeugt daraus
CSS-Variablen, die im Editor und im Frontend gleich sind. Das SCSS des Themes
liefert nur, was sich damit nicht ausdrücken lässt: Komponentenlogik und
Feinheiten einzelner Blöcke.
Was daraus folgt: Eine Farbe ändert man nicht im Stylesheet, sondern in der
theme.json. Sonst laufen Editor und Frontend auseinander.
Alles ist ein Modul¶
Der Funktionsumfang steckt in 50 Modulen unter
includes/theme-options/. Jedes Modul ist ein Ordner mit einer gleichnamigen
PHP-Datei und einer module.json, die seine Metadaten trägt.
Ein Modul kann mitbringen: Blöcke, Shortcodes, Felder in den Theme-Optionen, einen eigenen Inhaltstyp, eigene Assets, Templates.
graph LR
Option["Option twtheme_modules"] --> Registry["Modul-Registry"]
Registry --> Aktiv["aktive Module"]
Aktiv --> PHP["PHP wird geladen"]
Aktiv --> Blocks["Blöcke werden registriert"]
Aktiv --> Fields["Optionsfelder erscheinen"]
Registry --> Inaktiv["inaktive Module"]
Inaktiv --> Nichts["nichts wird geladen"]
Entscheidend ist der rechte Zweig: Ein abgeschaltetes Modul wird nicht geladen.
Seine Funktionen existieren nicht, seine Blöcke sind nicht registriert. Deshalb
gehört vor jeden Aufruf einer Modulfunktion ein function_exists().
Der Modulzustand ist eine gewöhnliche Option¶
Welche Module laufen, steht in der WordPress-Option twtheme_modules auf der
jeweiligen Seite. Das ist die einzige Quelle.
Das Theme ruft nirgends nach Hause und prüft keine Lizenz. Es gibt keinen ausgehenden Request. Ein TWhub kann dieselbe Option schreiben, ist aber nur einer von drei möglichen Schreibern:
graph LR
Admin["Theme → Module"] --> Apply["twtheme_modules_apply_state()"]
Hub["TW Hub Agent"] --> Apply
CLI["WP-CLI"] --> Apply
Apply --> Option["Option twtheme_modules"]
Fällt der Hub weg, bleibt der Zustand bestehen und die Seite Theme → Module voll bedienbar.
Felder statt ACF¶
TWtheme nutzt kein Advanced Custom Fields, sondern eine eigene Feld-Engine unter
includes/engine/. Sie erzeugt aus Felddefinitionen im PHP-Array:
- die Eingabefelder im Backend, über den
FieldBuilder - Optionsseiten und Meta-Boxen
- Inhaltstypen und Taxonomien
- Shortcodes für einzelne Feldwerte, automatisch
- die Datenquelle der Meta-Blöcke im Editor
Ein einmal definiertes Feld ist damit überall verfügbar: im Backend zum Ausfüllen, im Frontend als Block, als Shortcode und im Code.
Laden nach Kontext¶
Nicht jeder Seitenaufruf braucht alles. includes/bootstrap.php entscheidet
anhand des Request-Kontexts, welche Module überhaupt geladen werden — eine
REST-Anfrage braucht andere Teile als eine Frontend-Seite oder der Site-Editor.
Steuern lässt sich das über die Filter twtheme_boot_module_map und
twtheme_boot_modules.
Wo was liegt¶
| Ordner | Inhalt |
|---|---|
templates/ |
Block-Templates als HTML |
parts/ |
Template-Parts als HTML |
template-parts/ |
Bausteine in PHP, aus Code aufgerufen |
styles/ |
Blockstil-Variationen |
includes/theme-options/ |
die 50 Module |
includes/engine/ |
Feld-Engine, Inhaltstypen, Import und Export |
includes/helper/ |
öffentliche Helferfunktionen |
includes/gutenberg/ |
Blockregistrierung und Editor-Assets |
includes/plugins/ |
Anbindung an Fremdplugins |
source/ |
SCSS- und JS-Quellen |
assets/ |
gebaute CSS- und JS-Dateien |
scripts/ |
Build-, Prüf- und Release-Werkzeuge |
languages/ |
Übersetzungen |
source/ und assets/ nicht verwechseln: Bearbeitet wird immer source/,
ausgeliefert wird assets/. Dazwischen liegt der Build —
siehe Build-Kette.
Die Reihenfolge beim Anpassen¶
Für jede Anpassung gibt es einen vorgesehenen Weg. Die Reihenfolge ist eine Rangfolge, nicht eine Auswahl: Was weiter oben geht, sollte nicht weiter unten gelöst werden.
theme.jsonim Child — Farben, Schriften, Abstände, Blockstandards- Template und Template-Part im Child mit gleichem Dateinamen überschreiben
- Eigenes CSS und JS aus dem Child laden
- PHP-Hooks und Filter nutzen
- Nur wenn unvermeidbar: eine einzelne Parent-Datei gezielt kopieren
Ausführlich unter Child-Theme.