Files
Oxicloud/doc/i18n.md
T
2026-04-01 23:14:42 +02:00

101 lines
3.1 KiB
Markdown

# 16 - Internationalization
JSON-based translation system. Translations are loaded from static files, cached in memory, and served via a public REST API (no auth required).
## Supported Languages
| Locale | Code | File |
|---|---|---|
| English | `en` | `static/locales/en.json` |
| Spanish | `es` | `static/locales/es.json` |
| French | `fr` | `static/locales/fr.json` |
| German | `de` | `static/locales/de.json` |
| Portuguese | `pt` | `static/locales/pt.json` |
| Persian | `fa` | `static/locales/fa.json` |
| Chinese | `zh` | `static/locales/zh.json` |
| Dutch | `nl` | `static/locales/nl.json` |
Default locale: **en** (English).
## Architecture
| Layer | Component | File |
|---|---|---|
| Domain Port | **I18nService** trait, **Locale** enum | `src/domain/services/i18n_service.rs` |
| Application Service | **I18nApplicationService** | `src/application/services/i18n_application_service.rs` |
| Application DTOs | **LocaleDto**, **TranslationRequestDto**, etc. | `src/application/dtos/i18n_dto.rs` |
| Infrastructure | **FileSystemI18nService** | `src/infrastructure/services/file_system_i18n_service.rs` |
| Interfaces | **I18nHandler** | `src/interfaces/api/handlers/i18n_handler.rs` |
## REST API
Public endpoints (no authentication), under `/api/i18n`:
| Method | Path | Handler | Description |
|---|---|---|---|
| `GET` | `/api/i18n/locales` | `get_locales` | List available locales |
| `GET` | `/api/i18n/translate` | `translate` | Translate a key (`?key=...&locale=...`) |
| `GET` | `/api/i18n/locales/{locale_code}` | `get_translations_by_locale` | Get all translations for a locale |
### Examples
```bash
# List available locales
curl "https://oxicloud.example.com/api/i18n/locales"
# [{"code":"en","name":"English"},{"code":"es","name":"Spanish"}, ...]
# Translate a key
curl "https://oxicloud.example.com/api/i18n/translate?key=app.title&locale=es"
# {"key":"app.title","locale":"es","text":"OxiCloud"}
# Get all translations for a locale
curl "https://oxicloud.example.com/api/i18n/locales/en"
# { "app": { "title": "OxiCloud", ... }, "nav": { ... }, ... }
```
## Translation File Format
Nested JSON with dot-delimited key lookups:
```json
{
"app": {
"title": "OxiCloud",
"description": "Your personal cloud storage"
},
"nav": {
"files": "Files",
"shared": "Shared",
"recent": "Recent",
"favorites": "Favorites",
"trash": "Trash"
},
"actions": {
"search": "Search files...",
"new_folder": "New folder",
"upload": "Upload",
"download": "Download",
"delete": "Delete"
},
"share": { ... },
"user_menu": { ... }
}
```
Key lookup: `"nav.files"` resolves to `"Files"`.
## Fallback Behavior
If a key is missing in the requested locale, the system falls back to English (`en`). If still not found, returns an `I18nError::KeyNotFound`.
## Caching
Translations are cached in-memory via `RwLock<HashMap<Locale, serde_json::Value>>`. Loaded lazily on first request per locale.
## Frontend Integration
The frontend uses `static/js/i18n.js` and `static/js/languageSelector.js` to:
1. Detect the user's preferred language
2. Load translations via `/api/i18n/locales/{code}`
3. Apply translations to DOM elements