Zum Inhalt

Internationalisierung

AdaptiveLearner läuft in 8 Sprachen. Fünf sind nativ (DE, EN, ES, FR, EL) mit echten Übersetzungen. Drei (PT, TR, JA) sind aktuell englischer Durchgriff — sie haben alle Schlüssel, aber die Werte sind noch Englisch und warten auf Muttersprachler- Beiträge.

Wo die Strings liegen

Backend

YAML-Kataloge in backend/config/i18n/{lang}.yaml — eine Datei pro Sprache. Der Referenzkatalog ist EN; jeder andere muss denselben Schlüssel-Baum haben.

# backend/config/i18n/de.yaml
common:
  save: Speichern
  cancel: Abbrechen
settings:
  title: Einstellungen
  section_language: Sprache
  ...

Das Backend exponiert GET /api/i18n/{lang}, das den ganzen Katalog als JSON zurückgibt. Der useI18n-Hook im Frontend ruft es beim ersten Paint und cachet das Ergebnis.

Frontend-Fallbacks

frontend/src/i18n/fallbacks.ts trägt einen Inline-Subset von Strings, hart ins Frontend-Bundle kodiert. Diese zeigen sich beim ersten Paint, bevor der Backend-Katalog geladen ist — und als permanenter Fallback, wenn der Katalog-Endpunkt 5xx liefert.

Die Fallback-Auflösungskette in useI18n:

  1. Backend-Katalog (Live-Strings aus /api/i18n/{lang}). Dot-Notation-Pfad walken.
  2. Hartkodierte Frontend-Fallbacks (Erstpaint-Resilienz).
  3. Vom Aufrufer übergebener Fallback-String.
  4. Der Schlüssel selbst.

In-App-Hilfe / Docs-Site

docs/help/_meta.yaml deklariert den Navigationsbaum mit DE+EN-Titeln pro Eintrag. Die in-app Hilfe-Sektion liest das direkt; scripts/generate_mkdocs_nav.py regeneriert den mkdocs.yml-Nav-Block aus derselben Quelle.

Hilfeseiten-Markdown liegt in docs/help/{lang}/... — ein Ordner pro Sprache. mkdocs-static-i18ns docs_structure: folder- Modus erledigt die Auflösung.

Neue Sprache hinzufügen

  1. Backend-Katalog: backend/config/i18n/en.yaml nach backend/config/i18n/{neuelang}.yaml kopieren. Jeden Wert übersetzen (oder als englische Platzhalter für einen Durchgriff stehen lassen).
  2. Frontend-Konstanten: Sprachcode zu SUPPORTED_LANGUAGES in frontend/src/lib/constants.ts hinzufügen.
  3. Frontend-Fallbacks: einen {neuelang}: {...}-Block zu frontend/src/i18n/fallbacks.ts mit dem kleinen Subset der Erstpaint-Strings hinzufügen.
  4. Test-Fragen: plugins/adaptive-learner-plugin-assessment/adaptive_learner_assessment/questions.py editieren — ein text_{neuelang}-Feld zu jedem QUESTIONS-Eintrag und jeder Antwort hinzufügen. JSON neu exportieren.
  5. Session-Prompts: plugins/adaptive-learner-plugin-session/adaptive_learner_session/prompts.py editieren — einen dritten Sprachschlüssel in jede (Methode, Schritt)-Zelle einfügen. JSON neu exportieren.
  6. Docs-Site: mkdocs.ymls plugins.i18n.languages-Block aktualisieren und ein docs/help/{neuelang}/-Verzeichnis spiegelnd zur EN-Struktur anlegen.

Parität-Tests

backend/tests/test_i18n_parity.py läuft über jeden Katalog und prüft:

  • Jede Sprache hat jeden Schlüssel, den die Referenz (EN) hat.
  • Keine Sprache hat einen zusätzlichen Schlüssel, den die Referenz nicht hat.

Das fängt den häufigsten Drift-Bug: jemand fügt einen Key in EN hinzu und vergisst die anderen 7 Dateien. Nach jeder Katalog-Änderung make test-backend laufen lassen.

Plurale

Die aktuellen Kataloge nutzen keine ICU-Plural-Syntax. Die wenigen Zähler, die wir rendern (Session-Anzahl, Streak-Tage), machen Hartwahl in TS:

const label = count === 1 ? t("session_single") : t("session_plural");

ICU-Plural-Strings via mkdocs-i18n oder eine Runtime-ICU- Library steht auf der Folge-Liste.

RTL-Sprachen

Arabisch, Hebräisch, Persisch etc. bräuchten bidirektionale Layout-Unterstützung im CSS. Das aktuelle Theme nimmt LTR an; RTL steht auf der Folge-Liste.

Wann KEINE Übersetzung anlegen

Wenn ein String nur in Entwickler-Oberflächen erscheint (Fehlermeldungen von AdaptiveLearnerError, Log-Zeilen, Test-Fixture-Daten), Englisch lassen. Die i18n-Maschinerie ist nur für End-User-sichtbare Strings da.

console.warn und console.error im Frontend bleiben ebenfalls Englisch — sie sind für Entwickler an der Browser- Konsole, nicht für Endnutzer.