現在、当サイト「mozilla.org 日本語版」の和訳文書は更新されておらず、mozilla.org の原文 よりも内容が古くなっている可能性があります。ご不便をお掛けしますが、最新の情報は原文をご確認ください。



国際的なカスタマイズをし易いコードを書く

Tao Cheng


目標

ローカライゼーション(l10n)、カスタマイズ、国際化(i18n)をし易いコードを書くことが重要である理由:
  • 使用可能性。XUL や CSS、C++コードでさえ変更不要。ローカライゼーションと地域化は、 "langenus.xpi"といった言語パックや、"regus.xpi"といった地域パックで可能。 
  • 費用対効果。翻訳者は*.dtd や *.properties ファイル中のキーと値の組み合わせを扱うだけでよく。 マークアップ言語やプログラミング言語を習熟する必要がない。
  • 地域と言語の切替、インストール、アップグレード。言語パックと地域パックは 追加可能で、ローカライズビルドもしくはカスタマイズビルドを作成するのに、言語パックと 地域パックだけあればよい。
  • QA 懸念の低減。リソース修正時にプログラムのロジックやバイナリが重複とは無縁になるため、 不具合は減少し、GUI関連のものや見つかり易いものが中心となる。
  • エラーの減少傾向。 形式の固定されたファイル(キーと値)とすることで、 人為ミスが発生しにくくなる。

目標でないもの

XUL 技術の紹介ではありません。対象読者はC++、JavaScript、それからマークアップ言語のコーディング経験があり、基本的理解をしている人です。

ローカライゼーションとカスタマイズ

ローカライゼーションとカスタマイズ、それから Mozilla でそれをどうやって実現する?
  • ローカライゼーション: 翻訳や地域や地域文化に合わせるための UI リソースのカスタマイズ

    • Mozilla UI は、XML アプリケーションである XUL 技術をベースに築かれています。 ローカライゼーションを円滑にするため、すべての言語リソースを、文書型定義(DTD)の外部サブセットとして 外部化しています。翻訳者やローカライズ作業者は、DTD(例: "navigator.dtd")内の値を翻訳することで、 XUL 構文の理解は不要のままブラウザをローカライズします。
    • C++やJavaScript のコードでは、文字列やリソースはキーと値の組で Java のプロパティファイルの形式(例:"navigator.properties")で保存されます。 XPCOM オブジェクト、nsIStringBundleService、nsIStringBundle がそれらを読み込みます。
    • メニュー、フォーム、ダイアログのレイアウトはローカライズ可能です。 例としては、検索メニュー、アドレス帳の新しいカードダイアログ等が挙げられます。 そのような UI のために、しばしば実装のための XUL オーバーレイを使用します。
    • ローカライゼーションにおいて、DTD と property、そして RDF ファイルだけを翻訳者へ渡しておき、翻訳者はキーと値の組み合わせを相手にすれば よいのです。

  • カスタマイズ: ローカライゼーションと似ていますが、UI の修正に主眼がおかれます。 カスタマイズの例:

    • メニュー項目に「Help」メニューを追加する。
    • サイドバータブを追加する。
    • throbber アイコンや throbber の URL を修正する。
    • パーソナルツールバーからNet2phoneやタスクメニュー、設定ダイアログを削除する。

ローカライズ/カスタマイズ可能なコードを書く

  1. ローカライズ/カスタマイズ可能なリソースって何?

    • テキスト、エンドユーザが目にする文字列。 これらのリソースは langenus.xpi 中にある jarファイルの一つの中に含まれます。
      • 良い例: en-US.jar や、 en-{mac, unix, win}.jar
      • 悪い例: 言語パックに関係なくローカライズできるように、 XUL、JavaScript、C++ のコードの中に文字列をハードコーディングする。

    • 外部 Web サイトを指し示す Web リンク(URL)(例" http://www.foo.com) 例えば、 URL は「ホーム」ボタンや、 「N」ロゴボタン(訳注:Netscape を意識した記述で、Throbber のことと思われる)や、 広告バナーなどに関連づけられます。
      • 良い例: US.jar に含める。
      • 悪い例: XUL や langenus.xpi の中に埋め込む。

    • 形状要素(幅、高さ、サイズ変更の可・不可等)、 UI 設定(プルダウンメニュー、ダイアログ等)。 翻訳(アジア、ドイツ等)は文字数の変化による幅や高さの増減が起こりがちです。 翻訳の結果として文字欠け等を発生させないため、これらもローカライズしてください。
      • 良い例: *.dtd (もしくは *.properties)に外部化する。
      • 悪い例: .xul、.css、C++、JavaScript 等にハードコードする。

    • 言語、文化に依存する画像。  (英語等の)文字を含む画像とアイコンはローカライズが困難です。 悪い例:
      • 「MyNetscape」と表示するための "My" と書かれた画像。
      • ツールバーを整形するためのComposer(や Editor)のボールドイタリックのボタンアイコン
      • Composer(や Editor)のツールバーにある abc という文字を含むスペルチェッカーボタン。

    • 温度機能(華氏 V.S. 摂氏)
      • 悪い例: 単位として華氏のみを想定する。
      • 良い例: 単位を明記し、さらにローカライズ可能とする。

    • 郵便アドレスのフォーマット。メールアドレスのフォーマットは国によって異なります。 世界統一のアドレス形式は存在しません。 ユーザインタフェースデザインは、地域性に配慮し、ローカライズによる調整の余地を残しておく必要があります。 例えば、
      • 合衆国においては、郵便アドレスの各項目は次のような順序になります 町内住所、市、州、Zip コード、国。
      • しかし、アジアでは、郵送アドレスは国、州、郡、市等の順になります。

    • 計測単位: メートル法 V.S. 英語式測量法。

  2. どのようにローカライズ/カスタマイズ可能にするのか。 推奨される方法は、以下のように、ソースファイルの種類ごとに決まっています。 (詳細は、" XUL Coding Style Guidelines "を参照のこと)

    1. XUL: XML DTD (*.dtd) を使用する

      • Mozilla にて chrome ファイルへの参照が必要な場合、必ず chrome URL ( chrome://navigator/content/foo.xulといった形式)を使用する。
      • *.dtd に格納した外部化したローカライズ可能なリソースをexternalize localizable resources into *.dtd: chrome://navigator/ locale/foo.dtdに設置する。
        例: EdColorPicker.xulにて、テキストの実体や定義は外部 DTD のアドレスを宣言できます。 それらは、次のようにして参照できます。

        <!DOCTYPE window SYSTEM "chrome://editor/locale/EdColorPicker.dtd"

         69     <button id="LastPickedButton" crop="right" oncommand="SelectLastPickedColor();">
        70 <spacer id="LastPickedColor"
        71 LastTextColor="" LastBackgroundColor=""
        72 persist="LastTextColor LastBackgroundColor"/>
        73 <label value="&lastPickedColor.label;" flex="1" style="text-align: center;"/>
        74 </button>
        DTD ファイル EdColorPicker.dtd にて、実体が以下のように定義されています。

        <!ENTITY lastPickedColor.label "Last-picked color">

      • キー V.S. 値: (命名階層の慣習)
        • <!ENTITY openFileCmd.label "Open File...">
          <!ENTITY openFileCmd.accesskey "o">
          <!ENTITY openFileCmd.commandkey "o">

    2. C++/JavaScript: 以下のようなランタイムリソースを外部化するために、 String Resource Manager (nsIStringBundleService や nsIStringBundle)を使う。

      • エラーメッセージ:
        • alert.txt =Connection to server, "home.foo.com", failed.
        • alert.url = http://support.foo.com/
      • 進捗を示す文字列: downloading %1 out of %2
      • 設定文字列/設定値: browser.startup.homepage= http://home.netscape.com  
      • XUL や JavaScript の例:

        navigator.xulでは、必要な文字列リソースを宣言します。:
         85   <!-- hook for stringbundle overlays -->
        86 <stringbundleset id="stringbundleset">
        87 <stringbundle id="bundle_navigator" src="chrome://navigator/locale/navigator.properties"/>
        88 <stringbundle id="bundle_brand" src="chrome://global/locale/brand.properties"/>
        89 <stringbundle id="bundle_navigator_region" src="chrome://navigator-region/locale/region.properties"/>
        90 <stringbundle id="bundle_brand_region" src="chrome://global-region/locale/region.properties"/>
        91 <stringbundle id="findBundle" src="chrome://global/locale/finddialog.properties"/>
        92 </stringbundleset>

        これに加え、navigator.jsでは、getString{Name,ID}() を使って対になったリソース(キーと値)へアクセスし、取得します。

        257 function Startup()
        258 {
        259 // init globals
        260 gNavigatorBundle = document.getElementById("bundle_navigator");
        261 gBrandBundle = document.getElementById("bundle_brand");
        ... }

        783 function BrowserOpenFileWindow()
        784 {
        785 // Get filepicker component.
        786 try {
        787 const nsIFilePicker = Components.interfaces.nsIFilePicker;
        788 var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
        789 fp.init(window, gNavigatorBundle.getString("openFile"), nsIFilePicker.modeOpen);
        790 ...
        ...
        ...
        796 }
        797 }

  3. 地域コンテンツ(US.jar) の UI 言語(en-US.jar)からの分離: English (US)、 English (Canada)、English (GB) というように、地域に毎に 多様にローカライズされたビルドの開発速度向上のため、 地域コンテンツファイルは en-US.jar とは別のファイルに格納されます。 ベンダーは、UI 言語をローカライズするのと比較して、時間も資源配分も節約してローカライズすることができます。 以下の2つのサブセクションでは、UI 言語と地域コンテンツを比較して、それぞれ ローカライズ可能なリソースのうちどんな種類のものが UI言語に入り、 どんなものが地域コンテンツに入るのかを並べます。

    1. UI 言語: すべての、地域依存でないローカライズ可能なリソースは、 "langenus.xpi"の中に含まれます。これには以下のものを含みます。

      • エンドユーザに見えるリソース(文字列等)のうちプラットフォーム依存ではないものは、 "en-US.jar"に含まれるべきです。 Crome の URL の例は "chrome://navigator/locale/foo.dtd"です。
      • プラットフォームに依存するすべてのファイルや動的なオーバーレイは "en-{mac, unix, win}.jar" に含まれるべきです。 Crome の URL の例は "chrome://foo-platform/locale/foo.dtd"です。 (langenus.xpi に含まれる)インストーラスクリプトは、プラットフォームに対応する jar ファイルを選択して インストールする判定を備えています。 プラットフォーム特有のリソースを en-US.jar から分離する最終目的は、 langenus.xpi をプラットフォーム間の再利用を容易にすることにあります。 プラットフォーム特有のリソースの例としては、
        • デフォルト文字コード設定。日本用 Web ブラウザでは、 UNIX ブラウザ向けデフォルト文字コードセットは、 "EUC-JP" ですが、Windows ブラウザでは "Shift-JIS" とすべきです。 (訳注:実際には必ずしもそうとは言い切れない。あくまで例として解釈すべき)
        • キーバインド: "Ctrl + N" と "Cmd + N"
        • マウスホイール:Windows と Linux のみです
        • 印刷ダイアログ: Unix のみです。

    2. 地域コンテンツ: 地域/国特有のリソースで、 regus.xpi に含まれるべきです。 地域リソースには以下の2種類があります。

      • chrome の Locale プロバイダ: 地域コンテンツは (URL)。chrome URL で参照されるすべての地域依存リソース (例:"chrome://navigator-region/locale/region.dtd")は、 "US.jar" に含まれるべきです。これらリソースは同じプロファイルでも 切り替え可能です。
        • メニュー項目に関連した URL
          • region.dtd
          • region.properties:
          • builtinURLs.rdf - N ロゴやヘルプメニュー等に対する実行時 URL。
        • カスタマイズ/ローカライズ可能な UI
          • メニュー項目の4番目から始まる"検索"メニュー: searchMenu.rdf
          • "Print Plus" メニュー: communicatorOverlay.rdf
          • パーソナルツールバーボタン: "ホーム", "My Netscape", "検索", "Shop", and "Net2Phone".
        • 他のものは?

      • デフォルトの プロファイルは(bin/{defaults,searchplugins})です。 これらはプロファイルが新規作成されたとき、コピーされ、 コピーされたプロファイルはその後のユーザのセッションの間、修正されます。 デフォルトのプロファイルデータは一度プロファイルにコピーされて使用されると、 コピー先のものと入れ替えることはできません。 例えば、クライアントのインストール先フォルダ(サブフォルダ)"defaults" は、以下のディレクトリとサブディレクトリを含みます:

        • "isp/ US/{aol.rdf,nswebmail.rdf}" - これらは新規メール/ニュースアカウントセットアップウィザード で参照されます。
        • "messenger/ US/Template" - これは、デフォルトのメッセージのテンプレートです。
        • "profile/ US"
          • bookmarks.html
          • default-invite.rdf - AIM(AOL Instant Messanger) で使用されます。
          • default-messages.rdf - AIM(AOL Instant Messanger) で使用されます。
          • localstore.rdf - UI 設定に関係する chrome の制御に使用します。s
          • mimeTypes.rdf - ヘルパーアプリケーションによって参照されます。
          • panels.rdf - デフォルトの sidebar パネル
          • search.rdf - どの検索エンジンを使用するかを制御します。

  4. CSS - CSS には UI 文字列はありません、ええ。 UI 文字列には、この代わりに、DTD や property ファイルが使用します。

    1. フォント設定:グローバルな UI 文字列に影響を与えるフォント設定は、 "chrome://global/locale/intl.css" で行われるべきです。
    2. CSS には UI 文字列はありません、ええ。 UI 文字列には、この代わりに、DTD や property ファイルが使用します。例えば、
      • HTML フォームボタンラベル:送信、 OK等。 etc.
      • CSS はダイアログのボタン文字列を装飾します。

ローカリゼーション凍結ガイドライン

Michele Carlson 9/12/01

目的:
ローカリゼーション UI 凍結日は、我々が US 製品とともにローカライズされた製品を 同時に提供可能とするために整えられます。 つまり、Netscape ブラウザの新バージョンが市場に出回ったことを一般の人々が目にした日に、 他の言語のものも目にすることができるだろうということです。 もし、ローカリゼーション UI 凍結日が尊重されなければ、 US 製品とともにローカライズされた製品を同時には提供できないかもしれないという リスクを抱えることになります。 これは、世界中の多くのユーザにとっての損失です。 フリーズ以後の UI 変更があれば、ローカライズされた製品の再翻訳・再ビルドをすることに なります。 ローカリゼーションチームは翻訳のために新しい文字列を送り出し、戻ってくるのを 待たなければなりません。 これがローカライズされた製品にとってどれほどの影響があるでしょうか?

  • 翻訳のコストを増し、翻訳予算の制御能力を危険にさらします。
  • ローカライズ技術者の作業負荷を増し、 再翻訳結果により、統合とビルドという工程を繰り返すことになります。
  • QA の作業負荷を増します。 どの再翻訳結果に対しても、必ず QA サイクルテストを繰り返すことになります。
  • 同時に市場に出荷するためにかかる時間をしばしば延ばします。
目標:
我々の製品について、US 製品と同様に US 以外の多くの市場についても同時にリリース することを可能とすることは重要です。 これは、世界的に認識されるブランドを作ることにつながります。 真の国際的企業となるべき日々努力しています。 世界中のユーザから世界的企業として認められるようにつとめることは、多くのポイントの うちの一つにすぎません。

定義:
ローカリゼーション UI 凍結日を尊重することは、 すなわち技術者が以下に従うことです:

  • ユーザが目にするいかなる文字列も変更しません。 ファイル中の文字列の追加・削除・修正いずれもです。
  • 文字列を含むいかなる画像も変更してはなりません。
  • いかなる文字列も別の場所に移動してはいけません。 ファイルからファイルへの移動、jar/xpi ファイル間の移動いずれもです。
  • URL、メニュー、検索エンジン、プラグインを含むいかなる コンテンツも変更してはいけません。
  • 単語、空白、カンマ、コロン等いかなる文字列も修正してはいけません。 文字列内でユーザインタフェースに現れるいかなる変更もしてはいけません。
ローカリゼーション UI 凍結日以後に、ローカリゼーションに影響させる ことなく技術者が可能な変更は?
技術者は、UI に関わらないどの部分の重要なコードでも修正を継続することができます。 UI に影響を及ぼす修正をする場合、技術者は、ローカリゼーションには影響させてはいけません。

タイミング:
ベータ版と RTM リリースの両方でローカリゼーション UI 凍結日の設定は重要です。 具体的なローカリゼーション UI 凍結日はマスタースケジュールに定められなければ なりません。 スケジュール管理者は、mcarlson とともに、ローカリゼーション UI 凍結日がこのガイドラインに記述された内容を満足することのできる日と なることを保証するよう、ローカリゼーション UI 凍結日の調整に責任を持ちます。 スケジュール管理者が、リリースの大きさを知らない場合、mcarlson チームは、 単語の合計数を基準に推定サイズの情報を提供しなくてはなりません。

Mozilla 開発者がローカリゼーション凍結を遵守する必要がある時、 mozilla.org のスタッフは Mozilla 開発者にその時期を連絡します。

例外:
ローカリゼーション UI 凍結日の例外は、ケースバイケースで行われるレビューです。 いかなる例外のリクエストも、Netscape ローカライズ技術者チームのマネージャー mcarlson@netscape.com へ承認を得るために送られます。