docs(i18n): apply guidelines and update TOCs (#3535)

This commit is contained in:
Kapunahele Wong 2017-04-12 15:18:38 -04:00 committed by Ward Bell
parent 8554e38dd2
commit 9bb44197ec
1 changed files with 140 additions and 120 deletions

View File

@ -4,24 +4,36 @@ a#top
:marked
Angular's _internationalization_ (_i18n_) tools help make your app available in multiple languages.
## Table of contents
# Contents
* [Angular and i18n template translation](#angular-i18n)
* [Mark text with the _i18n_ attribute](#i18n-attribute)
* [Help the translator with a description and intent](#help-translator)
* [Translate text without creating an element](#no-element)
* [Add _i18n-..._ translation attributes](#translate-attributes)
* [Handle singular and plural](#cardinality)
* [Select among alternative texts](#select)
* [Create a translation source file with the **_ng-xi18n_ extraction tool**](#ng-xi18n)
* [Other translation formats](#other-formats)
* [Other options](#ng-xi18n-options)
* [Add an `npm` script for convenience](#npm-i18n-script)
* [Translate text messages](#translate)
* [Create a localization folder](#localization-folder)
* [Translate text nodes](#translate-text-nodes)
* [Translate `plural` and `select`](#translate-plural-select)
* [Translate `plural`](#translate-plural)
* [Translate `select`](#translate-select)
* [The app before translation](#app-pre-translation)
* [Merge the completed translation file into the app](#merge)
* [Merge with the JIT compiler](#jit)
* [SystemJS text plugin](#text-plugin)
* [Create translation providers](#create-translation-providers)
* [Bootstrap the app with translation providers](#bootstrap-the-app)
* [Internationalization with the AOT compiler](#aot)
* [Translation file maintenance and _id_ changes](#maintenance)
:marked
**Try this** <live-example name="cb-i18n" title="i18n Example in Spanish">live example</live-example>
Try this <live-example name="cb-i18n" title="i18n Example in Spanish">live example</live-example>
of a JIT-compiled app, translated into Spanish.
@ -82,6 +94,7 @@ a#i18n-attribute
+makeExample('cb-i18n/ts/src/app/app.component.1.html', 'i18n-attribute', 'src/app/app.component.html')(format=".")
a#help-translator
:marked
### Help the translator with a _description_ and _intent_
@ -106,6 +119,8 @@ a#i18n-attribute
The Angular extraction tool preserves both the _meaning_ and the _description_ in the translation source file
to facilitiate contextually-specific translations.
a#no-element
:marked
### Translate text without creating an element
Suppose there is a stretch of text that you'd like to translate.
@ -188,7 +203,7 @@ a#cardinality
This syntax conforms to the
<a href="http://userguide.icu-project.org/formatparse/messages" target="_blank" title="ICU Message Format">ICU Message Format</a>
that derives from the
<a href="http://cldr.unicode.org/" target="_blank" title="CLDR">Common Locale Data Repository (CLDR),</a>
<a href="http://cldr.unicode.org/" target="_blank" title="CLDR">Common Locale Data Repository (CLDR)</a>,
which specifies the
<a href="http://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules" target="_blank" title="Pluralization Rules">pluralization rules</a>.
@ -302,8 +317,8 @@ a#localization-folder
You will probably translate into more than one other language so it's a good idea
for the project structure to reflect your entire internationalization effort.
One approach is to dedicate a folder to localization and store related assets
(for example, internationalization files) there.
One approach is to dedicate a folder to localization and store related assets,
such as internationalization files, there.
.l-sub-section
:marked
Localization and internationalization are
@ -316,7 +331,8 @@ a#localization-folder
Make a copy of the `messages.xlf` file, put it in the `locale` folder and
rename it `messages.es.xlf`for the Spanish language translation.
Do the same for each target language.
a#translate-text-nodes
:marked
### Translate text nodes
In the real world, you send the `messages.es.xlf` file to a Spanish translator who fills in the translations
using one of the
@ -352,18 +368,20 @@ a#translate-plural-select
The `<source>` tag is empty for `plural` and `select` translation
units, which makes them hard to correlate with the original template.
The `XLIFF` format doesn't yet support the ICU rules; it soon will.
The `XLIFF` format doesn't yet support the ICU rules.
However, the `XMB` format does support the ICU rules.
You'll just have to look for them in relation to other translation units that you recognize from elsewhere in the source template.
In this example, you know the translation unit for the `select` must be just below the translation unit for the logo.
a#translate-plural
:marked
### Translate _plural_
To translate a `plural`, translate its ICU format match values:
+makeExample('cb-i18n/ts/src/locale/messages.es.xlf.html', 'translated-plural', 'src/locale/messages.es.xlf (<trans-unit>)')(format=".")
a#translate-select
:marked
### Translate _select_
The `select` behaves a little differently. Here again is the ICU format message in the component template:
@ -422,14 +440,14 @@ a#merge
To merge the translated text into component templates,
compile the application with the completed translation file.
The process is the same whether the file is in `.xlf` format or
in another format (`.xlif` and `.xtb`) that Angular understands.
in another format that Angular understands, such as `.xlif` or `.xtb`.
You provide the Angular compiler with three new pieces of information:
* the translation file
* the translation file format
* the <a href="https://en.wikipedia.org/wiki/XLIFF" target="_blank">_Locale ID_</a>
(`es` or `en-US` for instance)
* The translation file.
* The translation file format.
* The <a href="https://en.wikipedia.org/wiki/XLIFF" target="_blank">_Locale ID_</a>
(`es` or `en-US` for instance).
_How_ you provide this information depends upon whether you compile with
the JIT (_Just-in-Time_) compiler or the AOT (_Ahead-of-Time_) compiler.
@ -458,7 +476,7 @@ a#jit
a#text-plugin
:marked
### SystemJS Text plugin
### SystemJS text plugin
Notice the SystemJS mapping of `text` to a `systemjs-text-plugin.js`.
With the help of a text plugin, SystemJS can read any file as raw text and
@ -468,6 +486,7 @@ a#text-plugin
SystemJS doesn't ship with a raw text plugin but it's easy to add.
Create the following `systemjs-text-plugin.js` in the `src/` folder:
+makeExample('cb-i18n/ts/src/systemjs-text-plugin.js', null, 'src/systemjs-text-plugin.js')(format='.')
a#create-translation-providers
:marked
### Create translation providers
@ -475,10 +494,10 @@ a#text-plugin
while compiling the application:
* `TRANSLATIONS` is a string containing the content of the translation file.
* `TRANSLATIONS_FORMAT` is the format of the file: `xlf`, `xlif` or `xtb`.
* `TRANSLATIONS_FORMAT` is the format of the file: `xlf`, `xlif`, or `xtb`.
* `LOCALE_ID` is the locale of the target language.
The `getTranslationProviders` function in the following `src/app/i18n-providers.ts`
The `getTranslationProviders()` function in the following `src/app/i18n-providers.ts`
creates those providers based on the user's _locale_
and the corresponding translation file:
+makeExample('cb-i18n/ts/src/app/i18n-providers.ts', null, 'src/app/i18n-providers.ts')
@ -493,24 +512,25 @@ a#text-plugin
1. It creates a transaction filename from the locale according to the name and location convention
[described earlier](#localization-folder).
1. The `getTranslationsWithSystemJs` method reads the translation and returns the contents as a string.
1. The `getTranslationsWithSystemJs()` method reads the translation and returns the contents as a string.
Notice that it appends `!text` to the filename, telling SystemJS to use the [text plugin](#text-plugin).
1. The callback composes a providers array with the three translation providers.
1. Finally, `getTranslationProviders` returns the entire effort as a promise.
1. Finally, `getTranslationProviders()` returns the entire effort as a promise.
a#bootstrap-the-app
:marked
### Bootstrap the app with translation providers
The Angular `bootstrapModule` method has a second, _options_ parameter
The Angular `bootstrapModule()` method has a second _options_ parameter
that can influence the behavior of the compiler.
You'll create an _options_ object with the translation providers from `getTranslationProviders`
You'll create an _options_ object with the translation providers from `getTranslationProviders()`
and pass it to `bootstrapModule`.
Open the `src/main.ts` and modify the bootstrap code as follows:
+makeExample('cb-i18n/ts/src/main.ts', null, 'src/main.ts')(format=".")
:marked
Notice that it waits for the `getTranslationProviders` promise to resolve before
Notice that it waits for the `getTranslationProviders()` promise to resolve before
bootstrapping the app.
The app is now _internationalized_ for English and Spanish and there is a clear path for adding
@ -519,7 +539,7 @@ a#text-plugin
a#aot
.l-main-section
:marked
### _Internationalize_ with the AOT compiler
### _Internationalization_ with the AOT compiler
The JIT compiler translates the application into the target language
while compiling dynamically in the browser.
@ -529,7 +549,7 @@ a#aot
produces a small, fast, ready-to-run application package.
When you internationalize with the AOT compiler, you pre-build
a separate application package for each
language. Then in the host web page (`index.html`),
language. Then in the host web page, in this case `index.html`,
you determine which language the user needs
and serve the appropriate application package.
@ -543,16 +563,16 @@ a#aot
[just before merging the translation file](#app-pre-translation)
and refer to the [AOT cookbook](aot-compiler.html) to make it _AOT-ready_.
Next, issue an `ngc` compile command for each supported language (including English).
Next, issue an `ngc` compile command for each supported language, including English.
The result is a separate version of the application for each language.
Tell AOT how to translate by adding three options to the `ngc` command:
* `--i18nFile`: the path to the translation file
* `--locale`: the name of the locale
* `--i18nFormat`: the format of the localization file
* `--i18nFile`: the path to the translation file.
* `--locale`: the name of the locale.
* `--i18nFormat`: the format of the localization file.
For this sample, the Spanish language command would be
For this sample, the Spanish language command would be:
code-example(language="sh" class="code-shell").
./node_modules/.bin/ngc --i18nFile=./locale/messages.es.xlf --locale=es --i18nFormat=xlf
@ -569,10 +589,10 @@ a#maintenance
As the application evolves, you will change the _i18n_ markup
and re-run the `ng-xi18n` extraction tool many times.
The _new_ markup that you add is not a problem;
but _most_ changes to _existing_ markup trigger
generation of _new_ `id`s for the affected translation units.
but _most_ changes to existing markup trigger
generation of new `id`s for the affected translation units.
After an `id` changes, the translation files are no longer in-sync.
After an `id` changes, the translation files are no longer in sync.
**All translated versions of the application will fail** during re-compilation.
The error messages identify the old `id`s that are no longer valid but
they don't tell you what the new `id`s should be.