codecamp

Angular 准备翻译模板

准备翻译组件

要准备翻译项目,请完成以下操作。

  • 使用 ​i18n​ 属性标记组件模板中的文本
  • 使用 ​i18n-​ 属性在组件模板中标记属性文本字符串
  • 使用带 ​$localize​ 标记的消息字符串标记组件代码中的文本字符串

在组件模板中标记文本

在组件模板中,i18n 元数据就是 ​i18n ​属性的值。

<element i18n="{i18n_metadata}">{string_to_translate}</element>

使用 ​i18n ​属性在组件模板中标记静态文本消息以进行翻译。将它放在每个包含要翻译的固定文本的元素标签上。

i18n ​属性是供 Angular 工具和编译器识别的自定义属性。

i18n 示例

下面的 ​<h1>​ 标签显示了一个简单的英语问候语:“Hello i18n!”。

<h1>Hello i18n!</h1>

要将问候语标记为待翻译,请将 ​i18n ​属性添加到 ​<h1>​ 标记。

<h1 i18n>Hello i18n!</h1>

翻译没有 HTML 元素的内联文本

使用 ​<ng-container>​ 元素来为特定文本关联翻译行为,而不会改变文本的显示方式。

每个 HTML 元素都会创建一个新的 DOM 元素。要想避免创建新的 DOM 元素,请将文本包裹在 ​<ng-container>​ 元素中。以下示例显示了如何将 ​<ng-container>​ 元素转换为不显示的 HTML 注释。

<ng-container i18n>I don't output any element</ng-container>

标记翻译的元素属性

在组件模板中,i18n 的元数据是 ​i18n-{attribute_name}​ 属性的值。

<element i18n-{attribute_name}="{i18n_metadata}" {attribute_name}="{attribute_value}" />

HTML 元素的属性包括那些要和组件模板中显示的其它文本一起翻译的文本。

将 ​i18n-{attribute_name}​ 与任何元素的任何属性一起使用,并将 ​{attribute_name}​ 替换为该属性的名称。使用以下语法分配含义、描述和自定义 ID。

i18n-{attribute_name}="{meaning}|{description}@@{id}"

i18n-title 示例

要翻译图像的标题,请查看此示例。以下示例显示具有 ​title ​属性的图像。

<img [src]="logo" title="Angular logo" alt="Angular logo">

要标记出待翻译的标题属性,请完成以下操作。

  1. 添加 ​i18n-title​ 属性
  2. 下面的示例展示了如何通过添加 ​i18n-title​ 来标记出 ​img ​标签上的 ​title ​属性。

    <img [src]="logo" i18n-title title="Angular logo" alt="Angular logo"/>

在组件代码中标记文本

在组件代码中,翻译源文本和元数据被反引号 (​`​) 字符包围。

使用 ​$localize​ 标记的消息字符串在代码中标记出要翻译的字符串。

$localize `string_to_translate`;

i18n 元数据包裹在冒号 (​:​) 字符中,并放在翻译源文本之前。

$localize `:{i18n_metadata}:string_to_translate`

包含插值文本

在 ​$localize​ 标记的消息字符串中包含插值文本

$localize `string_to_translate ${variable_name}`;

命名插值占位符

$localize `string_to_translate ${variable_name}:placeholder_name:`;

用于翻译的 i18n 元数据

{meaning}|{description}@@{custom_id}

以下参数提供上下文和附加信息,以避免翻译人员弄混。

元数据参数

详情

自定义 ID

提供自定义标识符

说明

提供额外的信息或背景

含义(Meaning)

提供文本在特定上下文中的含义或意图

添加有用的描述和含义

要准确翻译文本消息,就要为翻译人员提供额外信息或上下文。

为 ​i18n ​属性的值或 ​$localize​ 标记的消息字符串添加文本消息的描述

以下示例显示了 ​i18n ​属性的值。

<h1 i18n="An introduction header for this sample">Hello i18n!</h1>

以下示例显示了带有描述的 ​$localize​ 标记消息字符串的值。

$localize `:An introduction header for this sample:Hello i18n!`;

翻译者可能还需要了解该特定应用上下文中此文本消息的含义或意图,以便以与具有相同含义的其他文本相同的方式对其进行翻译。把含义放在 ​i18n ​属性值的最前面,并用 ​|​ 字符将其与描述分开:​{meaning}|{description}​。

h1 示例

比如,你可能希望将 ​<h1>​ 标记指定为需要以相同方式翻译的站点标题,无论是把它用作标题还是在其他文本部分中引用。

以下示例显示如何指定 ​<h1>​ 标记无论在标题还是在别处引用都要以相同方式翻译。

<h1 i18n="site header|An introduction header for this sample">Hello i18n!</h1>

其结果是:任何标有 ​site header​ 的文本都会以相同方式翻译,因为其含义完全相同。

以下代码示例显示了带有含义和描述的 ​$localize​ 标记消息字符串的值。

$localize `:site header|An introduction header for this sample:Hello i18n!`;
Angular 提取工具会为模板中的每个 ​i18n ​属性生成一个翻译单元条目。Angular 提取工具会根据含义和描述为每个翻译单元分配一个唯一的 ID。
具有不同含义的相同文本元素以不同的 ID 提取。比如,如果单词“right”在两个不同的位置使用以下两个定义,则该单词将被以不同地方式翻译并作为不同的翻译条目合并回应用程序。
  • correct ​如 "you are right"
  • direction ​如 "turn right"
如果相同的文本元素满足以下条件,则只会提取一次文本元素并使用相同的 ID。
  • 相同的含义或定义
  • 不同的描述
只要出现相同的文本元素,该翻译条目就会合并回应用程序。

ICU 表达式

ICU 表达式可帮助你在组件模板中标记出某些条件下的替代文本。ICU 表达式包括一个组件属性、一个 ICU 子句以及由左花括号 ( ​{​ ) 和右花括号 ( ​}​ ) 字符包围的 case 语句。

{ component_property, icu_clause, case_statements }

组件属性定义了变量,而 ICU 子句定义了条件文本的类型。

ICU 子句

详情

plural

标记复数的使用

select

根据你定义的字符串值标记出替代文本的一些选择

为了简化翻译,请使用带有正则表达式的 Unicode 子句(ICU 子句)的国际化组件。

ICU 子句遵循 CLDR 复数规则 中指定的 ICU 消息格式

标记复数

不同的语言有不同的复数规则,这增加了翻译的难度。因为其他语言环境表达基数的方式不同,你可能需要设置与英语不一致的复数类别。使用 ​plural ​从句来标记当逐字翻译时可能没有意义的表达式。

{ component_property, plural, pluralization_categories }

在复数类别之后,输入由左大括号 (​{​) 和右大括号 (​}​) 字符包围的默认文本(英文)。

pluralization_category { }

以下复数类别适用于英语,可能会根据语言环境而变化。

复数类

详情

范例

zero

数量为零

=0 { }
zero { }
one

数量为 1

=1 { }
one { }
two

数量为 2

=2 { }
two { }
few

数量为 2 或更多

few { }
many

数量很大

many { }
other

数量的默认值

other { }

如果不能匹配任何复数类别,Angular 就会使用 ​other ​来匹配缺失类别的标准后备值。

other { default_quantity }

有关复数类别的更多信息,请参阅 CLDR - Unicode Common Locale Data Repository 中的选择复数类别名称

许多语言环境不支持某些复数类别。默认语言环境 (​en-US​) 使用一个非常简单的 ​plural()​ 函数,该函数不支持 ​few ​复数类别。另一个具有简单 ​plural()​ 函数的语言环境是 ​es​。以下代码示例显示了 en-US 多重plural()函数。

function plural(n: number): number {
  let i = Math.floor(Math.abs(n)), v = n.toString().replace(/^[^.]*\.?/, '').length;
  if (i === 1 && v === 0) return 1;
  return 5;
}

plural()​ 函数只返回 1 ( ​one ​) 或 5 ( ​other ​)。而 ​few ​类别永远不会匹配到。

minutes 示例

如果你想用英文显示以下短语,其中 ​x​ 是一个数字。

updated x minutes ago

如果你还想根据 ​​的基数显示以下短语。

updated just now
updated one minute ago

使用 HTML 标记和插值。下面的代码示例展示了如何在 ​<span>​ 元素中使用 ​plural ​子句来表达前三种情况。

<span i18n>Updated {minutes, plural, =0 {just now} =1 {one minute ago} other {{{minutes}} minutes ago}}</span>

查看前面代码示例中的以下详细信息。

参数

详情

minutes

第一个参数指定这个组件属性是 minutes 并确定其分钟数。

plural

第二个参数指定 ICU 子句是 plural

=0 {just now}

对于零分钟,复数类别是 =0。其值是 just now

=1 {one minute}

对于一分钟,复数类别是 =1。该值为 one minute

other {{{minutes}} minutes ago}

对于任何不匹配的基数,默认的复数类别是 other。该值为 {{minutes}} minutes ago

{{minutes}}​ 是一个插值

标记替代和嵌套表达式

select ​子句根据你定义的字符串值标记替代文本的选择。

{ component_property, select, selection_categories }

翻译所有替代项以根据变量的值显示替代文本。

在选择类别后,输入由左大括号 ( ​{​ ) 和右大括号 ( ​}​ ) 字符包围的文本(英文)。

selection_category { text }

不同的语言环境具有不同的语法结构,这增加了翻译的难度。使用 HTML 标记。如果无法匹配任何选择类别,Angular 就会使用 ​other ​来匹配缺失类别的标准后备值。

other { default_value }

gender 例子

如果你想用英文显示下面的短语。

The author is other

如果你还想根据组件的 ​gender ​属性显示以下短语。

The author is female
The author is male

下面的代码示例展示了如何绑定组件的 ​gender ​属性,并使用 ​select ​子句在 ​<span>​ 元素中表达前三种情况。

gender ​属性将输出绑定到以下每个字符串值。

英语值

女性

female

男性

male

其它

other

select ​子句会将值映射成适当的翻译。以下代码示例显示了与 select 子句一起使用的 ​gender ​属性。

<span i18n>The author is {gender, select, male {male} female {female} other {other}}</span>

gender 和 minutes 示例

将不同的子句组合在一起,比如 ​plural ​和 ​select ​子句。以下代码示例显示了基于 ​gender ​和 ​minutes ​示例的嵌套子句。

<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>


Angular 根据语言环境格式化数据
Angular 处理翻译文件
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

Angular 开发指南

Angular 特性预览

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }