Internationalisierung (i18n)¶
Übersicht¶
Die xynap Platform bietet ein globales i18n-System mit automatischer Übersetzung, Redis-Caching und Admin-Verwaltung.
| Komponente | Technologie |
|---|---|
| Übersetzungs-API | FastAPI /api/v1/i18n/ |
| Cache | Redis Hash (i18n:bundle:{locale}, TTL 1h) |
| Auto-Übersetzer | LibreTranslate (lokal) |
| Source-of-Truth | en.json (englische Quelltexte) |
| Frontend | vue-i18n mit dynamischem Laden |
| Admin-UI | Settings → Sprachen |
Architektur¶
Frontend (Vue) Backend API Storage
┌─────────────┐ GET /i18n ┌──────────────┐ ┌──────────┐
│ vue-i18n │ ──────────→ │ i18n Router │ ──→│ Redis │ (Cache)
│ loadMessages │ /{locale} │ │ └──────────┘
└─────────────┘ │ │ ↓ miss
│ │ ┌──────────┐
│ │ ──→│ DB │ (translations)
│ │ └──────────┘
│ │ ↓ miss
│ │ ┌──────────┐
│ │ ──→│ en.json │ + Auto-Translate
└──────────────┘ └──────────┘
Lookup-Kette¶
- Redis —
HGETALL i18n:bundle:{locale}→ sofort zurück - DB —
translations-Tabelle → in Redis cachen - en.json + LibreTranslate → übersetzen, in DB + Redis speichern
- Fallback — Key selbst zurückgeben
Öffentliche API-Endpoints¶
Kein Auth erforderlich.
Sprachen auflisten¶
Response:
[
{"code": "de", "label": "Deutsch"},
{"code": "en", "label": "English"},
{"code": "es", "label": "Español"}
]
Übersetzungs-Bundle laden¶
Liefert alle Übersetzungs-Keys als flaches JSON. Unterstützt ETag/If-None-Match für Conditional Requests (304 Not Modified).
Response-Header:
Response-Body:
{
"error.not_found": "Nicht gefunden",
"auth.login_success": "Anmeldung erfolgreich",
"invoice.created": "Rechnung {number} erstellt"
}
Einzelnen Key abrufen¶
Admin-Endpoints¶
Erfordern settings.manage Permission.
Sprache hinzufügen¶
Beim ersten Bundle-Abruf der neuen Sprache werden alle Keys automatisch via LibreTranslate übersetzt.
Sprache entfernen¶
Einschränkung
de und en können nicht entfernt werden.
Manuelle Übersetzung setzen¶
PUT /api/v1/i18n/admin/translations/{locale}/{key}
Content-Type: application/json
{"value": "Benutzer nicht gefunden"}
Überschreibt automatische Übersetzungen. Wird als auto_translated=false markiert.
Übersetzungen neu generieren (Rebuild)¶
Generiert alle veralteten (stale) Übersetzungen neu via LibreTranslate.
Auto-Übersetzungen verwerfen (Forget)¶
Löscht alle Auto-Übersetzungen einer Sprache. Werden beim nächsten Abruf frisch erzeugt.
Statistiken¶
{
"total_keys": 111,
"languages": [
{
"code": "de", "label": "Deutsch",
"total": 111, "translated": 111,
"auto": 0, "manual": 111, "stale": 0
}
]
}
Veraltete Übersetzungen¶
Stale-Detection¶
Jede Übersetzung speichert den MD5-Hash des englischen Quelltexts (source_hash). Wenn sich en.json ändert:
- Hash stimmt nicht mehr überein
- Übersetzung wird als
stale=truemarkiert - Beim nächsten Bundle-Abruf oder Rebuild wird sie automatisch neu übersetzt
Frontend-Integration¶
Statische Dateien (Fallback)¶
de.ts und en.ts sind sofort verfügbar beim Laden — kein Flash of Untranslated Content.
Dynamisches Laden¶
Nach dem Mount lädt das Frontend die Übersetzungen von der API:
import { loadMessages } from '@/i18n/loader'
const msgs = await loadMessages('de')
// → API-Call mit ETag-Cache → localStorage-Cache
Sprachwechsel¶
import { useLocale } from '@/shell/composables/useLocale'
const { locale, languages, setLocale, toggleLocale } = useLocale()
// Verfügbare Sprachen (dynamisch von API)
// languages.value → [{code: 'de', label: 'Deutsch'}, ...]
setLocale('es') // Lädt automatisch das spanische Bundle
Dateien¶
| Datei | Beschreibung |
|---|---|
app/core_models/translation.py |
DB-Model (translations-Tabelle) |
app/i18n/cache.py |
Redis-Cache-Layer |
app/i18n/translator.py |
LibreTranslate-Client |
app/i18n/service.py |
Translation-Service (Kern-Logik) |
app/i18n/router.py |
API-Endpoints |
app/i18n/__init__.py |
t(key, locale) Funktion |
frontend/src/i18n/loader.ts |
API-basierter Loader |
frontend/src/shell/composables/useLocale.ts |
Locale-Composable |
frontend/src/shell/settings/SettingsLanguages.vue |
Admin-UI |