このチュートリアルでは、あなたのアプリが世界中の人々のためにアクセス可能でユーザーフレンドリーを作るプロセスを通してあなたを連れて行くつもりです。世界の約20パーセントだけが英語を話すので、他の言語のオプションを提供することで、あなたのユーザーエクスペリエンスを向上させ、あなたのアプリの到達範囲を大幅に向上させることができます。 Angularの組み込みの国際化ツールを見て、正しく使用する方法を説明します。
アプリではなくサイトを構築している場合は、ツールセットを正しく持っていることを確認してください。私たちのガイドをベストに見てください ウェブサイトビルダー そしてトップ ウェブホスティング もっと見つけるために。
プロセスを実証するための非常に単純なデモアプリを作成しました。 ここから複製してください その後、インストール手順に従ってください。
あなた自身を理解するためにアプリを始めてください。それはただ異なるコンテキストを持つ乱数と値を表示して更新するだけです。通貨、日付など、チュートリアル中に使用されるパイプと機能の一部をカバーします。
アプリ - 国際化とローカライゼーションを翻訳することについて話すときに互換的に使用される2つの単語があります - しかし、彼らは実際には少し異なることを意味します。国際化とは、さまざまな言語をサポートするためのアプリを準備するプロセスを指します。対照的に、ローカライズは実際にあなたのアプリを必要な言語に翻訳するプロセスを指します。基本的に国際化はあなたがアプリごとに何をするものであり、ローカル化はロケールごとに1回行われます - 少なくともそれは計画です。
これらの用語はまた、短縮されたバージョンによく知られている可能性があります.I18N(18は、最初の 'i'と最後の 'N'の国際化の間の文字数、L10n)とL10nの数です。そしてローカライズの 'n')。
今日世界中で6,000以上の言語が使われています。そのほとんどは非常に小さなグループでのみ使用されます。それでも上位3言語の上に焦点を当てていても、北京語、スペイン語、英語 - 日付の書式設定、文法構造、複数形、および数式のフォーマットに大きな違いがあります。
5番目に広く使用されている言語を含めると - アラビア語 - 私たちは別の違いに遭遇します。アラビア語は右から左(RTL)スクリプトです。これは、UIもミラーリングされなければならないことを意味します。
そのため、ローカライズ中、文法、レイアウト、フォーマットの違いを検討しなければならず、もちろんテキスト自体を変更する必要があります。角度はこれの大部分を助けることができますが、あなたはまだテキストを手動で翻訳する必要があります(そして翻訳を保存する) クラウドストレージ それで、それはあなたのチームと安全で共有可能です)。
サポートする必要があるロケールごとにローカライズする必要があります。ロケールとは、世界の地域、通常は国の地域内で共有される傾向がある上記の考慮事項の一般的な好みのセットを指します。各ロケールは、言語コードとロケール拡張子を指定するUnicodeロケール識別子によって表されます。
Angularのデフォルトのロケールは 'en-us'です。これは、地域「米国」(アメリカ合衆国)で話されている言語コード「en」(英語)です。 「en-us」のためにローカライズされたアプリは、イギリスで話されている英語である「en-GB」にローカライズされたアプリと微妙に異なります。たとえば、米国の日付は(バッフルリング)フォーマットされています。この小さな違いは、理解に大きな誤差を引き起こす可能性があります。
イラクで話されているようにアラビア語のためのデモアプリを興味深くしましょう。今回はデフォルトとして英語を使用します。
当社のデモプロジェクトは、いくつかの便利なツールを含むアンギュラCLIを使用して作成されました。このプロジェクトでは、このプロジェクトでは、前回の(AOT)コンパイラを使用しています。「angular.json」の変更を加える必要があります。ジャストインタイム(JIT)を使用したい場合は、物事をわずかに異なる方法で設定する必要があります。
AOTビルドを使用すると、テンプレートやスタイルシートなどのものを取得する必要なしにロードする必要なしにロードするReady-To-Goアプリケーションを表示します。その結果、ロケールごとにビルドを作成し、URLまたはある種のサーバー側の言語検出ロジックを使用して適切なビルドを提供する必要があります。最も簡単な方法は、各ロケールのディレクトリを作成することです。 www.example.com/en-gbとwww.example.com/ar-iq。トレードオフは、言語をオンザフライに切り替えることはできませんが、実際には実際のユーザーが必要とするものになる可能性が低いということです。
まず最初に私達は私達のアラビア語ロケールのためのビルド構成を追加する必要があります。 JSONファイルで、 'Architect.build.Configuration'オブジェクトを探します。次のブロックを追加して、ロケールの設定を定義します。
"AR-IQ":{
"basehref": "/ ar-iq /"、
"展開": "/ ar-iq /"、
"outputPath": "dist / angular-i18n-demo /
AR-IQ "、
"i18nfile": "src / locale / messages.ar-iq。
XLF "、
"i18nformat": "xlf"、
"i18nlocale": "AR-IQ"
この構成は、コンパイルされたビルドと使用する翻訳ファイルとフォーマットを出力する場所にあるAngularに指示します。ロケールを設定し、Appが展開されるディレクトリに抗体を伝えます。
また、 'en-gb'ロケールを使用するには、 'architect.build.options'のデフォルトオプションを変更する必要があります。図のように、次のプロパティを設定してください。 (注)このボード全体でAOTを有効にしているため、製造と開発の構築に使用されます。
「OUTPUTPATH」:「DIST / ANGULAR-I18N-DEMO / en-GB」、 "i18nlocale": "en-gb"、 "DeployUrl": "/ en-gb /"、 "basehref": "/ en-gb /"、 "AOT":TRUE角度はいくつかのロケールをサポートします。 [i18nlocale]プロパティに正しい値を使用してください。あなたは完全なリストを見ることができます ここに 。
シーンの背後にあるこの構成は、これらのロケール設定ファイルのいずれかから読み込まれて読み取ります。
ビルド出力を設定することに加えて、開発のための 'ng serve'コマンドの設定を設定する必要があります。追加したビルド構成を参照することができるので、これはより簡単です。 'angular.json'では、 'ArchitectServe.configurations'に次のブロックを追加します。
"AR-IQ":{
「BrowserTarget」:「angular-i18n-」
デモ:ビルド:AR-IQ "、
"ServePath": "/ AR-IQ /"
ここでは、「BrowserTarget」プロパティを使用してビルド構成オプションを参照しています。また、「ServePath」も設定しています。アラビア語アプリを作成または構築することができる前に、上記の 'i18nfile'プロパティで参照されている翻訳ファイルを作成する必要があります。 Angular CLIには、フラグ付きテキストを業界標準の翻訳元ファイルに抽出するためのツールが含まれています。
これらのファイルはチュートリアルの後半で後で詳しく説明しますが、今度は、コンパイルを許可するために基本的な空のファイルをエクスポートする必要があります。
次のオプションを使用して 'ng xi18n'コマンドを使用します。これは '--out-file'ファイル名にロケールIDを含める唯一の時です。
$ NG XI18N --output-path locale --out-file
messages.ar-iq.xlf --i18n-locale ar-iq
これにより、src / localeディレクトリにファイルを作成する必要があります。これからは、常に 'messages.xlf'という名前のファイルを出力し、その名前のロケールIDを使用してバージョンを手動でコピーします。その理由は、抽出ツールがファイルに追加された既存の翻訳を上書きするのを防ぐことです。
この時点で、プロジェクトをコンパイルして何が起こるかを確認できますが、使用する構成を「NG Serve」コマンドに指示する必要があります。まず英語版を見てみましょう。英語がデフォルトであるため、ここで変更はありません。
$ NGサーブ
あなたが見ることができるように、それはオリジナルのバージョンのように見えます。注目すべき違いは、$ $の代わりに$ $を指定するようになりました。さて、今アラビア語のバージョンを試してみましょう。英語版を停止して実行します。
$ NG Serve - Configuration = AR-IQ
あなたがこのバージョンでより明白な違いがあると思うように、特に日付はアラビア語で書かれています。月と日などのいくつかのものの名前は、セットリストからのものであり、最終的には既知の番号に関連しています。ただし、他のすべてはまだ英語です。
'app.component.html'のソースコードを詳しく見てください、そしてあなたは私たちがさまざまなパイプを使うことがわかります。次の角度パイプはロケール認識です。つまり、現在のロケール:「DatePipe」、「CurrencyPipe」、「DecimalPipe」、「CentialPipe」に基づいて、出力を適応させます。
あなたがこれらのパイプを慎重に使うならば、角度はたくさんあなたのためのローカライズされた脚仕事を扱います。慎重に私たちはあなたができるところで利用可能な事前定義されたオプションを使用することを意味します。良い例は、前述の米国の対イギリスの日付フォーマットです。あなたがイギリスにいるなら、(賢明な)日毎月のフォーマットを使用して日付を表示したい場合は、事前定義された「ショートデート」オプションがm / d / yyとしてレンダリングすることを発するようにイライラするかもしれません(例: 。10/9/18)そしてこのような望ましい形式をハードコードするように誘惑されます。
{{mydate |日付: 'dd / mm / y'}
しかし、角度はデフォルトで 'ja-us'ロケールを使用しているため、M / D / YYフォーマットを得ることがわかりました。したがって、フォーマットをハードコードする代わりに、[ShortDate]オプションを使用し、[en-GB]を使用するようにアプリをローカライズする必要があります。
{{mydate |日付: 'ShortDate'}}
それはもっと小さな努力を取りますが、私たちは私たちの心の内容にロケールを追加し、常にユーザーフレンドリーな日付形式を持ちます。
残念ながら、定義済みの形式を上書きするための簡単で組み込み方法があるようです。たとえば、実行時にフォーマットを変更する方法がないため、dd / mm / yの代わりに '' shortdate ''形式がdd / mm / yyyyになることをお勧めします。また、独自の定義済みのオプションを追加することはできません。
これらのエッジケースでは、Angular 'DatePipe'をラップし、ロケールごとのカスタムフォーマットを処理するカスタム日付パイプを作成できます。認識されないものは何でも組み込みの 'DatePipe'に渡されます。
棚から「CurrencyPipe」は米ドルとして数値をフォーマットし、小数点以下の桁数にトリムし、ロケールの設定で定義されているグループ化を追加します。
あなたは両方の地域で通貨が常に米ドルにあることに気付くでしょう。 'en-GB'ロケールを使用すると、魔法のようにSterling(GBP)に切り替えません。その理由は、£10が10ドルと同じではないため、番号を参照する通貨を明示的に指定する必要があります。
App.component.htmlを更新してGBPを通して使用しましょう。通貨コードを指定するときは、ISO 4217規格(オンラインでのリスト)から正しい値を使用する必要があります。
追加すると、 ':' gbp ''を追加して2つの通貨パイプを変更します。
{{value $ |非同期|通貨: 'GBP'}
そしてあなたは私たち$の代わりに£シンボルを見始めるでしょう。
覚えておいてください、あなたが通貨を変更するならば、GBPの同等の値にUSDを自動的に変換するようなものは何もしません - それが使用するシンボルを変更するだけです。
さて、私たちは2つのロケールを設定し、角度が唯一の仕事の中で箱から出して行っていますが、テキストはまだ英語中です。 Angularはこれを自動的に翻訳することはできませんが、それはワークフローの一部で私たちを助けることができます。これが起こらなければならないものです。
角度は、ステップ2と4で私たちを助けますが、開発者は手動でステップ1をする必要があります。ステップ3は通常、翻訳ファイルを読み書きするための特別なソフトウェアを使用して、翻訳専門家または代理店によって完了するでしょう。
これを実現するには、翻訳する固定テキストを含むすべての要素に特別な属性を追加する必要があります。コンテンツがAPIから到着した場合はクリアしてください。これは修正されたテキストではなく、APIでローカライズする必要があります。テキストがソースコード内のHTMLテンプレートに直接書き込まれたときにのみ属性を追加する必要があります。ここでのキーポイントは、TypeScriptファイルをlocale-agnosticに保持しようとする必要があります。つまり、コンポーネントロジックで翻訳する必要があるテキストをすべてテンプレート内に保持するのを避けることです。それ以外の場合、抽出ツールはそれを抽出することができません。とにかくあなたの懸念を分離するのは良い練習です - 人生とコードで。
'app.component.html'を開き、「現在の値」タイトルから始めましょう。テキストを直接含む要素に 'i18n'属性を追加するだけです。
divクラス= "Meta__title" I18N>
現在の価値
< / div>
これは単なる「ダム」カスタム属性であることを理解することが重要です。それは実行時に何も起動する角度指令ではありません、実際には、コンパイラは翻訳後にそれを削除します。
とにかく、抽出ツールを再度実行して翻訳ファイルを再生成するとどうなるのか見てみましょう。 「--out-file」は、現在「messages.xlf」です。
$ NG XI18N --output-path locale --out-file
messages.xlf --i18n-locale ar-iq
出力XLFファイルを開き、追加のコンテキスト情報と共にこのようなものに見える新しい翻訳単位ブロックが表示されます。
<トランスユニットID = "FACE3D45C0F0CD38B726E7798DA15
3E2F8D55551 "datatype =" html ">
< Source&GT。
現在の価値
< / source>
これは、ツールが 'i18n'属性を拾い上げたことを意味します。その長いIDはツールによって生成され、テキストが変わっていない限り同じままになります。同じテキストのインスタンスが複数ある場合、それらはすべて同じIDを取得します。このIDを編集しないでください。
ご希望の場合は、 'i18n'属性内にカスタムIDを指定できます。これを行うと、テキストが変更されていてもIDは同じままになりますので、アプリケーション全体でID衝突がないことを確認する必要があります。カスタムIDを設定するには '@@'の接頭辞を使用してください。ここでidは 'title'になるでしょう:
DIVクラス= "Meta__title" I18N = "@@ title"&gt。
現在の価値
< / div>
翻訳者が正確な翻訳を提供することができるようにするために、それらはしばしばテキストが使用されているというコンテキストを知る必要があるでしょう。 'i18n'属性では、翻訳者を支援するための説明と意味を定義できます。フォーマットは次のとおりです。
DIV I18N =「意味|説明@@
カスタマイズ ">テキスト< div>
意味や説明でタイトルを更新しましょう。
それは翻訳者に正確な翻訳を提供するのに十分な文脈を与えるべきです。翻訳ファイルを再生成し、これらの値が出力されているのを見てください。カスタムIDを使用しない場合、生成されたIDは意味とテキストをアカウントに取り込むことに注目する価値があります。それで同じテキストですが、異なる意味で、別のIDが得られます。ただし、説明はIDに影響を与えません。
イントロセクションに進みましょう。最初の段落にはテキストと実行時に補間される変数が含まれています。どうやってこれを取り扱うのですか?
幸せにそれはかなり簡単です。繰り返しますが、包含要素に意味のある「i18n」属性を追加する必要があります。段落要素に直接追加します。
< P i18n = "閉じる値|市場のときの値
昨日の@@ clowtvalue ">
抽出ツールをもう一度実行すると、この新しい翻訳単位が表示されます。
<トランスユニットID = "cmstantvalue"
データ型= "HTML">
< Source>昨日& apos; s閉じる値は
< x id = "補間" qquiv-text = "{{{{
clowtvalue |通貨:& apos; gbp& apos;
/ gt; / source>
可変補間が出力にどのように詳細にされているかを参照してください。これについての素晴らしいことは、翻訳者が必要に応じて文法を修正することができ、バインディングを破ることなく文法的な構造を修正することができます。たとえば、文が最もよく書かれている言語があるかもしれません:x値は昨日の閉まり、すなわち最初の変数と共に変数を使っていました。
次の段落に移動すると、威圧的な構文が表示されます。これはICUメッセージ形式と呼ばれ、変数の値に基づいてさまざまなテキストのチャンクを指定できます。
これを使用して、値がゼロであるかどうかを英語で単語に追加することができます。たとえば、 'seconds'がこのICU複数形式式を使用できる秒数を含む変数である場合
{秒}} {秒、複数、1つ
{second}、その他{秒}}
これは出力されます。
文書化されていないようですが、複数の構造構文の内側の「asyncpipe」を使用して、観測値を使用することもできます。
その例では「1つ」と「その他」は複数のカテゴリです。から選択するカテゴリがいくつかありますが、注意してください。すべてのロケールがすべてのカテゴリをサポートしているわけではなく、現在のロケールでサポートされていないカテゴリを使用しようとすると、角度はわかりません。 「2つの」カテゴリがあなたの 'en-gb'ロケールで機能していて、代わりにあなたは「他の」テキストを見ていないので、何か悪いことをしたことを考えやすいです。 「ゼロ」と「2」が明示的な値であっても、「en」(そして他の多くの一般的な言語)だけが '1と'その他 'をサポートします。
このファイルをチェックしてください 実際にサポートされているものを見るために。
カテゴリの代わりに番号を使用してこの制限を回避できます。値を '='で接頭辞するだけです。
{ウォッチャー、複数、= 0 {誰も誰もいない} = 1
{一人の人} = 2 {2人です}
その他{{{houthers}}}}
今見ている
これはすでにデモAppで設定されていますが、包含段落に 'i18n'属性を追加する必要があります。
< p i18n = "ウォッチャー|人々の数
値@@ Watchers "&GTを見てください。
抽出ツールをもう一度実行して、これがどのように見えるかを確認してください。これがわずかに異なる出力が出力されることがわかります。 2つの翻訳単位を作成します。 ICU式自体に1つ、その式を元の文字列に補間するもの。
変数の値に応じてさまざまなテキストを表示したい場合は、上記の「複数の」構文と非常に似ている「選択」ICU式を使用できます。私たちのデモAppでは、値に適用される変更を監視し、変更が正のものであるかゼロかに応じて 'up'、 'down'、または 'stable'を出力する「Trend $」という観察可能なストリームを作成します。
その後、ストリーム値に応じて異なる文字列を出力するように、[選択] ICU式を接続します。ここでは、「AsyncPipe」を使用して表示できます。
値{トレンド$ |非同期、選択、UP
{減少した}安定した{減少しました}
{変わらなかった}
DOMを操作するには「NGIF」または「NGSWITCH」を使用するよりもややクリーナーな構文です。プラス抽出ツールでもうまくいきます。収容要素に 'i18n'属性を追加します。
< DIVクラス= "Card__info" I18n = "値
トレンド|価値変更傾向@@トレンド "&gt。
翻訳ファイルを再生すると、2つの翻訳単位が作成された複数の出力と同様のアプローチが表示されます。 ICU式は、それらに慣れたらきれいに便利です。加えて、より複雑な出力を作成するようにそれらを入れ子にすることができます。
追加する1つの「i18n」属性
DIVクラス= "Card__info" I18n = "トランザクション
カウント|今日のトランザクション数@@
トランザクションの&gt。
トランザクション:{{Transactions $ |非同期|
番号}}
< / div>
これで、翻訳を必要とするすべてのテキストをマークアップしました。最後のテキストファイルを生成できます。作成されると、それを 'messages.ar-iq.xlf'に名前を変更し、前のincarnationを置き換えます。これは私たちが翻訳プロフェッショナルに送信しているファイルですが、このチュートリアルの目的のために、Google翻訳は立っているでしょう!
XLFファイルを開き、すべての '< source>'を複製します。要素、名前を変更する '<ターゲット>'。残念ながら、それは内容を美しくするのに役立つかもしれないのでそれはかなり乱雑になることがあります。
私たち全員を持っていることを確認するには、ファイルを保存してアラビア語ロケールでアプリを起動します。
$ NG Serve - Configuration = AR-IQ
このようなターミナルにメッセージが表示されている場合、それはあなたが逃したことを意味します:
XLIFF解析エラーのエラー:メッセージ* ID *
翻訳を欠場( "
うまくいけば、エラーはありませんが、ブラウザでアプリを見ることができます。実際のアラビア語がまだ追加されていませんので、それほど違うことはありません。
簡単なもので始めましょう - 「現在の値」のタイトル。 Google Translateは、(ここでのアラビア語のテキスト)になるべきだと言っているので、 '<ターゲット>'の値を更新する素子:
< Source>現在の値
ここまでは順調ですね。今度は補間のあるものをしましょう。ここに「昨日の締め切り価値は...」(うまくいけば!):
<ターゲット>アラビア語のテキスト< x
id = "補間" qquiv-text = "{{{clignvalue
| ..通貨:& apos; gbp& apos; "/> / lt ;/target>
翻訳するときに番号を使用して、補間がある場所を確認できます。 Google翻訳の翻訳結果が表示されたら、逆に見えます - つまり、スタート時の数字は、それをコピーして翻訳ファイルに貼り付けると元の注文に戻ります。これはアラビア語がRTL言語であるため、このスクリプトが(ほとんど)ミラーリングされているために起こります。 Google Translateは、含める要素に 'dir = "rtl"属性を追加することによってこれを行います。次のステップでこれを行う方法を学びます。残りの翻訳はデモrepo、チュートリアルの支店で利用可能です。
Angularが自動的にこれをやらないので、私たちは私たちのアプリでスクリプトの方向を管理する必要があります。現在のロケールがLTRまたはRTL言語であるかどうかを検出する方法もありますので、これをハードコードする必要があります。角度がこれに組み込まれた指令を提供した場合は素晴らしいことです。
'app.component.ts'を開きます。 'inject'、 'locale_id'と 'hostbinding'から '' @ angular / core ''をインポートします。次に、次のように「hostbinding」を設定します。これにより、AppComponentに 'dir'属性が追加され、デフォルトの言語方向を 'ltr'に設定します。
@ hostbinding( 'attr.dir')dir = 'ltr';
次にコンストラクタを追加し、 'locale_id'を注入します。 AOTを使用しているので、これを忘れないでください。
コンストラクタ(@inject(locale_id)プライベートロケール:String){}
そして最後に既存の 'ngoninit'メソッドに次のスニペットを追加します。ここでは、 'locale_id'、すなわち 'ar-iq'が 'ar'で始まり、それが代わりに 'rtl'に変更された場合にチェックします。
if(this.locale.startswith( 'ar')){
this.dir = 'rtl';
あなたがより多くのロケールをサポートする予定ならば、あなたは今日使用されているためにこれをよりスケーラブルにするためにこれをリファクタリングする必要があるでしょう。アラビア語アプリを起動して、UIがミラーリングされていることがわかりました - £サインは右側にあるべきです。
最後のステップは、製造ビルドを生成して確認することです。ただし、まず、「angular.json」設定を別の素早い変更にする必要があります。
'Architect.Build.Configurations'では、既存のプロダクションオブジェクトを複製し、それを「expecking-ar-iq」の名前を変更します。次に、既存の '"AR-IQ"構成からオブジェクトへのプロパティをコピーして貼り付けて、本番オプションと' i18n 'オプションの両方があります。
また、 'ArchitectServe.configurations'を更新する必要があります。今回は既存の '"AR-IQ"オブジェクトを複製し、それを「expecking-ar-iq」の名前を変更し、新しい' production-ar-iq '構成を指すように' browserget 'の値を変更します。
これで、このコマンドであなたの生産ロケールを構築して提供することができます。
$ NGサーブ - Configuration = Production-AR-IQ
さて、私たちはやった!私たちは私たちのアプリを国際化しました、そしてそれを 'en-gb'と 'ar-iqのオーディエンスのためにローカライズしました。角度が開発者向けにプロセスを著しく簡単にして、実際には最も難しいビットは、何でも間違っている場合はアラビア語のスピーカーを謝罪する必要があるものです。
この記事はもともとCreative Web Design Magazine Web Designerの第281号に掲載されました。 ここで問題281を購入してください または ここでWeb Designerを購読してください 。
関連記事: