Wie man Starlight-Sidebars vollständig automatisch erstellt (ohne die Kontrolle zu verlieren)

Haben Sie jemals versucht, die Generierung von Sidebars in Ihrem Starlight-Projekt zu vereinfachen? Haben Sie versucht, die gesamte Sidebar automatisch zu erstellen, nur um festzustellen, dass Sie die Struktur nicht nach Ihren Wünschen anpassen können?
Dieser Beitrag zeigt zwei Starlight-Funktionen, die es ermöglichen, vollständig automatisch generierte Sidebars flexibel zu gestalten und den Wartungsaufwand zu reduzieren.
In mittelgroßen bis großen Starlight-Projekten stellt sich das Problem, dass die manuelle Erstellung und Pflege der Starlight-Sidebar-Konfiguration eine mühsame und zeitaufwändige Aufgabe ist.
In der Vergangenheit bot Starlight nicht die richtigen Grundfunktionen dafür, und der empfohlene Ansatz bestand darin, die automatische Erstellung der Sidebar-Konfiguration um eine Ebene tiefer zu verschieben - sodass nur Ordner ohne verschachtelte Unterordner automatisch generiert wurden. Mit der Einführung von Route Data und dem jüngeren generateId()
-Hook im docsLoader
können diese Szenarien nun jedoch viel einfacher und effizienter gelöst werden.
Ein häufiges Problem war immer: „Wie kann ich die Reihenfolge der Sidebar-Ordner anpassen, wenn ich die Sidebar automatisch generiere?“ Alte Probleme wie #1223 schlagen eine Lösung vor, die von Nuxt Content inspiriert ist, bei der jeder Abschnitt des gesamten Pfads mit Zahlen + Punkten vorangestellt werden kann, um eine nummerische Sortierung auf Dateibasis festzulegen. Ein Beispiel für ein solches Projekt könnte so aussehen:
Directorysrc/content/docs/nested-folder
Directory1.frameworks
- 1.vue.md
- 2.nuxt.md
Directory2.examples
- 1.vercel.md
- 2.netlify.md
Wenn Sie diesen Ansatz in Starlight verwenden möchten, funktioniert er nicht sofort, aber mit einer einfachen Einrichtung können Sie ihn umsetzen.
Starlight 0.35.0 führte eine Callback-Funktion ein, die Sie an docsLoader()
übergeben können, um die ID (URL) der generierten Seite zu manipulieren. Indem Sie den Eintrag durch "/"
aufteilen und jede Zahl + Punkt auf Segmentebene entfernen, haben Sie nun die gleiche Funktionalität in Starlight:
import { defineCollection } from "astro:content";import { docsLoader } from "@astrojs/starlight/loaders";import { docsSchema } from "@astrojs/starlight/schema";
const leadingNumberAndDotRegEx = /^\d+\./;const fileExtensionRegEx = /\.(md|mdx)$/;
export const collections = { docs: defineCollection({ loader: docsLoader({ // Remove file extension and // leading numbers + dot from each segment generateId: ({ entry }) => entry .replace(fileExtensionRegEx, "") .split("/") .map((segment) => segment.replace(leadingNumberAndDotRegEx, "")) .join("/"), }), schema: docsSchema(), }),};
Die URL zum Zugriff auf die Seiten ändert sich nun z. B. von /nested-folder/1.frameworks/1.vue
zu /nested-folder/frameworks/vue
.
Allerdings enthalten die Ordnernamen in der Sidebar immer noch die 1.
-Präfixe. Lassen Sie uns also auch die Manipulation der Sidebar lösen:
Starlight 0.32.0 führte Route Data ein, das wir jetzt nutzen können, um die Ordnernamen in der Sidebar zu manipulieren:
- das Entfernen jeder führenden Zahl + Punkt aus dem Ordnernamen und
- die Anwendung von “Title Case”, damit sie nicht vollständig kleingeschrieben erscheinen
import { defineRouteMiddleware } from "@astrojs/starlight/route-data";
const leadingNumberAndDotRegEx = /^\d+\./;const wordSplitterRegEx = /\w\S*/g;
function toTitleCase(str: string) { return str.replace(wordSplitterRegEx, (word) => { return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(); });}
function cleanGroupLabels(entries: any[]) { for (const entry of entries) { if (entry.type === "group") { // Remove leading number + dot let label = entry.label.replace(leadingNumberAndDotRegEx, ""); // Convert to Title Case entry.label = toTitleCase(label); // Recurse into children cleanGroupLabels(entry.entries); } }}
export const onRequest = defineRouteMiddleware((context) => { const { sidebar } = context.locals.starlightRoute; cleanGroupLabels(sidebar);});
Beachten Sie, dass die Internationalisierung (i18n) von Ordnernamen bei einem solchen Setup eine fehlende Funktionalität ist, da es derzeit keinen Ort gibt, an dem Übersetzungen von Ordnernamen definiert werden können. Sie werden einfach in Title Case umgewandelt. Die Implementierung einer Logik zum dynamischen Laden von Übersetzungen könnte darin bestehen, das locale
-Feld aus den Routeninformationen zu lesen und Übersetzungen in json
-Dateien zu definieren. Andernfalls können Sie HiDeoos Plugin verwenden, das i18n unterstützt.
Vergessen Sie nicht, die Datei routeData.ts
zu Ihrer astro.config.mjs
hinzuzufügen:
starlight({ title: "Autogenerate whole sidebar", social: [{ icon: "github", label: "GitHub", href: "https://github.com/withastro/starlight" }], sidebar: [ { label: "Root Folder", autogenerate: { directory: "nested-folder" }, }, ], routeMiddleware: "./src/routeData.ts", }),
Natürlich können Sie den Code an Ihre Bedürfnisse anpassen (z. B. die “Title Case”-Transformation entfernen, da Ihre Dateinamen bereits korrekt geschrieben sind).
Wenn Sie Ihre gesamte Sidebar automatisch generieren und dennoch die Flexibilität haben möchten, alles nach Ihren Wünschen anzupassen, hat HiDeoo auch ein dediziertes Plugin für solche Anwendungsfälle erstellt: Starlight Auto Sidebar.
Insbesondere wurden diese zwei Funktionen in diesem Artikel erwähnt:
- Die Steuerung der Reihenfolge einzelner Verzeichnisse
- Die Anpassung der angezeigten Beschriftung einzelner Ordner
Wenn Sie jedoch die gesamte automatische Generierung durchführen möchten, ohne für jedes Verzeichnis manuell Beschriftungen und Reihenfolgen festlegen zu müssen, ist es bevorzugt und empfohlen, die Lösung selbst zu programmieren (mit einigen Richtlinien in diesem Blog).
Wenn Sie den in diesem Blog vorgestellten Code ausprobieren möchten, besuchen Sie gerne die StackBlitz oder den Quellcode im GitHub-Repo.