Templates & Themes bauen
Ein Orblio-Theme ist ein Ordner voller Vue-3-Vorlagen. Du gestaltest damit das komplette Aussehen einer Webseite und definierst die Block-Elemente, die Redakteure später zusammenstecken. Dieses Kapitel erklärt Struktur, Datei-Aufbau und die verbindlichen Regeln.
Mit KI schneller ans Ziel
Für den Bau von Themes gibt es einen fertigen KI-Skill. Er enthält alle Regeln dieses Kapitels in maschinenlesbarer Form — damit ChatGPT, Claude & Co. korrekte Orblio-Templates erzeugen.
Was ist ein Theme?
Ein Theme (technisch: ein Template-Ordner) bestimmt Farben, Schriften, Kopf- und Fusszeile sowie den gesamten Satz an Block-Elementen. Orblio nutzt dafür ein mehrschichtiges, Gutenberg-artiges System. Wichtig: Das Design muss handwerklich gut sein und die Orblio-Datenstruktur exakt einhalten — ein optisch perfektes Template, das die Verdrahtung verletzt, rendert nicht.
Ordnerstruktur eines Templates
Jedes Theme liegt unter templates/<NAME>/ und hat diese verbindliche Struktur:
templates/<NAME>/
├── components/ Block-Elemente (component1.vue, component2.vue, …)
├── files/ Datei-Icons fürs Theme
│ ├── default.svg Standard-Datei-Icon
│ ├── doc.svg pdf.svg ppt.svg xls.svg zip.svg
│ ├── icons/ SVG-Icon-Bibliothek für <oicon> (neu)
│ └── font/ (optional) eingebundene Schriften
├── cookies.vue Cookie-Banner (neu)
├── dynamiclists.vue Vorlagen für den "Dynamische Liste"-Block
├── emptycomp.vue Anzeige für Seiten ohne Blöcke
├── langswitcher.vue Sprachumschalter
├── lightbox.vue Lightbox / Galerie
├── navigation.vue Navigation (ID-basiert)
├── search.vue Seitensuche
└── theme.vue Theme-Wrapper (Header/Main/Footer)
Anatomie einer .vue-Vorlage
Jede Vorlagedatei besteht aus drei Blöcken — immer in dieser Reihenfolge:
<config>
{ "name": { "default": "Hero" }, "dbKeys": { "title": "text" } }
</config>
<script>
orblio.NAME = Vue.defineComponent({
props: [[orblio_inject_props]], /* vom System ersetzt — NIE selbst füllen */
template: ` … `,
/* data / computed / methods / mounted nach Bedarf */
});
</script>
<style>
/* Nested CSS mit & — KEIN SASS/SCSS */
</style>
NAME ist der Dateiname ohne Endung (theme, navigation, component5 …). Block-Komponenten registriert das System als orblio.componentN.
System-Platzhalter
Diese Platzhalter ersetzt das System zur Laufzeit — sie bleiben wörtlich stehen:
| Platzhalter | Ort | Bedeutung |
|---|---|---|
[[orblio_inject_props]] | props: | Vom System gelieferte Props. Nie selbst befüllen. Hängt bei Sub-Templates auch deren Logik an. |
[[orblio_template_contents]] | <main> in theme.vue | Hier rendert das System die Seiteninhalte (die Blöcke). |
[[orblio_template_mounted]] | mounted() in theme.vue | System-Mount-Logik. Eigener Code davor/danach erlaubt. |
[[orblio_editorbutton]] | Sub-Templates | Editier-Button im CMS-Bearbeitungsmodus, direkt nach dem Wurzelelement. |
Der <config>-Block
Jede Datei braucht einen <config>-Block, und er muss gültiges JSON sein: doppelte Anführungszeichen, keine Kommentare, kein Komma am Ende. Bei Blöcken meldet erst dbKeys den Block in der Block-Auswahl an. Fehlt dbKeys oder ist das JSON fehlerhaft, taucht der Block dort einfach nicht auf.
Theme (theme.vue):
{ "name": "Mein Theme", "description": "Kurzbeschreibung", "author": "...", "date": "2026-05-24" }Block-Komponente (components/componentN.vue):
{
"name": { "default": "Hero", "en": "Hero" },
"description": { "default": "Titel, Text, Bild" },
"author": "...",
"date": "2026-05-24",
"dbKeys": { /* deklariert die DB-Struktur — siehe Content-Elemente */ }
}Sub-Templates (navigation, search, langswitcher, lightbox, cookies, emptycomp, dynamiclists) haben eine einfache <config> mit name und description, ohne dbKeys.
Die harten Regeln
Diese Punkte sind nicht verhandelbar — verletzt eine Vorlage sie, rendert sie nicht oder zerstört das Layout:
- Kommentare nur
/* */— niemals//, weder in JS noch in CSS. - CSS (darf auch nested sein mit
&), kein SASS/SCSS. Nur natives verschachteltes CSS plus Custom-Properties (--token). - Vue 3 Options API über
Vue.defineComponent({…}). Kein<script setup>, keineimport/export, keine Composition-API. - Zentrale Elemente sind unveränderlich:
vtext,htmltext,oimage,ovideo,oicon,ofolder,repeatable,repeatcontents,fromdatabaseexakt wie dokumentiert verwenden. vtextfür designfixe Texte,htmltextnur für freien Fliesstext. Überschriften, Labels, Button-Beschriftungen immer mitvtext.- Jedes Tag auf eine Zeile. Orblio entfernt beim Bauen alle Zeilenumbrüche und Tabs. Attribute, die über mehrere Zeilen verteilt sind, kleben danach zusammen. Darum: ein Tag mit allen Attributen auf eine Zeile, nur Leerzeichen zum Einrücken.
- Kein
": "in sichtbarem Template-Text. Orblio macht daraus":". Texte mit Doppelpunkt gehören als Inhalt ins Feld, nicht ins Markup. - Externe Dienste nur über das Cookie-Banner. Videos über
ovideo. Karten und fremde Skripte mitdata-orb-cc="medien"(bzw.statistik,marketing) unddata-srcstattsrc— Orblio lädt sie erst nach der Zustimmung.
Verboten
//-Kommentare · <script setup> / import / export · fetch()/axios · props: [[orblio_inject_props]] selbst füllen · zentrale Elemente umschreiben · htmltext für Überschriften · hartcodierte <a href>/<button> in Blöcken · SASS · reines #000/#fff als Fläche.
Naming-Konventionen
.orb_header, .orb_nav_main). Lightbox: .orblb_*, Cookie-Banner: .orb_cc_*.component5.vue → .c5_section). So bleiben Styles kollisionsfrei.theme.vue unter :root definieren; Komponenten konsumieren mit Fallback: var(--r-md, 10px).Sub-Templates & der $root-Vertrag
Neben Blöcken hat ein Theme feste Sub-Templates, die das Laufzeitsystem ansteuert. Ihre Logik (Menüeinträge auflösen, suchen, Sprache wechseln, Lightbox bedienen, Zustimmung speichern) liefert Orblio selbst: Über [[orblio_inject_props]] wird sie automatisch angehängt. In der Datei stehen also nur Markup und CSS.
Ältere Themes laufen weiter
Bringt eine Datei eigene Methoden mit, haben diese Vorrang vor der Logik von Orblio. Ältere Themes funktionieren so unverändert. Sie verpassen dann aber Verbesserungen aus Updates, zum Beispiel bei der Lightbox. Wer ein Theme überarbeitet, sollte die eigene Logik in Sub-Templates deshalb entfernen.
| Sub-Template | Aufgabe | Style-Präfix |
|---|---|---|
theme.vue | Wrapper: Header, <main> mit den Inhalten, Footer. Ort für Tokens, Reset, Buttons. | orb_* |
navigation.vue | Menüs, per ID gesteuert. DOM: nav > ul > li(a + sub-ul), Zustände .active/.has_sub. | orb_nav_* |
search.vue | Volltextsuche mit Ergebnis-Dropdown. | orb_search_* |
langswitcher.vue | Sprachauswahl; rendert nur bei > 1 Sprache. | orb_lang_* |
lightbox.vue | Galerie/Overlay. Muss als <lightbox/> im Theme eingebunden sein. | orblb_* |
cookies.vue | Cookie-Banner. Muss als <cookies/> im Theme stehen. Wieder geöffnet wird es über <cookieoptions>…</cookieoptions> (siehe Cookie-Banner). | orb_cc_* |
emptycomp.vue | Erscheint auf Seiten, die noch keinen Block haben. Fehlt die Datei, bleibt eine leere Seite weiss. | frei |
dynamiclists.vue | Sonderfall: keine Komponente, sondern ein JS-Array von Listen-Vorlagen. | dl-* |
Der $root-Zustandsvertrag
Sub-Templates lesen und schreiben nur diese dokumentierten Felder:
| Zugriff | Zweck |
|---|---|
$root.page (r/w) | Aktuelle Seiten-URL. Schreiben = Navigation (SPA). '/' = Startseite. |
$root.contentLang (r/w) | Aktuelle Inhaltssprache ('default', 'en' …). |
$root.contentLangs (r) | Map verfügbarer Sprachen { key: Anzeigename }. |
Lightbox und Cookie-Banner nicht vergessen
Bindet das Theme <lightbox/> nicht ein (am Ende des Wrappers, nach dem Footer), sind alle a[data-link-open="lightbox"]-Links tot — auch wenn die Datei existiert. Dasselbe gilt für <cookies/>: Ohne die Zeile erscheint kein Banner.
Kompilierung
Deine .vue-Quelldateien werden von Orblio zu ausgelieferten Bundles kompiliert. Bearbeite immer die Quelldateien im Template-Ordner, nie die generierten Bundle-Dateien (z. B. *.foot.js unter defs/) — die sind reine Artefakte und werden beim nächsten Build überschrieben.