言語選択メニューを、固定のハードコードから、データベースに登録された言語を動的に読み込む方式に変更しました。 言語コード順でソートされるため、言語を切り替えても順序が一定に保たれます。
新しいTauriコマンドを2つ追加:
-
get_available_languages- データベースから利用可能な言語コードのリストを取得 -
get_language_names- 現在の言語で翻訳された言語名の配列を取得(言語コード順でソート)
これらのコマンドは既存の I18nService::get_available_languages() メソッドを活用します:
SELECT DISTINCT LANG_CODE FROM I18N_RESOURCES ORDER BY LANG_CODEメニューバーに言語選択ドロップダウンを追加:
<div id="language-menu" class="menu-item">
<span data-i18n="menu.language">Language</span>
<div id="language-dropdown" class="dropdown">
<!-- Language options will be populated dynamically -->
</div>
</div>新しい関数を追加:
-
setupLanguageMenu()- データベースから言語リストを取得し、動的にメニュー項目を生成- 現在の言語をマークする(緑の塗りつぶしの丸)
- 言語切り替えのイベントリスナーを設定
-
handleLanguageChange(langCode)- 言語変更を処理- UIを新しい翻訳で更新
- 言語メニューを更新して名前を表示
初期化時に setupLanguageMenu() を呼び出すように変更
-
保守性の向上 - 言語を追加する際、データベースにデータを追加するだけで済む
-
バグの削減 - ハードコードされた言語リストを複数箇所で管理する必要がなくなる
-
一貫性 - すべての言語データが一箇所(データベース)で管理される
-
拡張性 - 新しい言語を追加する際のコード変更が不要
-
順序の一貫性 - 言語コード順でソートされるため、言語切替時も順序が変わらない
言語データは I18N_RESOURCES テーブルに格納されています:
CREATE TABLE IF NOT EXISTS I18N_RESOURCES (
RESOURCE_ID INTEGER NOT NULL,
RESOURCE_KEY VARCHAR(256) NOT NULL,
LANG_CODE VARCHAR(10) NOT NULL,
RESOURCE_VALUE TEXT NOT NULL,
CATEGORY VARCHAR(64),
DESCRIPTION VARCHAR(512),
ENTRY_DT DATETIME NOT NULL,
UPDATE_DT DATETIME,
PRIMARY KEY(RESOURCE_ID),
UNIQUE(RESOURCE_KEY, LANG_CODE)
);lang.name.en- 英語の言語名(現在の言語で表示)lang.name.ja- 日本語の言語名(現在の言語で表示)
例:
- 英語で表示する場合:
lang.name.ja→ "Japanese" - 日本語で表示する場合:
lang.name.ja→ "日本語"
-
I18N_RESOURCESテーブルに新しい言語のリソースを追加 -
すべてのリソースキー(menu., error., etc.)に対して新しい言語の翻訳を追加
-
lang.name.{lang_code}リソースを各言語で追加 -
アプリケーションを再起動すると、新しい言語が自動的にメニューに表示される
-- 言語名のリソース
INSERT INTO I18N_RESOURCES (RESOURCE_ID, RESOURCE_KEY, LANG_CODE, RESOURCE_VALUE, CATEGORY, ENTRY_DT)
VALUES
(1001, 'lang.name.zh', 'en', 'Chinese', 'language', datetime('now')),
(1002, 'lang.name.zh', 'ja', '中国語', 'language', datetime('now')),
(1003, 'lang.name.zh', 'zh', '中文', 'language', datetime('now'));
-- その他すべての翻訳を zh 言語コードで追加
-- menu.file, menu.login, エラーメッセージなどすべての既存のユニットテストが成功しています:
cargo test --lib
# 結果: ok. 90 passed; 0 failed; 0 ignored既存の機能との後方互換性を保持しています。現在サポートされている言語:
- English (en)
- Japanese (ja)
-
src/lib.rs
- 新しいTauriコマンドの追加
get_available_languages()- 利用可能な言語のリストget_language_names()- ローカライズされた言語名
-
res/index.html
- 言語ドロップダウンメニューの追加
-
res/js/menu.js
- 動的言語メニューの実装
setupLanguageMenu()- メニュー項目の生成setupLanguageMenuHandlers()- イベントハンドラーの設定handleLanguageChange()- 言語変更の処理
-
res/css/menu.css
- 言語メニューのスタイル
バックエンドで Vec<(String, String)> として返すことで、順序を保証:
let mut language_names = Vec::new();
for lang_code in lang_codes {
let key = format!("lang.name.{}", lang_code);
if let Ok(name) = i18n.get(&key, ¤t_lang).await {
language_names.push((lang_code, name));
}
}
// 言語コードでソート
language_names.sort_by(|a, b| a.0.cmp(&b.0));フロントエンドでは配列として受け取り、順序を保持:
for (const [langCode, langName] of languageNames) {
// 配列の順序がそのまま保持される
}この実装により、以下が可能になります:
- データベースに言語データを追加するだけで新しい言語をサポート
- コードの変更なしに言語を追加・削除
- 翻訳の管理をデータベースで一元化
- 翻訳管理ツールとの統合が容易
- 初版作成
- 動的言語メニューの実装
- 言語順序のソート機能追加