Angular 提供了 i18n
功能让我们开发专案时可以让我们的专案应在不同的国家中被使用,Localization
是为不同语言环境构建应用程序版本的过程,包过提取文本已翻译成不同语言以及为特定语言环境设置数据格式。
使用 Angular i18n 为应用程序进行国际化:
pipes
显示本地化的日期、数字、百分比和货币要使用 Angular i18n 的前提下需要准备好 Angular CLI,因为几乎全部的任务都需要使用 Angular CLI
要使用 Angular CLI 的功能需要先使用 Angular CLI 将 @angular/localize
添加到专案中
ng add @angular/localize
使用这个 CLI Command 後会在 package.json
与 polyfill.ts
中导入 @angular/localize
,要注意如果没有加入这个功能的话,使用 i18n 功能将会失败。
Angular i18n 使用 Unicode
语言环境标示符 (ID) 引用语言环境,他可以用於指定 语言
、国家/地区
,这个 ID 由语言标示符所组成,例如 en
代表英语或 fr
代表法语,後面可以加上一个 破折号 ( - )
和 区域扩展名
,例如 US 表示美国 CA 表示加拿大,所以可以变成 en-US
他代表在美国的英语,fr-CA 代表在加拿大的法语以此类推, Angular 会依照这个 ID 来查找正确的对应区域设置数据。
在默认情况下 Angular 是使用 en-US
作为应用程序的初始语言环境,可以在 angular.json
中的 sourceLocale
中更改原始语言环境。
讲了这麽多,接着直接来看看如何在 Angular 终使用 i18n 吧,要翻译应用程序的 template 需要通过使用 Angular i18n attribute 和其他 attribute 来为翻译器准备文本,通常会使用以下的步骤:
使用 i18n
这个 attribute 标记要翻译的 template 的内容,将它放在需要翻译的元素标签上并带有要翻译的固定文本,举个例子
<h1>Hello i18n!</h1>
如果要将上面这个 <h1>
元素进行翻译的话,将 i18n attribute 添加到上面
<h1 i18n>Hello i18n!</h1>
当翻译人员与程序开发人员是不同人时,程序开发人员需要将这个要翻译的内容做一些解释好让翻译人员知道这个是什麽,才能进行准确的翻译,所以需要在 i18n attribute 中添加额外的说明用於描述这个翻译是什麽
<h1 i18n="An introduction header for this sample">Hello i18n!</h1>
除了加上这个 i18n attribute 的意图之外,还需要添加这个对於这个元素的描述,这样可大幅提高翻译的精准度,使用 |
将意图与描述分开 <maining> | <description>
。
<h1 i18n="site header|An introduction header for this sample">Hello i18n!</h1>
如果需要翻译一个还没有显示出来的元素时,请将文本加入到 <ng-container>
中
<ng-container i18n>I don't output any element</ng-container>
如果要翻译 HTML 的 attribute,例如 <img>
中的 title attribute 应该要将 i18n 使用 -
符号连接要翻译的 attribute
<img [src]="logo" title="Angular logo">
若要翻译 HTML 元素的 attribute 请添加 i18n-attribute
其中的 attribute 是需要翻译的 attribute 名称
<img [src]="logo" i18n-title title="Angular logo" />
也可以使用 i18n-attribute="<meaning> | <description>@@<id>"
语法分配含义、描述以及自定义的 ID
不同语言有不同的复数规则和语法结构,这让翻译的难度大大增加,所以为了简化翻译请使用带有正规表达式
的 Unicode
ICU 子句。
使用 plural
来标记如果逐字翻译可能没有意义表达,例如如果想用英文显示 updated x minutes ago
可能希望显示 jest now
、one minute ago
或 x minutes ago
,可以使用下面的例子
<span i18n>Updated {minutes, plural, =0 {just now} =1 {one minute ago} other {{{minutes}} minutes ago}}</span>
minutes
绑定了 component 的 property,她决定了显示的分钟数plural
翻译类型=0 { just now }
=1 { one minute ago }
如果要根据变量的值来决定替代的文本时则需要翻译所又替代文本,select
子句类似 plural
子句,根据定义的字串值标记替代文本的选择,举例来说 template 绑定了 component 的 property,透过 property 的值决定要翻译 male
、female
或 other
<span i18n>The author is {gender, select, male {male} female {female} other {other}}</span>
也可以将两种不的子句嵌套再一起
<span i18n>Updated: {minutes, plural,
=0 {just now}
=1 {one minute ago}
other {{{minutes}} minutes ago by {gender, select, male {male} female {female} other {other}}}}
</span>
上面介绍了一堆 i18n 的概念与用法後,接这直接来建立一个例子吧
ng generate component form
在 form.component.ts 中新增 Form Model
import { Component } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';
@Component({
selector: 'app-form',
templateUrl: './form.component.html',
styleUrls: ['./form.component.css']
})
export class FormComponent {
form = this.fb.group({
username: ['', Validators.required],
password: ['', Validators.required],
})
constructor(private fb: FormBuilder) { }
}
在 form.component.html 中绑定 FormControl 并在要翻译的元素上加上 i18n
<form [formGroup]="form">
<div class="content">
<label for="username" i18n>Username</label>
<input type="text" id="name" class="form-control" formControlName="username" />
<label for="password" i18n>Password</label>
<input type="text" id="name" class="form-control" formControlName="password" />
</div>
<div class="optionBtn">
<button type="button" class="btn btn-success" i18n>Login</button>
</div>
</form>
准备好要翻译的 template 後请使用 Angular CLI extract-i18n
command 将 tempalte 中标记的文本提取到 source language file
ng extract-i18n
extract-i18n 使用 XML
本地化交换文件格式,在项目的根目录中创建一个名为 messages.xlf
的 source language file,可以使用一些 option 选项
可以使用 --format
将 soruce language file 的格式更改为以下几种格式
ng extract-i18n --format=xlf
ng extract-i18n --format=xlf2
ng extract-i18n --format=xmb
ng extract-i18n --format=json
ng extract-i18n --format=arb
产生了 source language file 後接着来将他们翻译为各国的语言,由於 Angular 预设语言就是英文,所以不需要对英文进行翻译
将 source language file 复制一份後更改他的档名,更改为 messages.zh.hant.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="5248717555542428023" datatype="html">
<source>Username</source>
<target>使用者名称</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/form/form.component.html</context>
<context context-type="linenumber">3</context>
</context-group>
</trans-unit>
<trans-unit id="1431416938026210429" datatype="html">
<source>Password</source>
<target>密码</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/form/form.component.html</context>
<context context-type="linenumber">5</context>
</context-group>
</trans-unit>
<trans-unit id="2454050363478003966" datatype="html">
<source>Login</source>
<target>登陆</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/form/form.component.html</context>
<context context-type="linenumber">9</context>
</context-group>
</trans-unit>
</body>
</file>
</xliff>
在要翻译的名称 <source>
下方加上 <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="5248717555542428023" datatype="html">
<source>Username</source>
<target>ユーザー名</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/form/form.component.html</context>
<context context-type="linenumber">3</context>
</context-group>
</trans-unit>
<trans-unit id="1431416938026210429" datatype="html">
<source>Password</source>
<target>パスワード</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/form/form.component.html</context>
<context context-type="linenumber">5</context>
</context-group>
</trans-unit>
<trans-unit id="2454050363478003966" datatype="html">
<source>Login</source>
<target>ログイン</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/form/form.component.html</context>
<context context-type="linenumber">9</context>
</context-group>
</trans-unit>
</body>
</file>
</xliff>
将需要翻译的文本设定好後,接着更改 angular.json 的内容让 Angular 知道该使用哪一个语言
{
...
"projects": {
"project-name": {
"i18n": {
"locales": {
"tw": {
"translation": "messages.zh.hant.xlf",
"baseHref": "/tw/"
},
"jp": {
"translation": "messages.jp.xlf",
"baseHref": "/jp/"
}
}
}
}
}
}
修改 build 的设定
"architect": {
"build": {
...
"options": {
"localize": true,
"aot": true,
...
},
"configurations": {
"tw": {
"localize": ["tw"]
},
"jp": {
"localize": ["jp"]
},
}
}
}
修改 serve 的设定
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"configurations": {
"production": {
"browserTarget": "Angular-blog:build:production"
},
"tw": {
"browserTarget": "Angular-blog:build:tw"
},
"jp": {
"browserTarget": "Angular-blog:build:jp"
},
"development": {
"browserTarget": "Angular-blog:build:development"
}
}
}
使用 Angular CLI 将专案跑起来,来看看是否完成翻译
ng serve --configuration=tw --open
ng serve --configuration=jp --open
当完成翻译後可以在表单上面新增一个 select 用於选择要显示什麽语言,可以做到这种效果
本章中介绍了如何使用 Angular 的 i18n 功能做出国际化的应用程序,先在 template 中将要翻译的内容加上 i18n attribute,之後使用 Angular CLI Command ng extract-i18n
产生 source langange file,获得 source langange file 之後就可以对不同的语言进行翻译,在 <soruce>
的下方加上 <target>
并在其中填入翻译的内容,最後在 angular.json 中进行 i18n 的设定就完成了,是不是很简单呢。
下一篇会介绍 Angular 中一个重要的观念那就是 Module
,在前面很多篇中都会看到要引入某某 module 到 app.module.ts 中,这个 Module 可以看成是将各个功能进行模组化分割,这样比较方便管理与测试,详细的内容就留到明天讲解吧,明天见
<<: [面试][後端]请简述 Node.js 的 Event Loop
Merge Sort采用Divide and Conquer的方式,其实他的概念本身就是递回(rec...
Github page 的特色 劈头就上官方文件和 Landing page。 Github pag...
中秋过,老一辈常讲甚麽中秋变盘,认不认同看个人。但中秋之後的几天大涨大跌的,是不是好刺激? 想作多或...
这次的铁人赛进入了最後一天,感谢夥伴们彼此的扶持,也感谢没有放弃的自己。这次的DRF系列文章希望能帮...
前情提要 艾草:「你过来帮我摆一下魔法阵!」 「哇喔,看起来好厉害唷!这里有三个空位是要摆什麽吗?」...