介绍
国际化是在您的应用程序中支持多种语言的过程。
这可以通过第三方库在 Angular 应用程序中完成,例如ngx-translate
,或者您可以使用内置的 i18n 功能。
注: “i18n”是一个数字符号,其中“18”表示“国际化”一词中第一个字母(“I”)和最后一个字母(“N”)之间的字母数。在开发应用程序时,您可能还会遇到“a11y”,它是可访问性的数字名词。
在本教程中,您将学习在 Angular 应用程序中使用内置的 i18n 功能。
先决条件
要完成本教程,您需要:
- Node.js 安装在本地,您可以按照如何安装 Node.js 和创建本地开发环境来完成。
- 熟悉设置 Angular 项目和使用 Angular 组件可能会有所帮助。
本教程已通过 Node v14.13.1、npm
v6.14.8、angular
v10.1.6 和@angular/localize
v10.1.6 验证。
步骤 1 — 设置项目
您可以使用它@angular/cli
来创建一个新的 Angular 项目。
在终端窗口中,使用以下命令:
- npx @angular/cli new angular-internationalization-example --style=css --routing=false --skip-tests
这将配置一个新的 Angular 项目,其样式设置为“CSS”(与“Sass”、Less 或“Stylus”相反),没有路由,并跳过测试。
导航到新创建的项目目录:
- cd angular-internationalization-example
要为翻译项目创建基础,请app.component.html
在代码编辑器中打开并将代码替换为以下几行:
<section>
<article>
<h1>Under Construction!</h1>
<p>This page is under construction.</p>
</article>
</section>
此代码将显示"Under Construction!"
和"This page is under construction"
消息。
接下来,打开app.component.css
并用以下几行替换代码:
section {
background: #8e2de2; /* fallback for old browsers */
background: -webkit-linear-gradient(to right, #4a00e0, #8e2de2); /* Chrome 10-25, Safari 5.1-6 */
background: linear-gradient(to right, #4a00e0, #8e2de2);
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
article {
border: 1px solid white;
box-shadow: 1px 1px 100px 10px rgba(0, 0, 0, 0.8);
color: white;
padding: 40px;
text-align: center;
}
此代码使用 flexbox、视口高度值、线性渐变背景和框阴影将"Under Construction!"
消息放在屏幕上居中。
然后,打开styles.css
并用以下几行替换代码:
html,
body {
padding: 0;
margin: 0;
}
这将删除浏览器用户样式默认情况下倾向于放置的任何填充和边距。通过使用这些样式,您可以在具有不同默认值的所有浏览器之间创建一致的基线。
在终端窗口中,启动您的应用程序:
- npm start
localhost:4200
在您的网络浏览器中访问:
一旦您能够验证应用程序是否按预期运行,您就可以开始提取要翻译的消息。
第 2 步 – 使用xi18n
提取messages.xlf
让我们首先标记您要在应用程序中翻译的文本。在本教程中,您将使用 Google Translate 提供的翻译将应用程序翻译成法语 ( fr
) 和德语 ( de
)。
将i18n
指令添加到您要翻译的所有文本中:
<section>
<article>
<h1 i18n>Under Construction!</h1>
<p i18n>This page is under construction.</p>
</article>
</section>
然后,你将不得不作出的NPM脚本中package.json
使用的角度CLI从提取标记的项目app.component.html
到messages.xlf
文件:
{
// ...
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"i18n:extract": "ng xi18n"
},
// ...
}
添加后,在终端窗口中运行新脚本:
- npm run i18n:extract
然后,打开messages.xlf
,你会看到类似的东西:
<?xml version="1.0" encoding="UTF-8" ?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en-US" datatype="plaintext" original="ng2.template">
<body>
<trans-unit id="48a16ab522feaff81571155668deb1a4304291f4" datatype="html">
<source>Under Construction!</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/app.component.html</context>
<context context-type="linenumber">3</context>
</context-group>
</trans-unit>
<trans-unit id="84c778d7a95cb5dc26c9cc9feb5b7abb4d295792" datatype="html">
<source>This page is under construction.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/app.component.html</context>
<context context-type="linenumber">4</context>
</context-group>
</trans-unit>
</body>
</file>
</xliff>
对于每个需要翻译的项目(即有i18n
指令),trans-unit
将创建一个。
您还可以使用此结构来提供有关翻译的更多信息。如果您要让第三方翻译每条消息并希望提供更多信息,这将非常有用。
在 里面app.component.html
,i18n
用描述更新项目:
<article>
<h1 i18n="Title for the under construction card">Under Construction!</h1>
<p i18n="A description for the under construction card.">This page is under construction.</p>
</article>
您可以使用管道字符 ( |
)进一步向其添加上下文。这给出了一个项目的含义,每个具有相同含义的项目将具有相同的翻译:
<article>
<h1 i18n="Card Header|Title for the under construction card">Under Construction!</h1>
<p i18n="Card Descritpion|A description for the under construction card.">This page is under construction.</p>
</article>
您还可以通过使用两个 at 符号字符 ( ) 来为每个i18n
项目指定一个id,以在@@
生成翻译时强制持久化:
<article>
<h1 i18n="Card Header|Title for the under construction card@@constructionHeader">Under Construction!</h1>
<p i18n="Card Descritpion|A description for the under construction card.@@constructionDescription">This page is under construction.</p>
</article>
让我们再次构建翻译:
- npm run int:extract
这些项目现在将使用id、含义和描述进行更新:
<?xml version="1.0" encoding="UTF-8" ?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en-US" datatype="plaintext" original="ng2.template">
<body>
<trans-unit id="constructionHeader" datatype="html">
<source>Under Construction!</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/app.component.html</context>
<context context-type="linenumber">3</context>
</context-group>
<note priority="1" from="description">Title for the under construction card</note>
<note priority="1" from="meaning">Card Header</note>
</trans-unit>
<trans-unit id="constructionDescription" datatype="html">
<source>This page is under construction.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/app.component.html</context>
<context context-type="linenumber">4</context>
</context-group>
<note priority="1" from="description">A description for the under construction card.</note>
<note priority="1" from="meaning">Card Descritpion</note>
</trans-unit>
</body>
</file>
</xliff>
一旦您拥有一个messages.xlf
包含多个trans-unit
s、描述、含义和 id 的文件,您就可以开始创建法语和德语翻译。
第 3 步 — 创建法语和德语翻译
默认情况下,Angular 将所有内容都视为“美式英语” ( en-US
) 语言环境。您必须添加其他语言环境并更新配置以支持它们。
这些语言环境由语言环境标识符 (ID) 引用。例如,“美式英语”使用 ID en-US
。前两个字符 – en
– 为“英语”分配区域设置标识符。最后两个字符 – US
– 为“美国”分配区域设置扩展名。这些标识符源自 BCP47 建立的规则。
为避免项目目录混乱,将翻译文件存储在新目录中可能会有所帮助。您可以为脚本提供一个output-path
选项以i18n:extract
将它们放置在locales
目录中:
{
// ...
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"i18n:extract": "ng xi18n --output-path src/locale"
},
// ...
}
删除现有messages.xlf
文件:
- rm messages.xlf
并重新运行i18n:extract
命令;
- npm run i18n:extract
一旦您确认脚本更改按预期工作并且目录中有一个messages.xlf
文件locales
,您就可以开始添加target
s 进行翻译。
法语
首先,复制messages.xlf
到messages.fr.xlf
:
- cp src/locale/messages.xlf src/locale/messages.fr.xlf
然后,target
为每个项目添加一个:
<?xml version="1.0" encoding="UTF-8" ?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en-US" datatype="plaintext" original="ng2.template">
<body>
<trans-unit id="constructionHeader" datatype="html">
<source>Under Construction!</source>
<target>En construction</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/app.component.html</context>
<context context-type="linenumber">3</context>
</context-group>
<note priority="1" from="description">Title for the under construction card</note>
<note priority="1" from="meaning">Card Header</note>
</trans-unit>
<trans-unit id="constructionDescription" datatype="html">
<source>This page is under construction.</source>
<target>Cette page est en construction</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/app.component.html</context>
<context context-type="linenumber">4</context>
</context-group>
<note priority="1" from="description">A description for the under construction card.</note>
<note priority="1" from="meaning">Card Descritpion</note>
</trans-unit>
</body>
</file>
</xliff>
每个trans-unit
现在都有一条source
英文target
消息和一条法文消息。
德语
接下来,复制messages.xlf
到messages.de.xlf
:
- cp src/locale/messages.xlf src/locale/messages.de.xlf
然后,target
为每个项目添加一个:
<?xml version="1.0" encoding="UTF-8" ?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en-US" datatype="plaintext" original="ng2.template">
<body>
<trans-unit id="constructionHeader" datatype="html">
<source>Under Construction!</source>
<target>Im Bau</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/app.component.html</context>
<context context-type="linenumber">3</context>
</context-group>
<note priority="1" from="description">Title for the under construction card</note>
<note priority="1" from="meaning">Card Header</note>
</trans-unit>
<trans-unit id="constructionDescription" datatype="html">
<source>This page is under construction.</source>
<target>Diese Seite befindet sich im Aufbau</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/app.component.html</context>
<context context-type="linenumber">4</context>
</context-group>
<note priority="1" from="description">A description for the under construction card.</note>
<note priority="1" from="meaning">Card Descritpion</note>
</trans-unit>
</body>
</file>
</xliff>
每个trans-unit
现在都有一条source
英语target
消息和一条德语消息。
第 4 步 – 创建法语和德语版本
您拥有基于locale
.
您可以使用 Angular CLI 为您想要支持的每个语言环境生成特定的构建。
首先,您需要安装@angular/localize
:
- ./node_modules/@angular/cli/bin/ng add @angular/localize
angular.json
在您的代码编辑器中打开并添加fr
和de
语言环境:
{
"projects": {
"angular-internationalization-example": {
// ...
"i18n": {
"sourceLocale": "en-US",
"locales": {
"fr": {
"translation": "src/locale/messages.fr.xlf",
"baseHref": ""
},
"de": {
"translation": "src/locale/messages.de.xlf",
"baseHref": ""
}
}
},
"architect": {
// ...
}
}},
// ...
}
而对于创建配置设置fr
和de
下build
:
{
"projects": {
"angular-internationalization-example": {
// ...
"architect": {
"build": {
// ...
"configurations": {
"production": {
// ...
},
"fr": {
"localize": ["fr"],
"outputPath": "dist/under-construction-fr/",
"i18nMissingTranslation": "error"
},
"de": {
"localize": ["de"],
"outputPath": "dist/under-construction-de/",
"i18nMissingTranslation": "error"
}
}
},
// ...
}
}},
// ...
}
注:以前,本教程中使用单独的值"i18nFile"
,"i18nFormat"
和` "i18nLocale"
。这些已被弃用,localize
是首选方法。
您还可以更新下的配置设置serve
:
{
"projects": {
"angular-internationalization-example": {
// ...
"architect": {
"serve": {
// ...
"configurations": {
"production": {
"browserTarget": "angular-internationalization-example:build:production"
},
"fr": {
"browserTarget": "angular-internationalization-example:build:fr"
},
"de": {
"browserTarget": "angular-internationalization-example:build:de"
}
}
},
// ...
}
}},
// ...
}
您现在可以制作更多脚本,package.json
其中包括构建和服务新语言环境的能力:
{
"scripts": {
"ng": "ng",
"start": "ng serve",
"start:fr": "ng serve --configuration=fr",
"start:de": "ng serve --configuration=de",
"build": "ng build",
"build:fr": "ng build --configuration=fr",
"build:de": "ng build --configuration=de",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"i18n:extract": "ng xi18n --output-path src/locale"
}
}
您可以通过在终端中运行以下命令来启动我们所有的项目:
- npm start
在另一个终端窗口中,启动法语版本:
- npm run start:fr -- --port=4201
在另一个终端窗口中,启动德语版本:
- npm run start:de -- --port=4202
这将在默认端口上运行英语应用程序,在端口 4201 上运行法语,在端口 4202 上运行德语:
您已经构建了应用程序的翻译版本。
结论
在本教程中,您使用了 Angular 可用的内置 i18n 工具来生成法语和德语的翻译版本。
要了解有关使用内置 i18n 工具的更多信息,请参阅官方文档。
如果您想了解有关 Angular 的更多信息,请查看我们的 Angular 主题页面,了解练习和编程项目。