Implémentation i18n¶
KanjiIQ utilise le framework d'internationalisation intégré de Flutter avec des fichiers ARB (Application Resource Bundle) pour la localisation de l'interface et PostgreSQL JSONB pour la localisation du contenu.
Localisation de l'interface avec ARB¶
Configuration¶
Le système de localisation est configuré dans frontend/l10n.yaml :
Structure des fichiers ARB¶
Chaque langue dispose d'un fichier ARB suivant le format de message ICU :
// lib/l10n/app_en.arb (template)
{
"@@locale": "en",
"appTitle": "KanjiIQ",
"studyButton": "Start Study",
"selectLanguage": "Select Language",
"selectLevel": "Select JLPT Level",
"cardCount": "{count} cards",
"@cardCount": {
"placeholders": {
"count": { "type": "int" }
}
},
"noConnection": "No internet connection. Using cached data.",
"showAllLanguages": "Show all 51 languages"
}
Génération de code¶
L'exécution de flutter gen-l10n génère :
app_localizations.dart— Classe de base abstraite avec toutes les chaînes localiséesapp_localizations_en.dart— Implémentation anglaiseapp_localizations_ja.dart— Implémentation japonaise- ... (51 fichiers générés)
Utilisation dans les widgets Flutter :
// Access localized strings
Text(AppLocalizations.of(context)!.studyButton)
// With parameters
Text(AppLocalizations.of(context)!.cardCount(10))
Enregistrement des locales prises en charge¶
Les locales sont enregistrées dans MaterialApp :
MaterialApp(
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
locale: selectedLocale, // From LocalePreferences
)
Localisation du contenu¶
Le contenu des flashcards (significations des kanji, définitions de vocabulaire) est stocké en JSONB dans PostgreSQL et servi via l'API :
graph LR
A[API Request<br/>?lang=pt] --> B[Backend]
B --> C[PostgreSQL<br/>JSONB lookup]
C --> D[Return meaning<br/>in Portuguese]
Pipeline de traduction¶
Le nouveau contenu est traduit via l'API OpenAI :
- Le contenu source est rédigé en anglais
- Le backend envoie des requêtes de traduction à OpenAI avec le contexte du niveau JLPT et de l'usage
- Les traductions sont stockées dans la colonne JSONB aux côtés des traductions existantes
- Chaque langue peut être mise à jour indépendamment sans affecter les autres
Traduction auto-hébergée
Les manifestes Kubernetes incluent un déploiement LibreTranslate (k8s/04-libretranslate-deployment.yaml) comme alternative à OpenAI. Cela fournit une traduction entièrement auto-hébergée sans dépendances à des API externes, bien que la qualité varie selon les paires de langues.
Langue de l'interface vs langue du contenu¶
KanjiIQ permet de dissocier la langue de l'interface et la langue d'étude :
- Langue de l'interface : La langue des boutons, libellés et de la navigation (ex. : français)
- Langue d'étude : La langue des significations des flashcards (ex. : portugais)
Un utilisateur francophone étudiant le japonais peut avoir l'interface en français tout en voyant les significations des flashcards en portugais s'il le préfère.
Ajouter une nouvelle langue¶
Pour ajouter une nouvelle (52e) langue :
- Interface : Créer
lib/l10n/app_XX.arbavec toutes les chaînes traduites - Contenu : Ajouter les traductions aux colonnes JSONB via le pipeline de traduction
- Configuration de la locale : Ajouter le code de langue aux entrées
locale_configspertinentes via l'API administrateur - Build : Exécuter
flutter gen-l10npour régénérer les fichiers de localisation
Aucune migration de schéma ni modification du code backend n'est nécessaire — le stockage JSONB et le système ARB sont tous deux conçus pour l'extensibilité.