これは、Angular の公式ドキュメントの Internationalization (i18n) の章を意訳したものです。所々抜け落ち、翻訳モレがありますがあしからずご了承を。
バージョン 4.3.4 のドキュメントをベースにしています。
Internationalization (i18n)
Angularの国際化ツール(i18n)は、アプリを複数の言語で利用できるようにします。
スペイン語に翻訳された、JITコンパイルされたアプリケーションのライブサンプル/サンプルダウンロードを試してみてください。
Angularとi18nテンプレートの翻訳
アプリケーションの国際化は、献身と永続的なコミットメントを必要とする、チャレンジングで多面的な取り組みです。Angularの国際化機能が役立ちます。
このページでは、コンポーネントテンプレートテキストの複数の言語への翻訳を支援するために利用できるi18nツールについて説明します。
国際化の実践者は、翻訳可能なテキストを「メッセージ」と呼んでいます。このページでは、「テキスト」と「メッセージ」という言葉を区別なく使用し、「テキストメッセージ」の組み合わせで使用します。
i18nテンプレートの翻訳プロセスには4つのフェーズがあります。
- コンポーネントテンプレートの静的テキストメッセージを翻訳用にマークします。
- Angularのあるi18nツールはマークされたメッセージを業界標準翻訳ソースファイルに抽出します。
- 翻訳者がそのファイルを編集し、抽出されたテキストメッセージをターゲット言語に翻訳し、それをあなたに返します。
- Angularコンパイラは、完成した翻訳ファイルをインポートし、元のメッセージを翻訳されたテキストに置き換え、ターゲット言語で新しいバージョンのアプリケーションを生成します。
サポートされている言語ごとに別々のバージョンのアプリケーションをビルドして展開する必要があります。
i18n属性のテキストにマークを付ける
Angular i18n属性は、翻訳可能なコンテンツのマーカーです。固定テキストを翻訳する必要のあるすべての要素タグに配置します。
i18nはAngularディレクティブではありません。 Angularツールやコンパイラによって認識されるカスタム属性です。変換後、コンパイラはそれを削除します。
付随するサンプルでは、<h1>
タグはスペイン語に翻訳される簡単な英語の挨拶を表示します。
src/app/app.component.html
<h1>Hello i18n!</h1>
i18n
属性をタグに追加して、翻訳用にマークします。
src/app/app.component.html
<h1 i18n>Hello i18n!</h1>
descriptionとmeaningで翻訳者を助ける
翻訳者がテキストを適切に翻訳するために、補足説明を必要とするかもしれません。その場合は、i18n
属性に説明を割り当てることができます。
src/app/app.component.html
<h1 i18n="An introduction header for this sample">Hello i18n!</h1>
正しい翻訳を提供するために、翻訳者は、この特定のアプリケーションの文脈内のテキストの意味または意図を知る必要があり得る。
意味を持つ文字列を始めることによってコンテキストを追加し、|
文字(<meaning>|<description>
):
src/app/app.component.html
<h1 i18n="site header|An introduction header for this sample">Hello i18n!</h1>
同じ意味を持つメッセージの出現はすべて同じ翻訳をしますが、さまざまな意味のメッセージが異なる翻訳を持つ可能性があります。Angular 抽出ツールは、翻訳ソースファイルの意味と説明の両方を保存して、文脈に特有の翻訳を容易にします。
検索と保守を改善するカスタムIDを設定する
Angular i18n抽出ツールは、テンプレート内のi18n属性ごとに翻訳単位エントリを含むファイルを生成します。デフォルトでは、各翻訳単位に次のような一意のIDを割り当てます。
<trans-unit id="ba0cc104d3d69bf669f97b8d96a4c5d8d9559aa3" datatype="html">
このid
は、人間が読んだり覚えたりするのが難しく、難しいものです。
さらに悪い話として、例えばタイプミスを修正するために翻訳可能なテキストを変更を加えると、抽出ツールがその翻訳の新しいIDを生成します。新しいIDで更新しない限り、翻訳は失われます。そのためメンテナンスは複雑なものになります。
この問題を回避するには、独自の意味のあるIDをi18n
属性に指定することをお勧めします。プレフィックスは@@
です。
app/app.component.html
<h1 i18n="@@introductionHeader">Hello i18n!</h1>
これで、抽出ツールとコンパイラはカスタムIDを持つtrans-unitを生成するので、idを変更することはありません。
<trans-unit id="introductionHeader" datatype="html">
ここに定義を持つi18n
属性があり、その後にカスタムid
が続きます。
app/app.component.html
<h1 i18n="An introduction header for this sample@@introductionHeader">Hello i18n!</h1>
ここに意味と説明と最後にidがあります:
app/app.component.html
<h1 i18n="site header|An introduction header for this sample@@introductionHeader">Hello i18n!</h1>
一意のカスタムIDを必ず定義してください。2つの異なるテキストブロックに同じidを使用すると、最初の方だけ読み込まれて、両方のテキストブロックで表示されることになります。
例えば:
<p i18n="@@myId">Hello</p> <p i18n="@@myId">Good bye</p>
翻訳では:
<trans-unit id="myId" datatype="html"> <source>Hello</source> <target state="new">Hola</target> </trans-unit>
両方の
<p>
要素には、テキストHola
が含まれます。
要素を作成せずにテキストを翻訳する
翻訳したいテキストがあるとします。<span>
タグでそれを囲むこともできますが、何らかの理由で(例えば、CSSに対する恐れ)、翻訳を容易にするために新しいDOM要素を作成したくないケースもあるでしょう。
試すには2つの方法があります。
(1) <ng-container>
要素にテキストをラップします。<ng-container>
はレンダリングされません:
<ng-container i18n>I don't output any element</ng-container>
(2) テキストをHTMLコメントのペアで囲みます。
src/app/app.component.html
<!--i18n: optional meaning|optional description -->
I don't output any element either
<!--/i18n-->
i18n translation属性を追加する
テンプレートに画像を追加しました。あなたはアクセシビリティにも気を配り、title属性を追加したとしましょう:
src/app/app.component.html
<img [src]="logo" title="Angular logo">
こうなると、title
属性を翻訳する必要があります。Angular i18nサポートには、より多くの変換を行える属性としてi18n-x
があります。ここでの x
は変換する属性の名前です。 前の例のimg
タグのタイトルを翻訳するには、次のように記述します。
src/app/app.component.html
<img [src]="logo" i18n-title title="Angular logo" />
また、i18n-x="<meaning>|<description>"
の構文で意味と説明を割り当てることもできます。
単数形と複数形を扱う
言語にはそれぞれ異なる単数形・複数形のルールがあります。
あなたのアプリケーションがオオカミのコレクションについて何かを言うとします。 英語では、オオカミの数に応じて、 "no wolves", "one wolf", "two wolves", もしくは "a wolf pack" と表示できます。他の言語では、カーディナリティが異なって表現されることがあります。
オオカミの数に適したフレーズを表示するためにコンポーネントテンプレートをマークアップする方法は次のとおりです。
src/app/app.component.html
<span i18n>{wolves, plural, =0 {no wolves} =1 {one wolf} =2 {two wolves} other {a wolf pack}}</span>
- 最初のパラメータはキーです。 これは、オオカミの数を決定するコンポーネントプロパティ(
wolves
)に拘束されています。 - 第2のパラメータ
plural
は、これを複数の翻訳タイプとして識別します。 - 第3のパラメータは、複数のカテゴリとその一致する値からなる複数のパターンを定義します。
複数のカテゴリには、下記のものが含まれています
- =0 (もしくは0以外の他の数値)
- zero
- one
- two
- few
- many
複数のカテゴリの横にある括弧({}
)でデフォルトの英語の翻訳を配置できます。
- あなたが1つのオオカミについて話しているとき、
=1
{1つのオオカミ}と書くことができます。 - 0オオカミの場合、
=0
{オオカミなし}と書くことができます。 - 2つのオオカミにとって、あなたは
=2
{2つのオオカミ}と書くことができます。
あなたは3, 4、および他の数のオオカミのためにこれを保持することができます。あるいは、他のカテゴリーを、他に類のない基数のキャッチオールとして指定して、他の{a wolf pack}のように書くことができます。
この構文は、複数化規則を指定するCommon Locale Data Repository(CLDR)から派生したICUメッセージフォーマットに準拠しています。
代替テキストから選択する
ヒーローが男性か女性かによって、アプリケーションは異なるテキストを表示する必要があります。これらは代替テキストとして翻訳が必要です。
翻訳の選択でこれを処理できます。ICUのメッセージ構文の後にもselectが続きます。数値の代わりに文字列値に基づいて代替翻訳を選択します。
コンポーネントテンプレートの次の形式メッセージは、コンポーネントのgender
プロパティにバインドされ、 "m"または "f"のいずれかを出力します。メッセージは、これらの値を適切な翻訳にマッピングします。
src/app/app.component.html
<span i18n>The hero is {gender, select, m {male} f {female}}</span>a
複数形と選択式を組み合わせる
異なるICU式を一緒にネストすることもできます。例えば:
src/app/app.component.html
<span i18n>Here we have: {count, plural,
=0 {no one}
=1 {one {gender, select, male {man} female {woman}}}
other {{{heroes.length}} {gender, select, male {men} female {women}}}
}</span>
ng-xi18n
ツールを使用して翻訳ソースファイルを作成する
ng-xi18n抽出ツールを使用して、業界標準形式の翻訳ソースファイルにi18nマークのテキストを抽出します。
これは、@angular/compiler-cli
npmパッケージのAngular CLIツールです。 CLIとそのプラットフォームとサーバー間のPeer Dependenciesをまだインストールしていない場合は、ここで実行してください。
npm install @angular/compiler-cli @angular/platform-server --save
アプリケーションプロジェクトのルートにあるターミナルウィンドウを開き、ng-xi18n
コマンドを入力します。
./node_modules/.bin/ng-xi18n
Windowsユーザーは次のようにコマンドを引用する必要があります。
"./node_modules/.bin/ng-xi18n"
デフォルトでは、XML ローカリゼーションインターチェンジ ファイル フォーマット(XLIFF、バージョン1.2) に準拠したmessages.xlf
という名前の変換ファイルが生成されます。
その他の翻訳フォーマット
Angular i18nツールは、XLIFF 1.2とXLIFF 2、およびXML Message Bundle(XMB)をサポートしています。
これらのコマンド例に示すように、-i18nFormat
フラグを使用して明示的にフォーマットの選択を指定することができます。
./node_modules/.bin/ng-xi18n --i18nFormat=xlf --outFile=messages.xlf
./node_modules/.bin/ng-xi18n --i18nFormat=xlf2 --outFile=messages.xliff2.xlf
./node_modules/.bin/ng-xi18n --i18nFormat=xmb --outFile=messages.xmb
このガイドのサンプルは、デフォルトのXLIFF 1.2形式を採用しています。
その他のオプション
追加のオプションを指定する必要があるかもしれません。たとえば、tsconfig.json TypeScript構成ファイルがルートフォルダ以外の場所にある場合は、-p
オプションを使用してパスを指定する必要があります。
./node_modules/.bin/ng-xi18n -p path/to/tsconfig.json
./node_modules/.bin/ng-xi18n --i18nFormat=xmb -p path/to/tsconfig.json
利便性のためにnpmスクリプトを追加する
コマンドを覚えやすく実行するために、package.json
のscripts
セクションに便利なショートカットを追加することを検討してください。
"scripts":{
"i18n": "ng-xi18n"、
...
}
これで、次のようなコマンドバリエーションを発行できます。
npm run i18n
npm run i18n -- -p path/to/tsconfig.json
npm run i18n -- --i18nFormat=xmb -p path/to/tsconfig.json
オプションの前に --
フラグを付与することに注意してください。ng-xi18n
にすべてのフラグを渡すようにnpmに指示します。
テキストメッセージを翻訳する
ng-xi18n
コマンドは、プロジェクトルートフォルダmessages.xlf
に翻訳ソースファイルを生成します。次のステップは、英語のテンプレートテキストを特定の言語翻訳ファイルに翻訳することです。ガイドサンプルはスペイン語の翻訳ファイルを作成します。
ローカリゼーションフォルダを作成する
おそらく複数の言語に翻訳されるので、プロジェクト構造があなたの国際化の成果全体を反映することは良いアイデアです。
1つのアプローチは、フォルダをローカリゼーション専用にして、国際化ファイルなどの関連するアセットをそこにまとめて格納することです。
ローカリゼーションとインターナショナリゼーションは異なりますが、密接に関連する用語です。
このガイドはその提案に従います。 src/
の下にロケールフォルダがあります。フォルダー内のアセットは、よく知られているコードセットの言語文化コードに一致するファイル名拡張子を持ちます。
messages.xlf
ファイルのコピーを作成し、ロケールフォルダに置き、スペイン語のmessages.es.xlffor
という名前に変更します。それぞれのターゲット言語について同じことをします。
テキストノードを翻訳する
現実の世界では、messages.es.xlf
ファイルをスペイン語の翻訳者に送信し、多数あるXLIFFファイルエディタを使用して翻訳を入力していきます。
このサンプルファイルは、特別な編集者やスペイン語の知識がなければ翻訳が簡単です。 messages.es.xlf
を開き、最初の<trans-unit>
セクションを見つけます:
src/locale/messages.es.xlf ()
<trans-unit id="introductionHeader" datatype="html">
<source>Hello i18n!</source>
<target>¡Hola i18n!</target>
<note priority="1" from="description">An introduction header for this sample</note>
<note priority="1" from="meaning">User welcome</note>
</trans-unit>
このXML要素は、i18n
属性でマークした<h1>
挨拶タグの翻訳を表します。
translation unit
id=introductionHeader
は、以前に設定したカスタムIDから派生したものですが、ソースHTMLに** @@ プレフィックスは不要**です。
source、description、およびmeaning要素を使用して翻訳をガイドするには、<target/>
タグをスペイン語の挨拶に置き換えます。
src/locale/messages.es.xlf (, after translation)
<trans-unit id="introductionHeader" datatype="html">
<source>Hello i18n!</source>
<target>¡Hola i18n!</target>
<note priority="1" from="description">An introduction header for this sample</note>
<note priority="1" from="meaning">User welcome</note>
</trans-unit>
他のテキストノードも同じ方法で翻訳します。
src/locale/messages.es.xlf ()
<trans-unit id="ba0cc104d3d69bf669f97b8d96a4c5d8d9559aa3" datatype="html">
<source>I don't output any element</source>
<target>No genero ningún elemento</target>
</trans-unit>
<trans-unit id="df3cf8b55cb528cf8c00167e0b119bfb828538b5" datatype="html">
<source>I don't output any element either</source>
<target>Yo tampoco genero ningún elemento</target>
<note priority="1" from="description">optional description</note>
<note priority="1" from="meaning">optional meaning</note>
</trans-unit>
<trans-unit id="701174153757adf13e7c24a248c8a873ac9f5193" datatype="html">
<source>Angular logo</source>
<target>Logo de Angular</target>
</trans-unit>
ツールは、これらの翻訳単位ごとに
id
を生成しました。それらは編集しないでください。 各id
は、メッセージの内容と割り当てられた意味に依存します。factorとid
の変更も同様に変更してください。 翻訳ファイルのメンテナンスについては、説明を参照してください。このため、カスタムIDを指定して、ツールがIDを自動生成するのを回避する必要があります。
複数形と選択肢を翻訳
<source>
タグは、複数の翻訳単位と選択された翻訳単位では空白なため、元のテンプレートとの関連付けが困難です。XLIFF
形式はまだICUルールをサポートしていません。ただしXMB
形式はICUルールをサポートしています。
ソーステンプレートの他の場所から認識している他の翻訳単位に関して、それらを探すだけで済みます。この例では、select
の翻訳単位は、ロゴの翻訳単位のすぐ下になければなりません。
複数形を翻訳する
複数形を翻訳するには、そのICU形式の一致値を翻訳します。
src/locale/messages.es.xlf ()
<trans-unit id="6e22e74e8cbd3095560cfe08993c4fdfa3c50eb0" datatype="html">
<source/>
<target>{wolves, plural, =0 {ningún lobo} =1 {un lobo} =2 {dos lobos} other {una horda de lobos}}</target>
</trans-unit>
選択肢を翻訳する
select
の動作は少し異なります。ここでも、コンポーネントテンプレートのICU形式メッセージがあります。
src/app/app.component.html
<span i18n>The hero is {gender, select, m {male} f {female}}</span>
抽出ツールはそれを2つの翻訳単位に分割しました。
最初の単位には、選択範囲外のテキストが含まれています。 selectの代わりに、選択メッセージを表すプレースホルダ<x id="ICU">
があります。 テキストを翻訳し、プレースホルダをそのままにしておきます。
src/locale/messages.es.xlf ()
<trans-unit id="61cafedb85466ab789b3ae817bba1a545468ee1c" datatype="html">
<source>The hero is <x id="ICU"/></source>
<target>El heroe es <x id="ICU"/></target>
</trans-unit>
最初の翻訳ユニットのすぐ下にある第2の翻訳ユニットは、select
メッセージを含んでいます。これを翻訳してみましょう。
src/locale/messages.es.xlf ()
<trans-unit id="14c7055d67771a3b7b6888d282ac092896be06b6" datatype="html">
<source/>
<target>{gender, select, m {hombre} f {mujer}}</target>
</trans-unit>
ここで彼らは一緒にいます。翻訳後を見てみましょう:
src/locale/messages.es.xlf ()
<trans-unit id="61cafedb85466ab789b3ae817bba1a545468ee1c" datatype="html">
<source>The hero is <x id="ICU"/></source>
<target>El heroe es <x id="ICU"/></target>
</trans-unit>
<trans-unit id="14c7055d67771a3b7b6888d282ac092896be06b6" datatype="html">
<source/>
<target>{gender, select, m {hombre} f {mujer}}</target>
</trans-unit>
ネストされた式を翻訳する
ネストされた式は前の式と変わりません。前の例と同様に、2つの翻訳単位があります。
最初の例は、ネストされた式の外側のテキストが含まれます。
src/locale/messages.es.xlf ()
<trans-unit id="2cf9a08c5b6e3612572a2a36dd46563013848382" datatype="html">
<source>Here we have: <x id="ICU"/></source>
<target>Aquí tenemos: <x id="ICU"/></target>
</trans-unit>
2番目のユニットには、完全なネストされた式が含まれます。
src/locale/messages.es.xlf ()
<trans-unit id="db1b921b55301ce3957e382090729562002da036" datatype="html">
<source/>
<target>
{count, plural,
=0 { nadie }
=1 {{gender, select, m {un hombre} f {una mujer}}}
other {{{heroes.length}} {gender, select, m {hombres} f {mujeres}}}
}
</target>
</trans-unit>
両方を見てみましょう:
src/locale/messages.es.xlf ()
<trans-unit id="2cf9a08c5b6e3612572a2a36dd46563013848382" datatype="html">
<source>Here we have: <x id="ICU"/></source>
<target>Aquí tenemos: <x id="ICU"/></target>
</trans-unit>
<trans-unit id="db1b921b55301ce3957e382090729562002da036" datatype="html">
<source/>
<target>
{count, plural,
=0 { nadie }
=1 {{gender, select, m {un hombre} f {una mujer}}}
other {{{heroes.length}} {gender, select, m {hombres} f {mujeres}}}
}
</target>
</trans-unit>
テンプレートの翻訳全体が完了しました。いよいよ翻訳をアプリケーションに組み込む時です。
翻訳前のアプリ
前の手順が完了すると、サンプルアプリとその翻訳ファイルは次のようになります。
ソースは省略します。こちらを参照してください
完成した翻訳ファイルをアプリケーションにマージする
翻訳されたテキストをコンポーネントテンプレートにマージするには、完成した翻訳ファイルでアプリケーションをコンパイルします。このプロセスは、ファイルが.xlf
形式であるか、Angularが理解できる別の形式(.xtb
など)であっても同じです。
Angularコンパイラには、次の3つの新しい情報が提供されます。
- 翻訳ファイル
- 翻訳ファイルフォーマット
-
Locale ID(たとえば、
en
またはen-US
)
この情報の提供方法は、JIT(Just-In-Time)コンパイラまたはAOT(Ahead-of-Time)コンパイラでコンパイルするかどうかによって異なります。
- JITでは、ブートストラップ時に情報を提供します。
- AOTを使用するときは、情報を
ngc
オプションとして渡します。
JITコンパイラとのマージ
JITコンパイラは、アプリケーションのロード時にブラウザでアプリケーションをコンパイルします。 JITコンパイラを使用した翻訳は、次のような動的プロセスです。
- 現在のユーザーの言語バージョンを確認します。
- 適切な言語翻訳ファイルを文字列定数としてインポートする。
- 対応する翻訳プロバイダを作成して、JITコンパイラをガイドします。
- これらのプロバイダを使用してアプリケーションをBootstrapします。
index.htmlを開き、次のようにスクリプトを修正します。
index.html (launch script)
<script>
// Get the locale id somehow
document.locale = 'es';
// Map to the text plugin
System.config({
map: {
text: 'systemjs-text-plugin.js'
}
});
// Launch the app
System.import('main.js').catch(function(err){ console.error(err); });
</script>
このサンプルでは、ユーザーの言語は、index.htmlのglobal document.locale変数としてハードコードされています。
SystemJS テキストプラグイン
このプラグインは、SystemJSを使用するアプリケーションにのみ適用されます。Angular CLIを使用している場合は、ドキュメントを参照してください。
systemjs-text-plugin.js
へのテキストのSystemJSマッピングに注目してください。 テキストプラグインの助けを借りて、SystemJSは任意のファイルを生のテキストとして読み込み、その内容を文字列として返すことができます。 言語翻訳ファイルをインポートする必要があります。
SystemJSには生のテキストプラグインは付属していませんが、簡単に追加できます。src/
フォルダに次のsystemjs-text-plugin.js
を作成します。
src/systemjs-text-plugin.js
/*
SystemJS Text plugin from
https://github.com/systemjs/plugin-text/blob/master/text.js
*/
exports.translate = function (load) {
if (this.builder && this.transpiler) {
load.metadata.format = 'esm';
return 'exp' + 'ort var __useDefault = true; exp' + 'ort default ' + JSON.stringify(load.source) + ';';
}
load.metadata.format = 'amd';
return 'def' + 'ine(function() {\nreturn ' + JSON.stringify(load.source) + ';\n});';
}
translation providersを作成する
3つのプロバイダは、アプリケーションのコンパイル中に特定の言語のテンプレートテキストを翻訳する方法をJITコンパイラに指示します。
-
TRANSLATIONS
は、翻訳ファイルの内容を含む文字列です。 -
TRANSLATIONS_FORMAT
は、xlf
、xlf2
、またはxtb
のファイル形式です。 -
LOCALE_ID
は、ターゲット言語のロケールです。
次のsrc/app/i18n-providers.ts
のgetTranslationProviders()
関数は、ユーザーのロケールと対応する変換ファイルに基づいてこれらのプロバイダを作成します。
src/app/i18n-providers.ts
import { TRANSLATIONS, TRANSLATIONS_FORMAT, LOCALE_ID, MissingTranslationStrategy } from '@angular/core';
import { CompilerConfig } from '@angular/compiler';
export function getTranslationProviders(): Promise<Object[]> {
// Get the locale id from the global
const locale = document['locale'] as string;
// return no providers if fail to get translation file for locale
const noProviders: Object[] = [];
// No locale or U.S. English: no translation providers
if (!locale || locale === 'en-US') {
return Promise.resolve(noProviders);
}
// Ex: 'locale/messages.es.xlf`
const translationFile = `./locale/messages.${locale}.xlf`;
return getTranslationsWithSystemJs(translationFile)
.then( (translations: string ) => [
{ provide: TRANSLATIONS, useValue: translations },
{ provide: TRANSLATIONS_FORMAT, useValue: 'xlf' },
{ provide: LOCALE_ID, useValue: locale },
])
.catch(() => noProviders); // ignore if file not found
}
declare var System: any;
function getTranslationsWithSystemJs(file: string) {
return System.import(file + '!text'); // relies on text plugin
}
- これは、
index.html
で設定されたグローバルdocument.locale
変数からロケールを取得します。 - ロケールが存在しない場合、または言語が米国英語(
en-US
)の場合、翻訳する必要はありません。この関数は空のnoProviders
配列をPromise
として返します。この関数は、サーバーから変換ファイルを非同期に読み取る可能性があるため、Promise
を返す必要があります。 - 前述の名前と場所の規則に従って、ロケールからトランザクションファイル名を作成します。
-
getTranslationsWithSystemJs()
メソッドは変換を読み取り、その内容を文字列として返します。テキストがファイル名に追加され、テキストプラグインを使用するようにSystemJSに通知します。 - コールバックは、3つの翻訳プロバイダを使用してプロバイダ配列を構成します。
- 最後に、
getTranslationProviders()
はすべての努力を約束として返します。
LOCALE_ID
は、ここで説明する有効なロケールIDでなければなりません。
translation providers の Bootstrap
Angular bootstrapModule()
メソッドには、コンパイラの動作に影響する可能性のある第2のオプションパラメータがあります。
getTranslationProviders()
の翻訳プロバイダを使用してオプションオブジェクトを作成し、それをbootstrapModule
に渡します。src/main.ts
を開き、以下のようにブートストラップコードを修正してください:
src/main.ts
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { getTranslationProviders } from './app/i18n-providers';
import { AppModule } from './app/app.module';
getTranslationProviders().then(providers => {
const options = { providers };
platformBrowserDynamic().bootstrapModule(AppModule, options);
});
アプリケーションを起動する前にgetTranslationProviders()
が解決するのを待つことに注意してください。
アプリは現在英語とスペイン語で国際化されており、さらに多くの言語を追加する明確な道があります。
AOTコンパイラによる国際化
JITコンパイラは、ブラウザで動的にコンパイルしながら、アプリケーションをターゲット言語に変換します。柔軟性はありますが、ユーザーにとっては十分に速いとは限りません。
AOT(Ahead-of-Time)コンパイラは、小型で高速ですぐに実行できるアプリケーションパッケージを作成するビルドプロセスの一部です。 AOTコンパイラーで国際化すると、言語ごとに個別のアプリケーション・パッケージが事前にビルドされます。次に、ホストWebページ(この場合はindex.html)で、ユーザーが必要とする言語を決定し、適切なアプリケーションパッケージを提供します。
このガイドでは、複数のアプリケーションパッケージを作成し、ユーザーの言語設定に従ってそれらを提供する方法については説明しません。これは、AOTコンパイラに翻訳ファイルを適用するよう指示するために必要ないくつかのステップを説明しています。
AOTコンパイラーによる国際化には、AOTコンパイル専用の設定が必要です。翻訳ファイルをマージする直前に示すように、アプリケーションプロジェクトから始め、AOTガイドを参照してAOT対応にしてください。
次に、英語を含むサポートされている言語ごとにngc compile
コマンドを実行します。その結果、言語ごとに別々のバージョンのアプリケーションが作成されます。
ngc
コマンドに3つのオプションを追加して翻訳する方法をAOTに伝えてください:
--i18nFile
:翻訳ファイルへのパス。
--locale
:ロケールの名前。
--i18nFormat
:ローカリゼーションファイルの形式。
このサンプルでは、スペイン語のコマンドは次のようになります。
./node_modules/.bin/ngc --i18nFile=./locale/messages.es.xlf --locale=es --i18nFormat=xlf
Windowsユーザーはコマンドを引用する必要があります:
"./node_modules/.bin/ngc" --i18nFile=./locale/messages.es.xlf --locale=es --i18nFormat=xlf
不足している翻訳をレポートする
翻訳を提供するのを忘れてしまった場合、簡単に間違っているかもしれないという警告とともにビルドが成功します。Angularコンパイラは、さまざまな「missing translation」ビヘイビアに対して構成できます。
- Error エラー
- Warning 警告(デフォルト)
- Ignore 無視
JITの動作を変更するには、次の構成を使用します。
{ provide: CompilerConfig, useValue: new CompilerConfig({ missingTranslation: MissingTranslationStrategy.Error }) }
これを使用する良い場所は翻訳プロバイダです:
src/app/i18n-providers.ts
return getTranslationsWithSystemJs(translationFile)
.then( (translations: string ) => [
{ provide: TRANSLATIONS, useValue: translations },
{ provide: TRANSLATIONS_FORMAT, useValue: 'xlf' },
{ provide: LOCALE_ID, useValue: locale },
{ provide: CompilerConfig, useValue: new CompilerConfig({ missingTranslation: MissingTranslationStrategy.Error }) }
])
.catch(() => noProviders); // ignore if file not found
AOTの動作を変更するには、--missingTranslation
フラグをcompilationコマンドに追加します。
./node_modules/.bin/ngc --i18nFile=./locale/messages.es.xlf --locale=es --i18nFormat=xlf --missingTranslation=error
ファイルのメンテナンスとidの変更
アプリケーションが進化するにつれて、i18nマークアップを変更し、ng-xi18n
抽出ツールを何度も再実行します。追加する新しいマークアップは問題ではありません。しかし、id
は深刻な問題になる可能性があります!
id
がツールによって生成された場合、既存のマークアップを変更すると、影響を受ける翻訳単位の新しいid
が生成されます。
id
が変更されると、変換ファイルは同期しなくなります。そのため、再コンパイル時に警告メッセージが表示されます。警告メッセージには、一部の翻訳が欠落していることが示されていますが、古いid
がもう有効ではないことはわかりません。
カスタムIDを使用する場合、対応する翻訳単位を変更する際にツールでカスタムIDが保持されます。他に行う理由がない限り、カスタムid
を使用してください。
生成IDまたはカスタムIDのどちらを使用する場合でも、すべての翻訳メッセージファイルをソース管理にコミットしてください(特に英語のソースmessages.xlf
)。古いmessages.xlf
ファイルと新しいmessages.xlf
ファイルの違いは、翻訳ファイル全体でid
やその他の変更を見つけて更新するのに役立ちます。