多言語とロケール

MintJams CMS の多言語対応は、2 つの層で構成されます。今日は 英語(en)と日本語(ja に対応し、「1 つの JSON を追加するだけ」でロケールを増やせる設計です。

制御するもの 真実の源
ローカライズ設定 ロケール、タイムゾーン、数値書式、通貨 ユーザーごと(Preferences → 地域と言語)
メッセージバンドル 翻訳された文字列 JCR の /etc/i18n/<locale>.json

メッセージバンドル

JCR の /etc/i18n/ に置かれたフラットな JSON です。ロケールはファイル名の最後のドット区切り.json の前)で決まります。

/etc/i18n/en.json                  → locale "en"  (コア: common.* / webtop.* / cms.*)
/etc/i18n/ja.json                  → locale "ja"
/etc/i18n/content-browser.en.json  → locale "en"  (アプリのバンドル)
/etc/i18n/content-browser.ja.json  → locale "ja"
/etc/i18n/commerce.ja.json         → locale "ja"  (アドオンモジュール)

同じロケールのファイルはマージされます。各ユニット(コア・各アプリ・アドオン)が自分の名前空間のキーを持ち寄れるため、他のファイルを編集せずに追加できます。実行時、/etc/i18n/ の編集はホットリロードされ、各アプリが再描画されます。

キーの名前空間

接頭辞 所有者
common.* 共通 UI プリミティブ common.save
webtop.* シェル(デスクトップ、メニュー、ウィンドウ) webtop.startMenu.signOut
app.<appId>.* 個々のアプリ app.preferences.localization.title
cms.* 横断的なプラットフォームメッセージ(検証・エラー) cms.validation.string.tooLong

アプリの表示名は app.<appId>.title で localize します(無ければ app.ymltitle にフォールバック)。

メッセージ書式

バンドルは intl-messageformat で整形され、ICU のプレースホルダー・複数形・select を使えます。

"cms.validation.string.tooLong": "Value is too long (max {max} chars)",
"app.tasks.count": "{count, plural, =0 {No tasks} one {# task} other {# tasks}}"

執筆のルール

  • すべてのロケールでキーを同期する(en は最終フォールバック。en に無いキーはバグ)
  • 翻訳された断片を連結しない(語順が言語で異なる)。プレースホルダー付きで 1 文を 1 キーに
  • キーにユーザーデータを入れない(キーは識別子)

ローカライズ設定

ユーザーは Preferences → 地域と言語で次を設定します。変更は全アプリへ即時反映されます。

  • 言語 — Webtop とアプリの表示言語
  • タイムゾーン — 日時の表示
  • 数値の書式 — 数値・日付・リストのロケール
  • 通貨 — 金額の既定通貨

各項目は「自動」を選べ、空の場合はシステム/ブラウザの既定にフォールバックします(解決順: 完全一致 → 言語のみ → en)。

ロケールを追加する

既存の各ユニット(コアと各 <appId>)について、同じキーセットを持つ <locale>.json を追加するだけです。コード変更は不要で、ローダーがファイル名からロケールを判別し、Preferences の言語一覧も利用可能なバンドルから生成されます。

書式の利用(開発者向け)

アプリは、ユーザーの実効ロケール・タイムゾーン・通貨に従う共通ヘルパーで整形します。

import { formatNumber, formatCurrency, formatDate } from "../../composables/use-localization.js";