47 KiB
Internationalization (i18n)
国际化(i18n)
Angular's internationalization (i18n) tools help make your app available in multiple languages.
Angular的国际化(i18n)工具可以帮助我们使用多个语言发布应用。
Try this live example of a JIT-compiled app, translated into Spanish.
试试 这个翻译为西班牙语版JiT编译应用的在线例子。
{@a angular-i18n}
Angular and i18n template translation
Angular和_i18n_模板翻译
Application internationalization is a challenging, many-faceted effort that takes dedication and enduring commitment. Angular's i18n internationalization facilities can help.
应用程序国际化很具有挑战性,多方面的努力,需要持久的奉献和决心。 Angular的_i18n_国际化工具可以帮助你。
This page describes the i18n tools available to assist translation of component template text into multiple languages.
本章描述了一些_i18n_工具,它们可以帮你把组件模板文本翻译成多种语言。
Practitioners of internationalization refer to a translatable text as a "message". This page uses the words "text" and "message" interchangeably and in the combination, "text message". 国际化工作者通常将一个可翻译的文本叫作“信息”。 本章使用了“文本”和“信息”,它们可以互换,也可以组合“文本信息”。
The i18n template translation process has four phases:
_i18n_模板翻译流程有四个阶段:
-
Mark static text messages in your component templates for translation.
在组件模板中标记需要翻译的静态文本信息。
-
An angular i18n tool extracts the marked messages into an industry standard translation source file.
Angular的_i18n_工具将标记的信息提取到一个行业标准的翻译源文件。
-
A translator edits that file, translating the extracted text messages into the target language, and returns the file to you.
翻译人员编辑该文件,翻译提取出来的文本信息到目标语言,并将该文件还给你。
-
The Angular compiler imports the completed translation files, replaces the original messages with translated text, and generates a new version of the application in the target language.
Angular编译器导入完成翻译的文件,使用翻译的文本替换原始信息,并生成新的目标语言版本的应用程序。
You need to build and deploy a separate version of the application for each supported language.
你可以为每种支持的语言构建和部署单独的应用程序版本。
{@a i18n-attribute}
Mark text with the i18n attribute
使用_i18n_属性标记文本
The Angular i18n
attribute is a marker for translatable content.
Place it on every element tag whose fixed text should be translated.
Angular的i18n
属性是可翻译内容的标记。
将它放到每个固定文本需要翻译的元素标签中。
i18n
is not an Angular directive.
It's a custom attribute, recognized by Angular tools and compilers.
After translation, the compiler removes it.
i18n
不是Angular指令。
它是一个自定义属性,Angular工具和编译器认识它。
它将在完成翻译之后,被编译器移除。
In the accompanying sample, an <h1>
tag displays a simple English language greeting
that you translate into Spanish:
在例子中,<h1>
标签显示了一句简单的英文问候语,它将被翻译为西班牙语:
Add the i18n
attribute to the tag to mark it for translation.
添加i18n
属性到该标签上,把它标记为需要翻译的文本。
{@a help-translator}
Help the translator with a description and meaning
用描述和意图来帮助翻译人员
In order to translate it accurately, the translator may need a description of the message. Assign a description to the i18n attribute:
翻译人员可能需要待翻译文本的描述才能翻译准确。 为i18n属性添加描述:
In order to deliver a correct translation, the translator may need to know the meaning or intent of the text within this particular application context.
为了给出正确的翻译,翻译者需要知道你这段文本在特定情境下的 真实意图。
You add context by beginning the string with the meaning and
separating it from the description with the |
character (<meaning>|<description>
):
在描述的前面,我们为指定的字符串添加一些上下文含义,用|
将其与描述文字隔开(<意图>|<描述>
)。
While all appearances of a message with the same meaning have the same translation, a message with a variety of possible meanings could have different translations. The Angular extraction tool preserves both the meaning and the description in the translation source file to facilitate contextually-specific translations.
如果所有地方出现的文本具有相同含义时,它们应该有相同的翻译, 但是如果在某些地方它具有不同含义,那么它应该有不同的翻译。 Angular的提取工具在翻译源文件中保留含义和描述,以支持符合特定上下文的翻译。
{@a custom-id}
Set a custom id to improve search and maintenance
设置一个自定义的id
来提升可搜索性和可维护性
The angular i18n extractor tool generates a file with a translation unit entry for each i18n
attribute in a template. By default, it assigns each translation unit a unique id such as this one:
Angular 的 i18n
提取工具会为模板中每个带有i18n
属性的元素生成一个*翻译单元(translation unit)*条目,并保存到一个文件中。默认情况下,它为每个翻译单元指定一个唯一的id
,就像这样:
This id is obscure and difficult for humans to read or remember.
这个id
对于人类来说太晦涩,难于阅读和记忆。
Worse, when you change the translatable text, perhaps to fix a typo, the extractor tool generates a new id for that translation. You will lose the translation unless you update it with the new id. That complicates maintenance.
更糟的是,当我们修改这段可翻译的文字时(比如修改一个拼写错误),提取工具会生成一个新的id
。
我们就会丢失这段翻译成果,除非把它修改为新的id
。那样维护起来就太复杂了。
Consider specifying your own, meaningful id in the i18n
attribute, prefixed with @@
.
要想自己为i18n
属性指定一个有意义的id
,可以给它添加@@
前缀。
Now the extractor tool and compiler will generate a translation unit with your custom id and never change it.
现在,提取工具和编译器就会用*你的自定义id`生成一个翻译单元,而不会再改变它。
Here is the i18n
attribute with a definition, followed by the custom id
:
下面这个例子中的i18n
属性中有一个定义,然后跟着自定义id
:
Here is a meaning and a description and the id at the end:
下面这个例子带有含义和描述,最后是id
:
Be sure to define unique custom ids. If you use the same id for 2 different blocks of text, only the first one will be extracted, and its translation used in both blocks of text.
为了确保定义出唯一的自定义id。如果我们对两个不同的文本块使用了同一个id,那么就只有一个会被提取出来,然后其翻译结果会被用于全部文本块。
For example:
比如:
<p i18n="@@myId">Hello</p>
<p i18n="@@myId">Good bye</p>
with the translation:
带有翻译结果的:
<trans-unit id="myId" datatype="html">
<source>Hello</source>
<target state="new">Hola</target>
</trans-unit>
Both <p>
elements will contain the text Hola
.
两个<p>
元素都会包含文本Hola
。
{@a no-element}
Translate text without creating an element
翻译文本,而不必创建元素
Suppose there is a stretch of text that you'd like to translate.
You could wrap it in a <span>
tag but for some reason (CSS comes to mind)
you don't want to create a new DOM element merely to facilitate translation.
假设有一段文字要翻译。
我们可以把它包装进<span>
标签中,但是因为某些原因(比如出于CSS方面的考虑),你可能不想仅仅为了翻译而创建一个新的DOM元素。
Here are two techniques to try.
可以尝试两种技术来解决这个问题。
(1) Wrap the text in an <ng-container>
element. The <ng-container>
is never rendered:
(1) 把文本包装进一个<ng-container>
元素中。而<ng-container>
永远不会被渲染出来:
(2) Wrap the text in a pair of HTML comments:
(2) 把文本包装进一对 HTML 注释中:
{@a translate-attributes}
Add i18n translation attributes
添加 i18n 翻译属性
You've added an image to your template. You care about accessibility too so you add a title
attribute:
我们已经把一个图片添加到了模板中。我们也关心可访问性,故此也添加了一个title
属性:
The title
attribute needs to be translated.
Angular i18n support has more translation attributes in the form,i18n-x
, where x
is the
name of the attribute to translate.
这个 title
属性也需要翻译。
Angular i18n 支持更多形如i18n-x
的属性,其中的x
就是要翻译的属性名。
To translate the title
on the img
tag from the previous example, write:
为了翻译前面例子中img
标签上的title
属性,就要这样写:
You can also assign a meaning and a description with the i18n-x="<meaning>|<description>"
syntax.
我们也同样可以使用i18n-x="<meaning>|<description>"
语法来指定一个含义和描述。
{@a cardinality}
Handle singular and plural
处理单数与复数
Different languages have different pluralization rules.
不同的语言有不同的单复数规则。
Suppose your application says something about a collection of wolves. In English, depending upon the number of wolves, you could display "no wolves", "one wolf", "two wolves", or "a wolf pack". Other languages might express the cardinality differently.
假设应用中需要谈论一些狼。 在英语中,根据狼的数量,可能要显示为"no wolves"、"one wolf"、"two wolves"或"a wolf pack"。 而在其它语言中则可能会有不同的基数规则。
Here's how you could mark up the component template to display the phrase appropriate to the number of wolves:
下面我们示范要如何书写组件模板来显示适当的短语来表示狼的数量:
-
The first parameter is the key. It is bound to the component property (
wolves
) that determines the number of wolves.第一个参数是key。它绑定到了组件中表示狼的数量的
wolves
属性。 -
The second parameter identifies this as a
plural
translation type.第二个参数表示这是一个
plural
(复数)翻译类型。 -
The third parameter defines a pluralization pattern consisting of pluralization categories and their matching values.
第三个参数定义了一组复数表示模式,这个模式由复数类别和它们所匹配的值组成。
Pluralization categories include:
复数类别包括:
-
=0 (or any other number)
=0 (或其它数字)
-
zero
zero(零)
-
one
one(一个)
-
two
two(两个)
-
few
few(少数)
-
many
many(很多)
-
other
other(其它)
Put the default English translation in braces ({}
) next to the pluralization category.
把默认的英语翻译结果放在复数类别之后的括号({}
)中。
-
When you're talking about one wolf, you could write
=1 {one wolf}
.如果要说一只狼,就写
=1 {one wolf}
。 -
For zero wolves, you could write
=0 {no wolves}
.如果要说零只狼,就写
=0 {no wolves}
。 -
For two wolves, you could write
=2 {two wolves}
.如果要说两只狼,就写
=2 {two wolves}
。
You could keep this up for three, four, and every other number of wolves.
Or you could specify the other
category as a catch-all for any unmatched cardinality
and write something like: other {a wolf pack}
.
三只、四只或其它数量的狼也都以此类推。
或者,我们也可以指定**other
**类来捕获所有未匹配上的数量,写法为:other {a wolf pack}
。
This syntax conforms to the ICU Message Format that derives from the Common Locale Data Repository (CLDR), which specifies the pluralization rules.
这个写法符合ICU消息格式,它源自通用区域设置数据库(CLDR),其中指定了复数规则。
{@a select}
Select among alternative texts
在候选文本中选择
The application displays different text depending upon whether the hero is male or female. These text alternatives require translation too.
该应用还要根据英雄是男是女而显示出不同的文本,这些候选文本也同样需要翻译。
You can handle this with a select
translation.
A select
also follows the
ICU message syntax.
You choose among alternative translation based on a string value instead of a number.
我们可以使用select
翻译器来处理它。
select
也同样遵循 ICU 消息语法。我们在候选文本之间选择,但根据的是一个字符串值而不再是数字。
The following format message in the component template binds to the component's gender
property, which outputs either an "m" or an "f".
The message maps those values to the appropriate translation:
组件模板中的下列消息格式绑定到了组件的gender
属性,这个属性的取值是"m"或"f"。
这个消息会把那些值映射到适当的翻译文本:
Nesting pluralization and selection expressions
把"复数"与"选择"表达式嵌套在一起
You can also nest different ICU expressions together. For example:
我们也可以把不同的 ICU 表达式嵌套在一起,比如:
{@a ng-xi18n}
Create a translation source file with the ng-xi18n tool
使用_ng-xi18n_工具创建翻译源文件
Use the ng-xi18n extraction tool to extract the i18n
-marked texts
into a translation source file in an industry standard format.
使用ng-xi18n
提取工具来将i18n
标记的文本提取到一个符合行业标准格式的翻译源文件。
This is an Angular CLI tool in the @angular/compiler-cli
npm package.
If you haven't already installed the CLI and its platform-server
peer dependency, do so now:
它是在@angular/compiler-cli
npm包中的一个Angular CLI工具。
如果你还没有安装这个CLI和它的 platform-server
,安装它们:
Open a terminal window at the root of the application project and enter the ng-xi18n
command:
在应用的项目根目录打开一个终端窗口,并输入ng-xi18n
命令:
Windows users may have to quote the command like this: "./node_modules/.bin/ng-xi18n"
By default, the tool generates a translation file named messages.xlf
in the
XML Localization Interchange File Format (XLIFF, version 1.2).
工具默认生成一个名为**messages.xlf
**的翻译文件,格式为XML本土化互换文件格式(XLIFF, version 1.2)。
{@a other-formats}
Other translation formats
其它翻译格式
Angular i18n tooling supports XLIFF 1.2 and XLIFF 2 as well as the XML Message Bundle (XMB).
除了XML消息捆(XMB)格式外,Angular的i18n工具也同样支持 XLIFF 1.2和XLIFF 2 格式。
You can specify your choice of format explicitly with the --i18nFormat
flag as illustrated in these example commands
我们可以使用--i18nFormat
来明确指定想用的格式,范例如下:
The sample in this guide sticks with the default XLIFF 1.2 format.
本章的范例默认使用 XLIFF 1.2 格式。
{@a ng-xi18n-options}
Other options
其它选项
You may have to specify additional options.
For example, if the tsconfig.json
TypeScript configuration
file is located somewhere other than in the root folder,
you must identify the path to it with the -p
option:
我们还可能需要指定其它选项。
比如,如果TypeScript的配置文件tsconfig.json
位于其它地方而不是根目录,我们就要通过-p
选项来明确指出它的路径。
{@a npm-i18n-script}
Add an npm script for convenience
添加npm
便利脚本
Consider adding a convenience shortcut to the scripts
section of the package.json
to make the command easier to remember and run:
考虑在package.json
的scripts
区中添加一个便利脚本,来让命令更容易记忆和运行:
Now you can issue command variations such as these:
现在,我们就可以使用这些命令的变体形式了,比如:
npm run i18n npm run i18n -- -p path/to/tsconfig.json npm run i18n -- --i18nFormat=xmb -p path/to/tsconfig.jsonNote the --
flag before the options.
It tells npm to pass every flag thereafter to ng-xi18n
.
注意选项前面的--
标识。它告诉npm
要把这个参数后面的每一个标识都透传给ng-xi18n
。
{@a translate}
Translate text messages
翻译文本信息
The ng-xi18n
command generates a translation source file
in the project root folder named messages.xlf
.
The next step is to translate the English language template
text into the specific language translation
files. The guide sample creates a Spanish translation file.
ng-xi18n
命令在项目根目录生成一个名为messages.xlf
的翻译源文件。
下一步是将英文模板文本翻译到目标语言的翻译文件。
本烹饪书创建了一个西班牙语翻译文件。
{@a localization-folder}
Create 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 , such as internationalization files, there.
其中一种方法是为本土化和相关资源(比如国际化文件)创建一个专门的目录。
Localization and internationalization are different but closely related terms.
本土化和国际化是不同但是很相近的概念。
This guide follows that suggestion. It has a locale
folder under src/
.
Assets within the folder carry a filename extension that matches a language-culture code from a
well-known codeset.
本指南遵循了那个建议。在src/
目录下,有一个专门的locale
目录,该目录中的文件都带有一个代号作为扩展名,它们来自这个众所周知的代号表。
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.
复制一下messages.xlf
文件,把它放进locale
目录,并改名为messages.es.xlf
以用于西班牙语的翻译。对其它目标语言也同样要这么做。
{@a translate-text-nodes}
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
many XLIFF file editors.
在现实世界中,messages.es.xlf
文件会被发给西班牙语翻译,他们使用这些XLIFF文件编辑器中的一种来翻译它。
This sample file is easy to translate without a special editor or knowledge of Spanish.
Open messages.es.xlf
and find the first <trans-unit>
section:
我们不需要任何编辑器或者西班牙语知识就可以轻易的翻译本例子文件。
打开messages.es.xlf
并找到<trans-unit>
节点:
This XML element represents the translation of the <h1>
greeting tag you marked with the i18n
attribute.
这个XML元素代表了你使用i18n
属性标记的<h1>
问候语标签的翻译。
注意,翻译单元id=introductionHeader
派生自自定义id
,它设置起来更简单,但是在HTML源码中不需要@@
前缀。
Using the source, description, and meaning elements to guide your translation,
replace the <target/>
tag with the Spanish greeting:
翻译中利用_source_、_description_和_meaning_元素的信息,替换<target/>
标签为西班牙语问候语:
Translate the other text nodes the same way:
The tool generated the id
s for these translation units. Don't touch them.
Each id
depends upon the content of the message and its assigned meaning.
Change either factor and the id
changes as well.
注意id
是工具生成的。不要修改它。
它的值取决于两个因素:信息的内容和其指定的含义。
改变任何一个因素,id
就会改变。
See the translation file maintenance discussion.
参见**关于如何维护翻译结果文件的讨论**。
This is why you should specify custom ids and avoid tool generated ids.
这就是为什么我们应该**指定自定义 id**,避免让工具自动生成id。
{@a translate-plural-select}
Translate plural and select
翻译复数(plural)和选择(select)
Translating plural and select messages is a little tricky.
翻译复数和选择类的消息有点棘手。
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.
However, the XMB
format does support the ICU rules.
对于复数(plural
)和选择(select
)类型的翻译单元来说,标签是空的,这让它们很难和原始模板关联起来。
XLIFF 不支持这种 ICU 规则,但
XMB`格式却支持。
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.
我们要根据从原始模板中其它地方识别出来的翻译单元来找到建立它和原始模板之间的关联。
比如在这个例子中,我们知道select
一定会出现在logo的翻译单元的紧下方。
{@a translate-plural}
Translate plural
翻译复数
To translate a plural
, translate its ICU format match values:
要翻译一个复数,就要翻译它的ICU格式中匹配的值:
{@a translate-select}
Translate select
翻译选择(select)
The select
behaves a little differently. Here again is the ICU format message in the component template:
select
的行为略有不同。我们仍然来看组件模板中的ICU格式的消息:
The extraction tool broke that into two translation units.
提取工具会把它拆成两个翻译单元。
The first unit contains the text that was outside the select
.
In place of the select
is a placeholder, <x id="ICU">
, that represents the select
message.
Translate the text and leave the placeholder where it is.
第一个单元包含select
之外的文本。
这里的select
是一个占位符<x id="ICU">
,用来表示select
中的消息。
翻译这段文本,并把占位符放在那里。
The second translation unit, immediately below the first one, contains the select
message. Translate that.
第一个翻译单元的紧下方就是第二个翻译单元,包含select
中的消息。翻译它。
Here they are together, after translation:
在翻译之后,它们会放在一起:
Translate a nested expression
翻译嵌套的表达式
A nested expression is not different from the previous ones. As in the previous example, we have two translation units.
嵌套的表达式和前一节没有什么不同。就像上一个例子中那样,我们有两个翻译单元。
The first one contains the text outside the nested expression:
第一个包含嵌套表达式外部的文本:
The second unit contains the complete nested expression:
第二个包含完整的嵌套表达式:
And both together:
放在一起时:
The entire template translation is complete. It's time to incorporate that translation into the application.
整个模板的翻译就完成了。现在就该把翻译结果放回到应用程序中了。
The app before translation
翻译前的应用程序
When the previous steps finish, the sample app and its translation file are as follows:
如下所示,是完成前面的步骤后的例子应用和它的翻译文件:
{@a merge}
Merge the completed translation file into the app
合并已经翻译的文件
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 that Angular understands, such as .xtb
.
要合并已经翻译的文件到组件模板,使用翻译过的文件编译应用。
不管文件是.xlf
格式还是其他Angular接受的格式(.xlif
和.xtb
),流程是一样的。
You provide the Angular compiler with three new pieces of information:
你要为Angular编译器提供下列三种新信息:
-
The translation file.
翻译文件
-
The translation file format.
翻译文件的格式
-
The Locale ID (
es
oren-US
for instance).目标语言环境ID (例如
es
或en-US
)
How you provide this information depends upon whether you compile with the JIT (Just-in-Time) compiler or the AOT (Ahead-of-Time) compiler.
你如何提供这些信息取决于你使用的是JiT(即时)编译器还是AoT(预先)编译器。
-
With JIT, you provide the information at bootstrap time.
使用JiT时,在引导时提供
-
With AOT, you pass the information as
ngc
options.使用AoT时,在
ngc
命令的选项里提供
{@a jit}
Merge with the JIT compiler
用JiT编译器合并
The JIT compiler compiles the application in the browser as the application loads. Translation with the JIT compiler is a dynamic process of:
JiT(即时)编译器在应用程序加载时,在浏览器中编译应用。 在使用JiT编译器的环境中翻译是一个动态的流程,包括:
-
Determining the language version for the current user。
决定当前用户的语言,
-
Importing the appropriate language translation file as a string constant.
导入合适的语言翻译文件到一个字符串常量,
-
Creating corresponding translation providers to guide the JiT compiler.
新建对应的翻译提供商来指导JiT编译器,
-
Bootstrapping the application with those providers.
使用这些提供商来启动应用。
Open index.html
and revise the launch script as follows:
打开index.html
并这样修改加载脚本:
In this sample, the user's language is hard-coded as a global document.locale
variable
in the index.html
.
在本例中,用户的语言在index.html
中被硬编码到一个全局的document.locale
变量中。
{@a text-plugin}
SystemJS text plugin
SystemJS文本插件
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
return the contents as a string.
You'll need it to import the language translation file.
注意SystemJS将text
映射为systemjs-text-plug.js
。
在这个文本插件的帮助下,SystemJS可以读取任何原始文件并将其内容作为字符串返回。
你需要使用它来导入语言翻译文件。
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:
SystemJS没有自带原始文本插件,但是我们很容易添加它。
在src/
目录新建下面的systemjs-text-plugin.js
文件:
{@a create-translation-providers}
Create translation providers
新建翻译提供商
Three providers tell the JIT compiler how to translate the template texts for a particular language while compiling the application:
三种提供商帮助JiT编译在编译应用时,将模板文本翻译到某种语言:
-
TRANSLATIONS
is a string containing the content of the translation file.TRANSLATIONS
是含有翻译文件内容的字符串。 -
TRANSLATIONS_FORMAT
is the format of the file:xlf
,xlf2
, orxtb
.TRANSLATIONS_FORMAT
是文件的格式:xlf
、xlif
或xtb
。 -
LOCALE_ID
is the locale of the target language.LOCALE_ID
是目标语言的语言环境。
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:
在下面的src/app/i18n-providers.ts
文件的getTranslationProviders()
函数中,根据用户的语言环境和对应的翻译文件构建这些提供商:
-
It gets the locale from the global
document.locale
variable that was set inindex.html
.它从在
index.html
中设置的全局document.locale
变量中获取语言环境。 -
If there is no locale or the language is U.S. English (
en-US
), there is no need to translate. The function returns an emptynoProviders
array as aPromise
. It must return aPromise
because this function could read a translation file asynchronously from the server.如果没有语言环境或者语言是美国英语(
en-US
),则就无需翻译。该函数以Promise
的形式返回一个空的noProviders
数组。它必须要返回Promise
,因为这个函数可能异步从服务器读取翻译文件。 -
It creates a transaction filename from the locale according to the name and location convention described earlier.
根据上面描述的名字和本土化的约定,它根据语言环境创建一个合约文件名。
-
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.getTranslationsWithSystemJs()
方法读取翻译并以字符串的形式返回其内容。 注意它在文件名上附加!text
,告诉SystemJS使用文本插件。 -
The callback composes a providers array with the three translation providers.
回调函数使用这三种翻译提供商创建一个提供商数组。
- Finally,
getTranslationProviders()
returns the entire effort as a promise.
最后,getTranslationProviders()
返回以承诺的形式返回全部流程的结果。
{@a bootstrap-the-app}
Bootstrap with translation providers
使用翻译提供商引导应用
The Angular bootstrapModule()
method has a second options parameter
that can influence the behavior of the compiler.
Angular的bootstrapModule()
方法接受可选的第二参数,它可以影响编译器的行为。
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:
从getTranslationProviders()
返回的翻译提供商创建_options_对象,并将其传给bootstrapModule
。
打开src/main.ts
并这样修改引导代码:
Notice that it waits for the getTranslationProviders()
promise to resolve before
bootstrapping the app.
注意,它等待getTranslationProviders()
承诺的解析完成后,才引导应用。
The app is now internationalized for English and Spanish and there is a clear path for adding more languages.
现在,应用已经被国际化为英语版和西班牙语版,而且我们有了清晰的添加更多语言的方法。
{@a aot}
Internationalization with the AOT compiler
使用AoT编译器时的国际化
The JIT compiler translates the application into the target language while compiling dynamically in the browser. That's flexible but may not be fast enough for your users.
JiT编译器在浏览器中动态编译应用时,将其翻译到目标语言。 这样很灵活,但是对用户来讲,可能速度太慢。
The AOT (Ahead-of-Time) compiler is part of a build process that
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, in this case index.html
,
you determine which language the user needs
and serve the appropriate application package.
AoT(预先)编译器是一种构建流程,出产尺寸小、速度快和可执行的应用程序包。
在使用Aot编译器的环境中国际化,你为每种语言预先构建一个单独的应用程序包。然后,在宿主网络页面(index.html
)中,你再决定用户需要哪种语言,并选择合适的应用程序包。
This guide doesn't cover how to build multiple application packages and serve them according to the user's language preference. It does explain the few steps necessary to tell the AOT compiler to apply a translations file.
本烹饪书不介绍如何构建多种应用程序包和如何根据用户的语言设置推送它们。 它介绍了一些必要的步骤,来告诉AoT采用翻译文件。
Internationalization with the AOT compiler requires some setup specifically for AOT compilation. Start with the application project as shown just before merging the translation file and refer to the AOT guide to make it AOT-ready.
使用AoT编译器时的国际化,需要一些针对AoT的设置。 以合并翻译文件之前的应用项目开始,并参见AoT烹饪书,把它变成与AoT兼容的项目。
Next, issue an ngc
compile command for each supported language, including English.
The result is a separate version of the application for each language.
接下来,为每种支持的语言(包括英语)运行一次ngc
编译命令。
结果是每种语言都有自己单独的应用版本。
Tell AOT how to translate by adding three options to the ngc
command:
通过添加下面三种选项到ngc
命令来告诉AoT编译器如何翻译:
-
--i18nFile
: the path to the translation file.--i18nFile
: 翻译文件的路径 -
--locale
: the name of the locale.--locale
: 语言环境的名字 -
--i18nFormat
: the format of the localization file.--i18nFormat
: 翻译文件的格式
For this sample, the Spanish language command would be:
本西班牙语例子的命令为:
./node_modules/.bin/ngc --i18nFile=./locale/messages.es.xlf --locale=es --i18nFormat=xlfWindows users may have to quote the command:
Windows用户可能需要双引号这个命令:
"./node_modules/.bin/ngc" --i18nFile=./locale/messages.es.xlf --locale=es --i18nFormat=xlfReport missing translations
汇报缺失的翻译
If you forgot to provide a translation, the build will succeed with a warning that you might easily overlook. You can configure the Angular compiler for different "missing translation" behaviors:
如果你忘了提供翻译,构建工具会给出警告,以便你更容易发现它们。 我们可以把 Angular 编译器配置为发现"缺少翻译"时采取不同的行动:
-
Error
报错
-
Warning (default)
警告(默认值)
-
Ignore
忽略
To change the behavior in JIT, you can use the following configuration:
要在 JIT 编译器中改变这种行为,我们可以使用下列配置:
{ provide: CompilerConfig, useValue: new CompilerConfig({ missingTranslation: MissingTranslationStrategy.Error }) }A good place to use it is the translation providers:
使用它的一个好地方是在 "翻译服务提供商(provider)" 中:
To change the behavior in AOT, add the --missingTranslation
flag to the compilation command:
要在 AOT 编译器中改变这种行为,可以在编译命令行中添加 --missingTranslation
标志:
{@a maintenance}
File maintenance and id changes
文件维护与id
的改变
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 the id
can be a serious problem!
随着应用的成长,我们会修改 i18n
的页面脚本,并且多次重新运行 ng-xi18n
提取工具。
你新增的脚本毫无问题,但是原有脚本的 id
可能会面临一系列问题!
If the id
is generated by the tool, most changes to existing markup
cause the tool to generate a new id
for the affected translation unit.
如果id
是由工具生成的,大部分对现有脚本的改动会导致工具重新生成新的 id
,从而影响到翻译单元。
After an id
changes, the translation files are no longer in sync.
Because of that, you get some warning messages during re-compilation.
The warning messages identify that some translations are missing, but they don't tell you which
old ids
are no longer valid.
在一个id
变化之后,翻译结果文件将不再同步。
因此,我们会在重新编译的时候收到一些警告信息。
这些警告信息标识出了哪些翻译结果被丢了,但却不会告诉我们哪些原有的id
失效了。
If you use a custom id,
the tooling preserves the custom id
as you make changes to the corresponding translation unit. Use custom ids unless you have a very good reason to do otherwise.
如果我们使用自定义 id,当你修改相应的翻译单元时,工具就会保留这些自定义id
。除非有特别好的理由,否则应该总是使用自定义id
。
Whether you use generated or custom ids
, always commit all translation message files to source control,
especially the English source messages.xlf
.
The difference between the old and the new messages.xlf
file
will help you find and update ids
and other changes across your translation files.
无论我们是所有自动生成的id还是自定义id,都总是要把所有的翻译结果文件提交到源码控制系统中,特别是英语的源文件messages.xlf
。
比较新旧messages.xlf
文件之间的不同,可以帮助你在多个翻译结果文件之间发现id
的变化,以及其它更改。