i18n实现¶
KanjiIQ使用Flutter内置的国际化框架,通过ARB(Application Resource Bundle)文件进行UI本地化,通过PostgreSQL JSONB进行内容本地化。
基于ARB的UI本地化¶
配置¶
本地化系统在frontend/l10n.yaml中配置:
ARB文件结构¶
每种语言都有一个遵循ICU消息格式的ARB文件:
// 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"
}
代码生成¶
运行flutter gen-l10n会生成:
app_localizations.dart— 包含所有本地化字符串的抽象基类app_localizations_en.dart— 英语实现app_localizations_ja.dart— 日语实现- ...(51个生成的文件)
在Flutter组件中使用:
// Access localized strings
Text(AppLocalizations.of(context)!.studyButton)
// With parameters
Text(AppLocalizations.of(context)!.cardCount(10))
支持的区域注册¶
区域在MaterialApp中注册:
MaterialApp(
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
locale: selectedLocale, // From LocalePreferences
)
内容本地化¶
闪卡内容(汉字含义、词汇定义)以JSONB格式存储在PostgreSQL中,并通过API提供服务:
graph LR
A[API Request<br/>?lang=pt] --> B[Backend]
B --> C[PostgreSQL<br/>JSONB lookup]
C --> D[Return meaning<br/>in Portuguese]
翻译流水线¶
新内容通过OpenAI API进行翻译:
- 源内容以英语编写
- 后端向OpenAI发送翻译请求,附带JLPT级别和用法上下文
- 翻译存储在JSONB列中,与现有翻译并列
- 每种语言可以独立更新,不影响其他语言
自托管翻译
Kubernetes清单中包含一个LibreTranslate部署(k8s/04-libretranslate-deployment.yaml),作为OpenAI的替代方案。这提供了完全自托管的翻译服务,无需外部API依赖,但翻译质量因语言对而异。
UI语言与内容语言¶
KanjiIQ允许UI语言和学习语言不同:
- UI语言:按钮、标签和导航的语言(例如法语)
- 学习语言:闪卡含义的语言(例如葡萄牙语)
一个讲法语的用户在学习日语时,可以使用法语界面,同时查看葡萄牙语的闪卡含义。
添加新语言¶
添加第52种语言的步骤:
- UI:创建
lib/l10n/app_XX.arb,包含所有翻译后的字符串 - 内容:通过翻译流水线将翻译添加到JSONB列
- 区域配置:通过管理API将语言代码添加到相关的
locale_configs条目 - 构建:运行
flutter gen-l10n重新生成本地化文件
无需模式迁移或后端代码更改——JSONB存储和ARB系统都为可扩展性而设计。