Statische Seiten via Pull-API (Starlight, Astro, Hugo …)
Orimora kann die Inhaltsquelle einer statischen Seite sein, ohne einen Git-Mirror dazwischen. Die Seite zieht die veröffentlichten Dokumente eines freigegebenen Ordners zur Build-Zeit aus Orimoras token-gesicherter Pull-API und rendert sie — Orimora bleibt die einzige Quelle der Wahrheit, und es gibt kein separates Inhalts-Repository zu pflegen.
Das funktioniert mit jedem Generator, der Markdown + Frontmatter liest (Astro/Starlight, Hugo, Jekyll, Eleventy, …). Das Beispiel nutzt Starlight.
So funktioniert’s
Abschnitt betitelt „So funktioniert’s“- Du legst in Orimora eine Ordnerfreigabe für eine Collection an. Sie erzeugt ein nur-lesendes, nur-veröffentlichtes Token, das genau auf diesen Ordner beschränkt ist — nur dessen veröffentlichte Dokumente werden je sichtbar (kein Entwurfs-Leak).
- Ein kleines Pull-Skript läuft vor jedem Build, holt den veröffentlichten Satz als Markdown aus der Pull-API und schreibt eine Markdown-Datei pro Dokument.
- Der Generator baut wie gewohnt aus diesen Dateien.
Zuerst: SSG oder SSR? Zwei sehr verschiedene Wege
Abschnitt betitelt „Zuerst: SSG oder SSR? Zwei sehr verschiedene Wege“Dieses Rezept gilt für statische Generatoren (SSG: Starlight, Hugo, Jekyll, Eleventy …) — sie übernehmen Inhalte nur zur Build-Zeit, weshalb ein Pull-Skript und ein Rebuild-Auslöser nötig sind.
Server-gerenderte Apps (SSR/ISR — Next.js, Nuxt, SvelteKit …) brauchen dieses
Rezept nicht. Sie rufen die Pull-API einfach zur Request-Zeit auf (mit Cache
davor) — kein Build, kein Hook, Veröffentlichung ist sofort live. Die API unterstützt
updatedSince für inkrementelle Abrufe.
1. Ordnerfreigabe in Orimora anlegen
Abschnitt betitelt „1. Ordnerfreigabe in Orimora anlegen“- Öffne in der Seitenleiste das Menü einer Collection (Kebab oder Rechtsklick) und
wähle „Mit Dienst verbinden…”. (Benötigt die Capability
collection.share— standardmäßig nur für Admins.) - Wähle den Zieltyp Statische Website (SSG) und erstelle die Freigabe. Orimora erzeugt ein Lese-Token und zeigt es einmalig — jetzt kopieren und wie ein Passwort aufbewahren. Der Dialog zeigt auch den API-Endpunkt.
- Notiere die Collection-ID (steht in der Collection-URL) — das Pull-Skript filtert darauf.
Du hast nun drei Werte für das Skript: die Orimora-Basis-URL, die Collection-ID und das Token.
Sofort verifizieren
Abschnitt betitelt „Sofort verifizieren“Bevor Du irgendetwas baust, teste die Kette mit curl:
curl -H "Authorization: Bearer <token>" \ "https://wiki.example.com/api/v1/documents?collectionId=<collection-id>&format=markdown"Du musst die veröffentlichten Dokumente des Ordners als JSON sehen (data: [...]),
jeweils mit einem markdownText-Body und einem slug. Ein 401 heißt, das Token ist
falsch; ein 403, dass das Token nicht auf diese Collection beschränkt ist; ein leeres
data, dass der Ordner noch keine veröffentlichten Dokumente hat (Entwürfe erscheinen nie).
2. Das Pull-Skript
Abschnitt betitelt „2. Das Pull-Skript“Lege das als scripts/pull-orimora.mjs in Dein Seiten-Repo. Es blättert (offset-basiert)
durch die Pull-API und schreibt src/content/docs/orimora/<slug>.md:
import { mkdir, rm, writeFile } from 'node:fs/promises';import { join } from 'node:path';
const BASE = process.env.ORIMORA_URL; // z. B. https://wiki.example.comconst COLLECTION = process.env.ORIMORA_COLLECTION; // Collection-IDconst TOKEN = process.env.ORIMORA_TOKEN; // Ordnerfreigabe-Token (kb_…)const OUT = 'src/content/docs/orimora'; // Zielverzeichnisconst PAGE = 200;
if (!BASE || !COLLECTION || !TOKEN) { throw new Error('ORIMORA_URL, ORIMORA_COLLECTION und ORIMORA_TOKEN setzen');}
async function pull() { const docs = []; let offset = 0; let total = Infinity; do { const url = new URL(`${BASE}/api/v1/documents`); url.searchParams.set('collectionId', COLLECTION); url.searchParams.set('format', 'markdown'); url.searchParams.set('limit', String(PAGE)); url.searchParams.set('offset', String(offset)); const res = await fetch(url, { headers: { Authorization: `Bearer ${TOKEN}` } }); if (!res.ok) throw new Error(`Pull fehlgeschlagen: ${res.status} ${res.statusText}`); const { data, total: t } = await res.json(); docs.push(...data); total = typeof t === 'number' ? t : docs.length; offset += PAGE; } while (docs.length < total && offset < total); return docs;}
function toMarkdownFile(doc) { // `markdownText` ist der serialisierte Body (?format=markdown). Nur der Titel // wandert als Frontmatter — Starlights docsSchema verlangt ihn. const fm = { title: doc.title }; const yaml = Object.entries(fm) .filter(([, v]) => v !== null && v !== undefined) .map(([k, v]) => `${k}: ${JSON.stringify(v)}`) .join('\n'); return `---\n${yaml}\n---\n\n${doc.markdownText ?? ''}`;}
const docs = await pull();await rm(OUT, { recursive: true, force: true });await mkdir(OUT, { recursive: true });for (const doc of docs) { await writeFile(join(OUT, `${doc.slug}.md`), toMarkdownFile(doc), 'utf-8');}console.log(`${docs.length} Dokument(e) aus Orimora nach ${OUT} gezogen`);3. Vor dem Build ausführen
Abschnitt betitelt „3. Vor dem Build ausführen“Als prebuild-Schritt verdrahten, damit jeder Build die Inhalte auffrischt:
{ "scripts": { "prebuild": "node scripts/pull-orimora.mjs", "build": "astro build" }}npm run build zieht jetzt erst, dann baut es. Auf einem Host wie
Netlify/Vercel/Cloudflare Pages ORIMORA_URL, ORIMORA_COLLECTION, ORIMORA_TOKEN
als Build-Umgebungsvariablen setzen.
4. Rebuild auslösen
Abschnitt betitelt „4. Rebuild auslösen“Veröffentlichen schreibt nur nach Orimora — eine statische Seite zeigt den Inhalt erst nach dem nächsten Build. Löse ihn über Deinen Host aus: geplanter Build, manueller Deploy oder ein Git-Push. (Automatischer Rebuild-bei-Veröffentlichung für Ordnerfreigaben ist geplant.) Bei SSR/ISR-Apps stellt sich die Frage nicht — sie lesen die Pull-API live.
Pull-API-Referenz
Abschnitt betitelt „Pull-API-Referenz“GET /api/v1/documents — Authorization: Bearer <token>.
| Query | Bedeutung |
|---|---|
collectionId | Auf einen Ordner filtern (die Collection der Freigabe) |
format | markdown → markdownText-Body + abgeleiteten slug ergänzen |
limit | 1–100 (Default 25) |
offset | Offset-Paginierung; die Antwort trägt total |
updatedSince | ISO-Zeitstempel — nur Dokumente, die danach geändert wurden |
Jedes Element: id, title, emoji, collectionId, collectionName,
collectionSlug, updatedAt, publishedAt, tags und — mit
?format=markdown — slug und markdownText. Ein nur-veröffentlicht-Token
einer Freigabe liefert unabhängig von einem status-Parameter nur veröffentlichte
Dokumente.
Fallstudie: Diese Doku füttert sich selbst
Abschnitt betitelt „Fallstudie: Diese Doku füttert sich selbst“Der Praxistipps-Bereich genau dieser Doku wird live aus Orimora gezogen — mit exakt diesem Rezept, als Realitätscheck des Features:
- Die Tipps liegen in einer Praxistipps-Collection in Orimora, bereitgestellt über eine Ordnerfreigabe (nur-lesend, nur-veröffentlicht).
docs/scripts/pull-orimora.mjsläuft vor jedemastro buildund holt den Satz über die Pull-API. Env-Vars:ORIMORA_URL,ORIMORA_PRAXISTIPPS_COLLECTION,ORIMORA_PRAXISTIPPS_TOKEN— in Coolify auf der Docs-App gesetzt und als Docker-Build-Args durchgereicht (siehe Hinweis oben).- Bewusst robust: Fehlen die Variablen oder ist Orimora nicht erreichbar, überspringt das Skript mit Exit 0 — ein Orimora-Ausfall kann den Doku-Build nie brechen; der committete Platzhalter-Index bleibt stehen.
- Verifikation: Im Build-Log steht
[pull-orimora] Pulled N Praxistipp(s)(bzw. die Skip-Begründung).
Siehe auch
Abschnitt betitelt „Siehe auch“- REST-API Überblick — Auth, Rate-Limits, Pagination
- WordPress — denselben Ordner stattdessen nach WordPress importieren
- Kirby — dasselbe Pull-Muster für Kirby
- Git-Mirror — einen Ordner in ein Git-Repo pushen (statt dass die Seite zieht)