コンテンツにスキップ

i18n実装

KanjiIQは、UIローカライゼーションにFlutter組み込みの国際化フレームワークとARB(Application Resource Bundle)ファイルを使用し、コンテンツローカライゼーションにPostgreSQL JSONBを使用しています。

ARBによるUIローカライゼーション

設定

ローカライゼーションシステムはfrontend/l10n.yamlで設定されています:

arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart

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
)

コンテンツローカライゼーション

フラッシュカードコンテンツ(漢字の意味、語彙の定義)はPostgreSQLにJSONBとして保存され、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を通じて翻訳されます:

  1. ソースコンテンツは英語で作成
  2. バックエンドがJLPTレベルと使用法に関するコンテキストとともに翻訳リクエストをOpenAIに送信
  3. 翻訳は既存の翻訳と並んでJSONBカラムに保存
  4. 各言語は他に影響を与えることなく個別に更新可能

セルフホスト翻訳

Kubernetesマニフェストには、OpenAIの代替としてLibreTranslateデプロイメント(k8s/04-libretranslate-deployment.yaml)が含まれています。これにより、外部APIに依存せず完全にセルフホストされた翻訳が提供されますが、言語ペアによって品質は異なります。

UI言語とコンテンツ言語

KanjiIQでは、UI言語と学習言語を別々に設定できます:

  • UI言語:ボタン、ラベル、ナビゲーションの言語(例:フランス語)
  • 学習言語:フラッシュカードの意味の言語(例:ポルトガル語)

フランス語を話すユーザーが日本語を学習する場合、インターフェースをフランス語にしながら、フラッシュカードの意味をポルトガル語で表示することができます。

新しい言語の追加

新しい(52番目の)言語を追加するには:

  1. UI:すべての翻訳文字列を含むlib/l10n/app_XX.arbを作成
  2. コンテンツ:翻訳パイプラインを通じてJSONBカラムに翻訳を追加
  3. ロケール設定:管理APIを通じて関連するlocale_configsエントリに言語コードを追加
  4. ビルドflutter gen-l10nを実行してローカライゼーションファイルを再生成

スキーマ移行やバックエンドのコード変更は不要です — JSONBストレージとARBシステムはどちらも拡張性を考慮して設計されています。