Doku-Vollausbau: 62 Seiten (Projekt/Admin/Anwender/Referenz), Hook-Referenz mit Signaturen, Corporate-Screenshots, Coverage-Inventar
Deploy tibi-docs / build-and-deploy (push) Failing after 38s

- Einstieg: Schnellstart + Neues Projekt aus Starter-Skill, Was-ist-Tibi mit Backend/Website-Trennung
- Projekt: Sammlungen, Felder, Abfragen, Rechte, Hooks, Dateien, i18n, Suche, SSR, Pagebuilder, Jobs, Audit, Deploy, LLM, MCP
- Hook-Referenz: 66 Symbole mit Signatur + Beispiel + Fehlerfall (5 Kapitel)
- Admin: Ansichten, Editor, Medien, Exporte, Aktionen, Rechte, KI, Setup, Customizing
- Anwender: 11 Anleitungen im professionellen Du-Ton, 30 Corporate-Screenshots
- Referenz: Schemas, Token-Köpfe, Fehlerbilder, Shortcuts, OpenAPI-Platzhalter
- ADR-0001 bis 0003, Coverage-Skript (282 Items) + Map, Plan-Dateien
This commit is contained in:
apairon committed 2026-10-16 22:49:07 +00:00
1 parent acb1d32355
commit 1897bb50d9
101 files changed
+8980 -68

No files matched your search

+119
View File
@@ -0,0 +1,119 @@
---
title: 'Navigation und Sprachen'
description: 'Navigations-Collection, Sprachfelder, translationKey, Pfad-Regeln.'
---
import { Aside, Tabs, TabItem, Steps } from '@astrojs/starlight/components';
Navigation und Sprachen hängen zusammen: Die `navigation`-Sammlung hält je Sprache einen Baum, `content` hält je Sprache einen Eintrag.
Suche-Begriffe: Navigation anlegen, Sprache umschalten, translationKey.
## Navigations-Dokumente
`api/collections/navigation.yml` kennt genau vier Singleton-Bäume: `type` (`header`, `footer`) mal `language` (`de`, `en`) — abgesichert per Unique-Index `type_language`.
```yaml title="navigation.yml — Felder (gekürzt)"
# navigation.yml — Felder (gekürzt)
fields:
- name: language # de | en, Pflicht
- name: type # header | footer, Pflicht
- name: elements # object[]: {name, page?, external?, externalUrl?, hash?, elements?}
```
| Element-Art | Felder | Beispiel |
|---|---|---|
| Intern | `name` + `page` (= `content`-ID) | `{name: "Start", page: "<content.id>"}` |
| Extern | `name` + `external: true` + `externalUrl` | `{name: "Blog", external: true, externalUrl: "https://…"}` |
| Anker | zusätzlich `hash` ohne `#`, Muster `^[a-zA-Z0-9_-]+$` | `{name: "Kontakt", page: "<id>", hash: "kontakt"}` |
| Unterpunkt | geschachtelt in `elements.elements` | Header max. 2 Ebenen, Footer max. 1 |
<Steps>
1. Lege je Sprache einen Header und einen Footer an, je mit `active:true` (Pflicht trotz fehlendem Schema-Feld — siehe Kasten unten).
2. Löse Seiten mit Lookup auf:
```text title="Seiten per Lookup auflösen"
GET …/navigation?lookup=elements.page:content
```
3. Baue den Link aus dem Lookup: `href` = lokalisierter `_lookup.page.path` plus `hash`. Den `/de`-Präfix nie in die DB schreiben.
</Steps>
<Aside type="caution" title="active:true auch hier">
`filter_public.js` filtert anonym `active:true` — `navigation.yml` deklariert kein solches Feld.
Ohne gespeichertes `active:true` liefert die öffentliche Abfrage `count 0` (Vorfall 2026-10-05), mit Token sieht alles gut aus.
Lege `active:true` auf jedem Navigations-Dokument ab.
</Aside>
## Sprachmodell: lang + translationKey
`content.yml` nutzt Entry-i18n: eine Sprache je Eintrag, verbunden über den Schlüssel.
```yaml title="content.yml — i18n-Block (gekürzt)"
# content.yml — i18n-Block (gekürzt)
meta:
i18n:
entry:
languageField: lang
groupField: translationKey
```
| Regel | Konkret |
|---|---|
| `lang` | Sprachkürzel, z. B. `de`, `en` |
| `translationKey` | **Pflicht**, z. B. `home`, `ueber-uns` — pro Sprache eindeutig (Unique-Index `translationKey` + `lang`) |
| Zweiter Datensatz ohne Schlüssel | Kollidiert auf `null` — kein „geht schon gut" |
| `path` | Ohne Sprachpräfix gespeichert (`/ueber-uns`), URL mit Präfix (`/de/ueber-uns`) |
| `alternativePaths[].path` | Alte Pfade, gleiches Muster wie `path` |
Die Feld-i18n (Tabs je Feld, Test-Plan `34-i18n-fields`) und Entry-i18n (eine Sprache je Eintrag, Test-Plan `35-entry-i18n`) pflegst du im tibi-admin; das Datenmodell aus Projekt-Sicht ist immer `lang` + `translationKey`.
## Pfad-Regeln
```text title="Pfad-Muster für path und alternativePaths"
^/[a-z0-9-/]*$ → gilt für path und alternativePaths[].path
```
- Nur Kleinbuchstaben, Ziffern, `-` und `/`; keine Großbuchstaben, keine Umlaute (`/ueber-uns` statt `/Über-uns`).
- Unique-Index `path` + `lang`: gleicher Pfad in `de` und `en` ist okay, zweimal in `de` nicht.
- SSR streift den Präfix vor der Suche ab und liefert die kanonische URL zurück (`hooks/config.js` → `ssrValidatePath`).
## active:true auch hier (Checkliste)
| Sammlung | Ohne `active:true` öffentlich … |
|---|---|
| `content` | … filtern `filter_public` + SSR-Prüfung den Eintrag weg |
| `medialib` | … bleibt `_lookup` leer, Bilder verschwinden (siehe [Dateien und Bilder](/projekt/dateien-bilder/)) |
| `navigation` | … ist Header/Footer leer |
## Prüfung: anonyme SSR-Nav-Zahl
<Tabs>
<TabItem label="Deutsch + Englisch testen">
```text title="Navigation je Sprache prüfen (anonym)"
GET …/navigation?filter={"language":"de"}
GET …/navigation?filter={"language":"en"}
# anonym (ohne Token) müssen beide je einen Header und einen Footer liefern
```
</TabItem>
<TabItem label="SSR-Cache prüfen">
```text title="SSR-Cache prüfen"
GET …/ssr?url=/de/
# im HTML: window.__SSR_CACHE__ enthält das Ergebnis je Request (cacheKey mit data + count) — Navigation darin je Sprache mit count > 0 prüfen; die Abhängigkeiten selbst stehen separat im ssr-Dokument (Feld dependencies)
```
</TabItem>
</Tabs>
| Fehlerbild | Ursache | Lösung |
|---|---|---|
| Öffentliche Nav leer, mit Token voll | `active:true` fehlt | Auf allen vier Bäumen setzen |
| `409` beim zweiten Spracheintrag | `translationKey` fehlt oder doppelt | Eindeutigen Schlüssel je Sprache vergeben |
| `400` beim Speichern | Pfad mit Großbuchstaben/Umlaut | Kleinschreiben, Muster einhalten |
| Falsche Sprache im SSR | `lang`-Feld passt nicht zum Präfix | `lang` und URL-Präfix angleichen |
Weiter: [Lesen und suchen](/projekt/abfragen-lesen/), [Dateien und Bilder](/projekt/dateien-bilder/), [Rechte und Tokens](/projekt/rechte-tokens/).
Verifiziert am e3f92ebf 2026-10-14 (tibi-svelte-starter), am 2b091d89 2026-10-13 (tibi-admin-nova, Test-Pläne 34-i18n-fields, 35-entry-i18n)