如何使用ICU MessageFormat翻译消息
编辑本页如何使用ICU MessageFormat翻译消息
应用程序中的消息(即字符串)几乎从来都不是完全静态的。它们包含变量或其他复杂的逻辑,如多元化。要处理这个问题,Translator组件支持ICU MessageFormat语法。
提示
您可以在本文中测试ICU MessageFormatter的示例在线编辑器.
使用ICU消息格式
为了使用ICU消息格式,消息域必须加上后缀+ intl-icu
:
正常文件名 | 消息格式filename |
---|---|
messages.en.yaml |
消息+ intl-icu.en.yaml |
messages.fr_FR.xlf |
消息+ intl-icu.fr_FR.xlf |
admin.en.yaml |
管理+ intl-icu.en.yaml |
方法将处理此文件中的所有消息messageformat在翻译。
消息占位符
MessageFormat的基本用法允许您使用占位符(称为参数in ICU MessageFormat)在您的消息中:
- YAML
- XML
- PHP
1 2
# + intl-icu.en.yaml翻译/消息say_hello:“你好{名称}!”
谨慎
在以前的翻译格式中,占位符通常被封装%
(如。%的名字%
).这%
字符对于ICU MessageFormat语法不再有效,因此如果要从以前的格式升级,则必须重命名参数。
大括号内的所有内容({…}
)由格式化程序处理,并被其占位符替换:
1 2 3 4 5
//打印"Hello Fabien!"回声$翻译->反式(“say_hello”, (“名字”= >“法”]);//打印“Hello Symfonob娱乐下载y!”回声$翻译->反式(“say_hello”, (“名字”= >Sob娱乐下载ymfony的]);
根据条件选择不同的消息
大括号语法允许“修改”变量的输出。其中一个函数是选择
函数。它像PHP一样switch语句并允许您根据变量的值使用不同的字符串。它的一个典型用法是gender:
- YAML
- XML
- PHP
1 2 3 4 5 6 7 8 9 10
# + intl-icu.en.yaml翻译/消息# 'other'键是必需的,如果没有其他匹配的大小写则被选中invitation_title:>- {organizer_gender, select, female {{organizer_name}邀请你参加她的派对!} male {{organizer_name}邀请你参加他的派对!}多个{{organizer_name}have invited you to their party!} other {{organizer_name} has invited you to their party!} }
这看起来可能很复杂。所有函数的基本语法是{variable_name, function_name, function_statement}
(如你稍后所见,function_statement
对于某些函数是可选的)。在本例中,函数名为选择
它的语句包含这个select的“case”。这个函数应用于organizer_gender
变量:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
//打印“Ryan邀请你参加他的派对!”回声$翻译->反式(“invitation_title”, (“organizer_name”= >“瑞恩”,“organizer_gender”= >“男”]);//打印“John和Jane邀请你参加他们的聚会!”回声$翻译->反式(“invitation_title”, (“organizer_name”= >“约翰和简”,“organizer_gender”= >“多”]);//打印“ACME公司邀请您参加他们的聚会!”回声$翻译->反式(“invitation_title”, (“organizer_name”= >“ACME公司”,“organizer_gender”= >“not_applicable”]);
的{…}
语法在“文字”和“代码”模式之间交替。这允许你在选择语句中使用文字文本:
- 第一个
{organizer_gender, select,…}
Block启动“编码”模式,这意味着organizer_gender
作为变量处理。 - 内
{…邀请你参加她的派对!}
Block将您带回到“文字”模式,这意味着文本没有被处理。 - 在这个方块里,
{organizer_name}
再次启动“编码”模式,允许organizer_name
作为变量处理。
提示
虽然只放她的
,他的
或他们的
在switch语句中,最好在消息的最外层结构使用“复杂参数”。字符串以这种方式更易于翻译,并且,正如您可以在多个
在这种情况下,句子的其他部分可能会受到变量的影响。
提示
可以直接在代码中转换ICU MessageFormat消息,而无需在任何文件中定义它们:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
$邀请=“{organizer_gender, select, female {{organizer_name}邀请你参加她的派对!”} male {{organizer_name}邀请你参加他的派对!}多个{{organizer_name}have invited you to their party!} other {{organizer_name} has invited you to their party!} }';//打印“Ryan邀请你参加他的派对!”回声$翻译->反式($邀请, (“organizer_name”= >“瑞恩”,“organizer_gender”= >“男”),//如果你喜欢,所需的"+intl-icu"后缀也被定义为常量:/ /ob娱乐下载 Symfony \组件\ \ MessageCatalogueInterface:翻译:INTL_DOMAIN_SUFFIX“消息+ intl-icu”);
多元化的案例
另一个有趣的函数是复数
.它允许你在你的消息中处理多元化(例如。有3个苹果
vs有一个苹果
).这个函数看起来很像选择
功能:
- YAML
- XML
- PHP
1 2 3 4 5 6 7
# + intl-icu.en.yaml翻译/消息num_of_apples:>-{苹果,复数,=0{没有苹果}一个{有一个苹果…}其他{有#苹果!}}
多元化规则实际上相当复杂,每种语言都不同。例如,俄语中用不同的复数形式表示以1结尾的数字;以2,3或4结尾的数字;以5、6、7、8或9结尾的数字;甚至有些例外!
为了正确地翻译这个,可能的情况复数
每种语言的功能也不同。例如,俄语一个
,几
,许多
而且其他
,而英语只有一个
而且其他
.可能的情况的完整列表可以在Unicode的语言复数规则文档。在前面加上=
,您可以匹配精确的值(如0
在上面的例子中)。
这个字符串的用法与变量和select相同:
1 2 3 4 5
//打印“There is one apple…”回声$翻译->反式(“num_of_apples”, (“苹果”= >1]);//打印“有23个苹果!”回声$翻译->反式(“num_of_apples”, (“苹果”= >23]);
请注意
你也可以设置一个抵消
变量来决定复数形式是否应该偏移(例如在像你和其他人
/你和#其他人
).
提示
当组合选择
而且复数
函数,尽量还有选择
作为最外层的函数:
12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20
{gender_of_host, select, female {{num_guests,复数,offset:1 =0 {{host}不提供聚会。{{host}邀请{guest}参加她的派对。}=2 {{host} invites {guest} and one other person to her party.} other {{host} invites {guest} and # other people to her party.} }} male {{num_guests, plural, offset:1 =0 {{host} does not give a party.} =1 {{host} invites {guest} to his party.} =2 {{host} invites {guest} and one other person to his party.} other {{host} invites {guest} and # other people to his party.} }} other {{num_guests, plural, offset:1 =0 {{host} does not give a party.} =1 {{host} invites {guest} to their party.} =2 {{host} invites {guest} and one other person to their party.} other {{host} invites {guest} and # other people to their party.} }} }
其他占位符函数
除此之外,ICU MessageFormat还提供了两个其他有趣的函数。
序数
类似于复数
,selectordinal
允许您使用数字作为序数比例:
- YAML
- XML
- PHP
12 3 4 5 6 7 8 9 10 11 12
# + intl-icu.en.yaml翻译/消息finish_place:>-你完成了{place, selectordinal,一个{#st}两个{#nd}几个{#rd}其他{#th}}!#当仅将数字格式化为序数时(如上面所示),您也可以#使用序数函数:finish_place:你完成了{的地方,序数}!
1 2 3 4 5 6 7 8
//打印“你完成了第一名!”回声$翻译->反式(“finish_place”, (“地方”= >1]);//打印“You finished 9th!”回声$翻译->反式(“finish_place”, (“地方”= >9]);//打印“你完成了23名!”回声$翻译->反式(“finish_place”, (“地方”= >23]);
可能的情况也显示在Unicode的语言复数规则文档。
日期和时间
日期和时间函数允许您使用IntlDateFormatter:
- YAML
- XML
- PHP
1 2
# + intl-icu.en.yaml翻译/消息published_at:'发布于{publication_date, date} - {publication_date, time, short}'
的“函数声明”时间
而且日期
函数可以是其中之一短
,媒介
,长
或完整的
,对应于由IntlDateFormatter类定义的常量:
1 2
//印刷“出版于2019年1月25日-上午11:30”回声$翻译->反式(“published_at”, (“publication_date”= >新\ DateTime (“2019-01-25 11:30:00”)));
数字
的数量
formatter允许您使用Intl格式化数字NumberFormatter:
- YAML
- XML
- PHP
1 2 3
# + intl-icu.en.yaml翻译/消息进展:'{进度,数量,百分比}的工作已完成'value_of_object:“这件艺术品价值{价值,数字,货币}”
1 2 3 4 5 6 7 8 9
//打印“82%的工作已经完成”回声$翻译->反式(“进步”, (“进步”= >0.82]);//打印“100%的工作已经完成”回声$翻译->反式(“进步”, (“进步”= >1]);//打印"This artifact is worth $9,988,776.65"//如果我们将此转换为法语,则值将显示为// "9 988 776,65€"回声$翻译->反式(“value_of_object”, (“价值”= >9988776.65]);