Themes
Auf dieser Seite
Themes
Themes sind native BoxLang-.bxm-Templates - es gibt keine separate
Template-Engine oder einen eigenen Build-Schritt.
Integriert
| Theme | Basis | Hinweise |
|---|---|---|
bootstrap (Standard) | Bootstrap 5, vendoriert | Poppins-Schriftart, Navbar mit Marken-Gradient |
material | Handgefertigtes Material-artiges CSS | Card-Layout, Elevation-Schatten, Roboto-Schriftart |
tailwind | Tailwind Play CDN | Utility-Class-getrieben, kein Build-Schritt |
docsy | Handgefertigtes CSS, geforkt von material | An Read the Docs/Docsy angelehnter, marineblauer Referenzhandbuch-Look |
slate | Handgefertigtes CSS, geforkt von material | An Stripe/Slate angelehnt - eine dauerhaft dunkle Sidebar, unabhängig vom Hell-/Dunkelmodus |
docusaurus | Handgefertigtes CSS, geforkt von material | An Docusaurus angelehnte, kräftige, volle Breite farbige Navbar, abgerundete Cards |
justthedocs | Handgefertigtes CSS, geforkt von material | An Just the Docs angelehnter Minimalismus - die Suchbox sitzt oben in der Sidebar |
vuepress | Handgefertigtes CSS, geforkt von material | An VuePress angelehnter grüner Akzent, weich abgerundete Ecken |
gitbook | Handgefertigtes CSS, geforkt von material | An GitBook angelehnte zentrierte Lesespalte, Serifen-Überschriften |
notion | Handgefertigtes CSS, geforkt von material | An Notion angelehnte randlose Sidebar, nahezu grauskalige UI, großzügiger Weißraum |
Die sieben oben von material geforkten Themes verwenden materials
exakte BoxLang-Templates (layout.bxm/page.bxm/search.bxm) unverändert,
bis auf eine begrenzte CSS-Klassenpräfix-Umbenennung - nur
assets/style.css (und bei justthedocs eine verschobene
<bx:include>-Zeile, die die Suchbox in die Sidebar verlegt)
unterscheidet sich, sodass sie denselben vollständigen Funktionsumfang
und dasselbe air-gapped-fähige Verhalten erben, das material bereits
hat.
Das eigene CSS/JS jedes integrierten Themes (Bootstraps CSS/JS-Bundle,
highlight.js, Alpine.js, lunr.js für den standardmäßigen local-Suchanbieter,
und Mermaid, wenn mermaid aktiviert ist) wird vendoriert mit diesem Modul
ausgeliefert und direkt in jede gebaute site/ kopiert - kein CDN, kein
Internetzugang nötig, um eine gebaute Website anzusehen. Die eigene
Utility-Engine des tailwind-Themes (ein clientseitiger JIT-Compiler, kein
statisches Stylesheet) und andere optionale Funktionen, die du selbst
aktivierst (math, Algolia-Suche, Google Analytics), laden weiterhin von
einem CDN oder einer gehosteten API - siehe
Air-gapped/Offline-Websites unten.
bootstrap, material und tailwind verwenden dieselbe
BoxLang-Markenpalette (einen #00FF78 -> #00DBFF-Gradient und einen
#FFF500-Akzent); die sieben Galerie-Themes darunter verwenden stattdessen
jeweils ihre eigene, unterschiedliche Palette, angelehnt an die Plattform,
von der sie ihren Look entlehnen - siehe die Tabelle oben. Jedes der zehn
bringt unabhängig von der Palette denselben Satz an Seitenfunktionen mit:
- Ein Inhaltsverzeichnis "Auf dieser Seite", erzeugt aus den eigenen
h2/h3-Überschriften jeder Seite. - Breadcrumbs, die die Ahnenkette einer Seite zeigen, wenn sie mehr als eine Ebene tief unter einem verlinkten Vorfahren verschachtelt ist.
- Vorherige/Nächste-Seite-Links am Ende des Artikels, entlang der eigenen Leserichtung der Navigation.
- Syntax-hervorgehobene Codeblöcke, über highlight.js
plus eine eigene BoxLang-Grammatik (
```bx/```boxlang/```cfscript), jeweils mit einem Kopieren-Button - bei Hover sichtbar auf Geräten, die das unterstützen, auf Touch-Geräten immer sichtbar (dort gibt es kein Hover, um ihn einzublenden). Siehe Markdown-Erweiterungen. - Selbst gehostete Webfonts - keine Anfrage an
fonts.googleapis.comzur Anzeigezeit. - Ein Dunkel-/Hell-Modus-Umschalter, angetrieben von
Alpine.js für die Reaktivität. Die Wahl des
Besuchers wird in
localStoragegemerkt (mit Fallback auf die Betriebssystem-Präferenz) und noch vor dem ersten Rendern angewendet, um ein kurzes Aufblitzen des falschen Themes zu vermeiden. - Eine responsive Kopfzeile, die bei jeder Breite einreihig bleibt -
ein schmales Viewport schrumpft die Suchbox, statt sie in eine eigene
Zeile umbrechen zu lassen - plus eine einklappbare Sidebar-Navigation
(ein Hamburger-Umschalter in
bootstrap/material/tailwindgleichermaßen). - Tastaturkürzel in der Suchbox:
/fokussiert die Suche von überall auf der Seite, undEscapeschließt die Ergebnisse. Siehe Suche. - Ein Repo-Link und eine "Diese Seite bearbeiten"-/"Zuletzt
aktualisiert"-Zeile, wenn die Optionen
repo/lastUpdatedinbxsites.yamlgesetzt sind. Siehe Konfiguration. - Ein "Markdown herunterladen"-Link, neben "Diese Seite bearbeiten" -
die rohe
.md-Quelle jeder Seite wird zusammen mit ihrem gebauten HTML veröffentlicht (guides/themes.mdliegt nebenguides/themes/index.html), sodass sie (oder eine KI) die Seite direkt als reines Markdown lesen kann, statt gerendertes HTML zu parsen. Immer aktiv, keine Konfiguration nötig. Siehe Erste Schritte. - Eine optionale Fußzeile (Copyright,
social-Links, ein "Built with BxSites"-Hinweis), wennfooterinbxsites.yamltrueist. Siehe Konfiguration. - Ein Versionsumschalter, der automatisch erscheint, sobald ein
Projekt einen
docs/versions/-Ordner mit mehr als einer Version hat. Siehe Konfiguration. - Eine themenspezifische
404.html, automatisch ausgeliefert von den meisten statischen Hosts (einschließlich GitHub Pages) für jeden nicht gefundenen Pfad. Lege eine404.mdim Stammverzeichnis vondocs/(odersrc/) an, um Titel und Inhalt selbst zu bestimmen - sie wird nie als reguläre Seite gebaut (kein Nav-Eintrag, keinesitemap.xml-URL), sondern stattdessen direkt insite/404.htmlgerendert. - Ein eigenes Logo und Favicon, wenn
theme.logo/theme.faviconinbxsites.yamlgesetzt sind. Siehe Konfiguration. - Eine einklappbare Sidebar-Navigation, opt-in über
theme.options.navCollapsible- jeder Abschnitt mit Kindern (verlinkt oder nicht) erhält eine Umschalt-Schaltfläche, statt seine Kinder immer inline anzuzeigen, und der Abschnitt, der die aktuelle Seite enthält, startet immer geöffnet. Siehe Konfiguration. - Google Analytics, wenn
analyticsinbxsites.yamlkonfiguriert ist. Siehe Konfiguration. - Social-Share-Cards (Open-Graph- + Twitter-Card-Meta-Tags), erzeugt
aus der
description-Frontmatter jeder Seite (oder der websiteweitendescription) und ihrem eigenenogImage(oder dem websiteweiten) - optional automatisch pro Seite erzeugt übergenerateOgImagesinbxsites.yaml. Siehe Konfiguration. - Seiten-Tags, ein Icon und eine Zusammenfassungszeile, alle opt-in
über die eigene Frontmatter einer Seite - Tags werden als Badges
gerendert, die zu einem websiteweiten
/tags/-Index verlinken. Siehe Erste Schritte. - Eine explizite Navigations-Überschreibung, in
bxsites.yamloder der eigenendocs/nav.json, die die Ordner-Ableitung für große Websites ersetzt. Siehe Konfiguration. - Zusätzliches CSS/JS, eingebunden über
extraCss/extraJsinbxsites.yaml. Siehe Konfiguration. - Admonition-Callout-Boxen (Hinweis/Warnung/Tipp/...), standardmäßig im Markdown jeder Seite aktiv, einschließlich einklappbarer Varianten - keine Konfiguration nötig. Siehe Markdown-Erweiterungen.
- Fußnoten und Definitionslisten, opt-in über
markdowninbxsites.yaml. Siehe Markdown-Erweiterungen. - Content-Tabs, Code-Zeilennummern/hervorgehobene Zeilen/Titel und Diff-Markierungen/Terminal-Rahmen für Codeblöcke, keine Konfiguration nötig. Siehe Markdown-Erweiterungen.
- Mermaid-Diagramme, opt-in über
mermaidinbxsites.yaml. Siehe Markdown-Erweiterungen. - Mathematik (KaTeX), opt-in über
mathinbxsites.yaml. Siehe Markdown-Erweiterungen.
Lege in bxsites.yaml fest, welches Theme ein Projekt verwendet:
theme: { name: material }
{ "theme": { "name": "material" } }
Ein veröffentlichtes Theme installieren
Ein auf ForgeBox veröffentlichtes Theme installiert sich mit nichts
weiter als der bxSites-Binary selbst - kein box/CommandBox nötig.
Durchsuche die bereits veröffentlichten Pakete unter der Kategorie
bxsites-themes auf
ForgeBox:
bxSites install:theme --name=bx-sites-theme-blog1 [--version=1.0.0]
Das lädt das ZIP des Pakets herunter und entpackt es nach
themes/bx-sites-theme-blog1/ im Projekt-Wurzelverzeichnis, wobei vor
Abschluss geprüft wird, ob es den ThemeProvider-Vertrag unten erfüllt.
Ein Projekt kann auf diese Weise mehrere installierte Themes
nebeneinander vorhalten und rein per Name zwischen ihnen wechseln:
theme: { name: bx-sites-theme-blog1 }
{ "theme": { "name": "bx-sites-theme-blog1" } }
Ein Theme braucht überhaupt keine BoxLang-Modul-/Klassenlader-Beteiligung
(anders als ein Plugin) - es sind reine Dateien, es gibt also keinen
separaten Aktivierungsschritt, wie ihn install:plugin hat; das Setzen
von theme.name ist die einzige nötige Verdrahtung. Siehe
install:theme in der CLI-Referenz.
Startest du stattdessen von einem Theme, das für einen anderen
statischen Site-Generator gebaut wurde? Siehe
Ein Theme importieren - theme:import wandelt die
eigenen Template-Dateien eines mkdocs-/jekyll-/hugo-Themes mechanisch in
ein bestmögliches themes/<name>/-Gerüst um.
Air-gapped/Offline-Websites
Eine gebaute Website funktioniert standardmäßig völlig ohne Internetzugang,
für bootstrap, material und die sieben von material geforkten
Themes (docsy, slate, docusaurus, justthedocs, vuepress,
gitbook, notion) mit dem standardmäßigen local-Suchanbieter:
Bootstraps eigenes CSS/JS, highlight.js, Alpine.js und
lunr.js sind alle mit diesem Modul vendoriert (resources/assets/vendor/)
und werden zur Build-Zeit direkt nach site/assets/vendor/ kopiert -
nirgends im erzeugten HTML taucht dafür ein CDN-<script>-/<link>-Tag
auf. Aktivierst du den Schlüssel mermaid in bxsites.yaml, wird Mermaid
auf dieselbe Weise vendoriert - sein mermaid.min.js-Bundle wird nach
site/assets/vendor/mermaid/ kopiert, und jedes integrierte Theme lädt es
von dort, sodass Diagramme weiterhin ganz ohne ausgehende Anfragen
gerendert werden.
Ein paar Dinge greifen weiterhin nach außen ins Netzwerk, aber nur, wenn du sie selbst aktivierst:
- Die eigene Utility-Engine des
tailwind-Themes ist ein clientseitiger JIT-Compiler, geladen voncdn.tailwindcss.com- kein statisches Stylesheet, das dieses Modul auf dieselbe Weise vendorieren könnte, daher ist dieses Theme (noch) nicht air-gapped-fähig. - Mermaids eigene Layout-Engine lädt bei Bedarf einen zusätzlichen Chunk
nach,
elk-api.js, von jsDelivr - aber nur für Diagrammtypen, die denelk-Layout-Algorithmus verwenden; das vendoriertemermaid.min.jsrendert jeden anderen Diagrammtyp vollständig eigenständig. - Die Option
mathinbxsites.yamllädt KaTeX (sowohl dessen JS als auch die eigenen Font-Dateien) von einem CDN, wenn sie aktiviert ist. searchProvider.provider: "algolia"undanalytics.provider: "google"sprechen naturgemäß mit einer gehosteten API/einem Tracking-Endpunkt - das Vendorieren der JS-Datei würde diese Abhängigkeit nicht beseitigen.
Wenn dein Einsatzziel wirklich null Internetzugang hat, bleib bei
bootstrap/material/einem der sieben von material geforkten Themes,
dem standardmäßigen local-Suchanbieter, vermeide
elk-Layout-Mermaid-Diagramme, falls mermaid aktiviert ist, und lass
math/Algolia/Analytics aus.
Siehe Icons dafür, wie die eigene icon-Frontmatter einer
Seite (oder das eigene icon eines nav.json-Eintrags) zu einem Emoji,
einem benannten Icon aus einer von acht mitgelieferten Bibliotheken oder
einer eigenen, projekteigenen SVG-Datei aufgelöst wird.
Der ThemeProvider-Vertrag
Ein Theme ist einfach ein Ordner mit:
layout.bxm(erforderlich) - die äußere HTML-Hülle + Navigation. Erhältvariables.page,variables.nav,variables.siteConfig,variables.themeDirundvariables.basePathim Scope, und bindet das benachbartepage.bxmüber#variables.themeDir#/page.bxmein.variables.basePathist immer ein root-relativer, auf/endender Pfad (standardmäßig/,/my-docs/, wennbaseURLinbxsites.yamldas überschreibt) - stelle diesen jedem internenhref/srcvoran, statt ein führendes/fest zu codieren, damit das Theme auch funktioniert, wenn die Website aus einem Unterpfad ausgeliefert wird.page.bxm(erforderlich) - der Artikelinhalt. Rendertvariables.page.contentHtml- das bereits konvertierte Markdown.search.bxm(optional) - das Markup der Suchbox, vonlayout.bxmnur eingebunden, wennsearchinbxsites.yamltrueist. Siehe Suche.assets/(optional) - Theme-CSS/JS, zur Build-Zeit nachsite/assets/theme/kopiert.
variables.page.editUrl/.lastUpdated (leere Zeichenketten, wenn nicht
konfiguriert) und variables.siteConfig.repo/.social/.footer sind
ebenfalls immer verfügbar und stützen die oben beschriebenen
Repo-Link-/Bearbeiten-Link-/Zuletzt-aktualisiert-/Fußzeilen-Funktionen -
ein eigenes Theme entscheidet selbst, ob und wie es sie rendert, wie auch
alles andere. variables.versions ([ { label, url } ], "Latest" zuerst)
und variables.currentVersion (das gerade gerenderte label) stützen den
Versionsumschalter - leer/"Latest" für ein nicht versioniertes Projekt,
sodass ein Theme nur dann einen Umschalter rendern muss, wenn
variables.versions.len() gt 1. Jedes integrierte Theme bezieht seine
Repo-/Social-Icons aus einem kleinen gemeinsamen SVG-Lookup,
<bx:include template="#variables.moduleAssetsDir#/icons.bxm">
(definiert bxsitesIcon( name ), eines von github, twitter/x, rss,
youtube, linkedin, facebook, bluesky, threads, slack,
patreon, email, edit, clock, mit einem generischen Link-Symbol als
Fallback) - ein eigenes Theme kann das auf dieselbe Weise einbinden, oder
seine Icons vollständig selbst bereitstellen.
Ein Theme-Ordner, dem eine der beiden erforderlichen Dateien fehlt,
schlägt sofort mit einem klaren BxSites.InvalidTheme-Fehler zur Build-Zeit
fehl, statt mit einem verwirrenden Template-Fehler tief im Rendering.
Farben anpassen, ohne ein Theme zu überschreiben
Für eine kleine Farb-/Schriftanpassung ist ein ganzes Theme zu forken
Overkill - jedes integrierte Theme liest seine Palette aus einer Handvoll
CSS-Custom-Properties auf :root, erneut deklariert unter
[data-theme="dark"] für den Dunkelmodus. Das
extraCss von bxsites.yaml wird
nach dem eigenen Stylesheet des Themes geladen, sodass eine erneute
Deklaration mit gleicher Spezifität darin gewinnt, ohne resources/themes/
überhaupt anzurühren:
extraCss: [ assets/brand.css ]
{ "extraCss": ["assets/brand.css"] }
/* docs/assets/brand.css - copied to site/assets/brand.css at build time */
:root {
--bxsites-gradient-start: #7C3AED;
--bxsites-gradient-end: #DB2777;
--bxsites-accent: #FBBF24;
--bxsites-link: #7C3AED;
--bxsites-link-hover: #9F5AF0;
}
[data-theme="dark"] {
--bxsites-link: #C4B5FD;
--bxsites-link-hover: #DDD6FE;
}
Das eigene Set des bootstrap-Themes
(resources/themes/bootstrap/assets/style.css) ist
--bxsites-gradient-start/-end, --bxsites-accent, --bxsites-bg,
--bxsites-text, --bxsites-sidebar-bg, --bxsites-sidebar-text,
--bxsites-border, --bxsites-link, --bxsites-link-hover,
--bxsites-code-bg, --bxsites-step-marker-bg, --bxsites-step-marker-text,
--bxsites-step-line, --bxsites-step-success-bg/-text,
--bxsites-step-warning-bg/-text und --bxsites-step-danger-bg/-text.
Jedes integrierte Theme garantiert --bxsites-gradient-start/-end,
--bxsites-accent sowie das --bxsites-step-*-Set unter genau diesen
Namen, sodass extraCss unabhängig vom Theme immer die
Markenfarbe/Stepper-Akzente umlenken kann - aber nur bootstrap, slate
und notion legen zusätzlich auch
--bxsites-bg/-text/-sidebar-bg/-sidebar-text/-border/-link/-link-hover/-code-bg
unter diesen Namen offen (justthedocs aliast alle bis auf die beiden
-sidebar-* auf dieselbe Weise). Jedes andere integrierte Theme
(material, tailwind, docsy, docusaurus, vuepress, gitbook)
verwendet für diese zweite Gruppe stattdessen seine eigenen internen
Custom-Property-Namen (z. B. verwendet materials eigenes
assets/style.css --md-bg/--md-ink/--md-link/...) - öffne das
eigene assets/style.css dieses Themes, um seine echten Namen zu finden,
bevor du eines davon über extraCss überschreibst. Alles über
Farbe/Schriftart hinaus (Layout, Chrome hinzufügen/entfernen) braucht
eine echte Überschreibung oder ein eigenes Theme - siehe unten.
Der Rest stützt den ::: stepper/::: step-Direktiv-Block
--bxsites-step-marker-bg/-textsind die Hintergrund-/Textfarbe des standardmäßigen nummerierten Kreises (bootstrap/materialsetzen ihn standardmäßig auf den eigenen--bxsites-accentdes Themes;tailwindverwendet ein eigenes Türkis-/Minz-Paar, da es keinen einzelnen gemeinsamen Akzent-Token hat),--bxsites-step-lineist die Verbindungslinie zwischen den Schritten, und die-success/-warning/-danger-Paare stützen das eigene, optionalecolor="..."-Attribut eines Schritts - anders als der Standard-Marker sind diese drei dasselbe feste Hintergrund-/Text-Paar sowohl im Hell- als auch im Dunkelmodus (ein in sich geschlossenes Badge, nicht an die eigene Markenfarbe des Themes gebunden), es gibt also keine[data-theme="dark"]-Überschreibung neu zu deklarieren:
:root {
--bxsites-step-marker-bg: #7C3AED;
--bxsites-step-marker-text: #fff;
--bxsites-step-success-bg: #059669;
--bxsites-step-success-text: #fff;
}
[data-theme="dark"] {
--bxsites-step-marker-bg: #C4B5FD;
--bxsites-step-marker-text: #1b1f21;
}
Homepage-Hero-Banner
Jedes integrierte Theme liefert CSS für ein Homepage-Banner in voller
Breite mit Titelbild und Call-to-Action-Buttons - genau diese Website
verwendet es in ihrer eigenen docs/index.md. Es gibt dafür keinen
Direktiv-Block und keine Konfiguration, nur schlichtes HTML, das jede
Seite einfügen kann (eine Homepage ist einfach eine normale Seite,
order: 1 oder sonst als Erste in der Navigation):
<div class="bxsites-hero">
<img class="bxsites-hero__banner" src="assets/home-banner.jpg" alt="...">
<div class="bxsites-hero__actions">
<a class="bxsites-hero__btn bxsites-hero__btn--primary" href="getting-started.md">Get Started</a>
<a class="bxsites-hero__btn bxsites-hero__btn--secondary" href="https://github.com/your/repo">View on GitHub</a>
</div>
</div>
bxsites-hero__btn--primary/--secondary sind dieselben zwei
Akzent-Stile, die jedes Theme bereits an anderer Stelle verwendet -
tausche, entferne oder füge Buttons nach Belieben hinzu, und
skaliere/ersetze das eigene Bild von bxsites-hero__banner über ein zu
docs/assets/-relatives src, auf dieselbe Weise, wie jedes andere Bild
aufgelöst wird.
Ein Theme überschreiben
Lege deine eigenen layout.bxm + page.bxm (und optional search.bxm /
assets/) in einen theme/-Ordner im Wurzelverzeichnis deines Projekts.
BxSites bevorzugt eine projektweite theme/-Überschreibung sowohl
gegenüber einem installierten themes/<name>/-Theme als auch gegenüber
jedem integrierten Theme, solange sie den obigen Vertrag erfüllt - die
integrierten Themes unter resources/themes/ dieses Moduls sind ein
guter Ausgangspunkt zum Kopieren und Anpassen. Vollständige
Auflösungsreihenfolge: theme/ (dieser Abschnitt) -> themes/theme.name/
(ein installiertes Theme,
falls theme.name zu einem passt) -> ein integriertes Theme namens
theme.name.
Ein durchgearbeitetes Beispiel - starte mit bootstrap und tausche seine
Markenpalette und Überschriften-Schriftart gegen deine eigenen aus, wobei
alles andere (Navigation, Suche, Dunkelmodus, Code-Hervorhebung, ...)
genau so weiterläuft, wie es bereits funktioniert:
my-project/
├── bxsites.yaml
├── docs/
└── theme/ ← project-level override, checked before any built-in theme
├── layout.bxm ← copied from resources/themes/bootstrap/layout.bxm
├── page.bxm ← copied from resources/themes/bootstrap/page.bxm, unchanged
├── search.bxm ← copied unchanged
└── assets/
└── style.css ← copied from bootstrap's assets/style.css, then edited
- Kopiere die drei
.bxm-Dateien undassets/style.cssausresources/themes/bootstrap/dieses Moduls in dastheme/deines Projekts. - Ändere nur das, was du wirklich ändern musst. Um Markenpalette und
Schriftart zu tauschen, genügt der obere Teil von
theme/assets/style.css:
:root {
--bxsites-gradient-start: #7C3AED; /* was #00FF78 */
--bxsites-gradient-end: #DB2777; /* was #00DBFF */
--bxsites-accent: #FBBF24; /* was #FFF500 */
}
body {
font-family: "Inter", system-ui, sans-serif; /* was "Poppins" */
}
- Führe
bxSites buildaus (oderservewährend der Iteration) - BxSites übernimmttheme/automatisch, keine Änderung anbxsites.yamlnötig (ein projektweitertheme/-Ordner hat immer Vorrang vor dem imtheme.namegenannten integrierten Theme). Alles, was du nicht angefasst hast - Navigations-Rendering, Suche, der Dunkelmodus-Umschalter, Code-Annotationen - funktioniert genau so weiter, wie es im ursprünglichenbootstrap-Theme funktioniert hat, da es darunter immer noch genau dasselbelayout.bxm/page.bxm-Markup ist.
Ein projektweiter theme/-Ordner ist allerdings alles-oder-nichts -
sobald BxSites einen findet, wird er anstelle des integrierten Themes
vollständig verwendet, braucht also trotzdem seine eigenen layout.bxm +
page.bxm, selbst wenn du nur assets/style.css geändert hast (ein
Ordner, dem eine der beiden fehlt, schlägt sofort mit
BxSites.InvalidTheme fehl, statt stillschweigend zurückzufallen). Für
eine reine CSS-Anpassung ohne .bxm, nutze stattdessen
extraCss von oben - es
legt sich über das Theme, das bxsites.yaml benennt, ganz ohne
theme/-Ordner. theme/ ist für den Fall, dass du auch das Markup
selbst ändern musst, siehe als Nächstes.
Ein Theme von Grund auf schreiben
Ein Theme braucht nur die beiden erforderlichen Dateien, hier also ein
wirklich minimales Beispiel - kein Bootstrap/Tailwind, kein Dunkelmodus,
keine Such-UI - um genau zu zeigen, was erforderlich ist im Vergleich zu
dem, was die integrierten Themes zusätzlich bieten. Speichere beide als
theme/layout.bxm und theme/page.bxm in deinem Projekt - ein
projektweiter theme/-Ordner wird automatisch übernommen (wie oben),
keine Änderung an bxsites.yaml nötig:
<!-- theme/layout.bxm -->
<bx:script>
function renderNav( required array nodes ) {
var html = "<ul>"
for ( var node in arguments.nodes ) {
html &= "<li>"
html &= len( node.url )
? '<a href="' & variables.basePath & node.url & '">' & encodeForHTML( node.title ) & '</a>'
: encodeForHTML( node.title )
if ( node.children.len() ) {
html &= renderNav( node.children )
}
html &= "</li>"
}
return html & "</ul>"
}
</bx:script>
<bx:output>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>#encodeForHTML( variables.page.title )# - #encodeForHTML( variables.siteConfig.name )#</title>
<link rel="stylesheet" href="#variables.basePath#assets/theme/style.css">
</head>
<body>
<header><a href="#variables.basePath#">#encodeForHTML( variables.siteConfig.name )#</a></header>
<nav>#renderNav( variables.nav )#</nav>
<main>
</bx:output>
<bx:include template="#variables.themeDir#/page.bxm">
<bx:output>
</main>
</body>
</html>
</bx:output>
<!-- theme/page.bxm -->
<bx:output>
<article>
<h1>#encodeForHTML( variables.page.title )#</h1>
#variables.page.contentHtml#
</article>
</bx:output>
Das ist ein vollständiges, funktionierendes Theme -
variables.page.contentHtml ist das bereits konvertierte Markdown
(Syntax-Hervorhebung, Admonitions, Tabs, Mathematik und alles), es bleibt
also nichts mehr zu parsen, nur noch zu layouten. Von hier aus füge
hinzu, was die integrierten Themes haben und du tatsächlich willst:
search.bxm (nur eingebunden, wenn search in bxsites.yaml true ist
- siehe Suche), einen Dunkelmodus-Umschalter (kopiere das
x-data/x-init-Alpine.js-Paar vom<body>-Tag vonresources/themes/bootstrap/layout.bxmund den passenden[data-theme="dark"]-CSS-Block), Breadcrumbs/Tags/Vorherige-Nächste-Links (page.bxmin jedem integrierten Theme zeigt das Muster - jedes ist nur einifum eine kleine Render-Funktion, alle gespeist aus Feldern, die bereits aufvariables.pagevorhanden sind), oder einenassets/-Ordner für dein eigenes CSS/JS, automatisch zur Build-Zeit nachsite/assets/theme/kopiert.