如何使用ICU MessageFormat翻译消息
编辑该页面如何使用ICU MessageFormat翻译消息
消息(如字符串)在应用程序几乎从未完全静态的。它们包含变量或其他复杂的逻辑,如多元化的案例。处理这个问题,翻译组件支持ICU MessageFormat语法。
提示
你可以测试出的ICU messageformat的例子在线编辑器。
使用ICU的消息格式
为了使用ICU消息格式、消息域后缀为+ intl-icu
:
正常的文件名称 | ICU消息格式的文件名 |
---|---|
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允许您使用占位符(称为参数在ICU MessageFormat)在您的消息:
1 2
# + intl-icu.en.yaml翻译/消息say_hello:“你好{名称}!”
1 2 3 4 5 6 7 8 9 10 11 12
< !——/消息+ intl-icu.en翻译。xlf - - >< ?xml version = " 1.0 " encoding = " utf - 8 " ? ><xliff版本=“1.2”xmlns=“urn: oasis:名称:tc: xliff文档:1.2”><文件通过读=“en”数据类型=“明文”原始=“file.ext”><身体><trans-unitid=“say_hello”><源>say_hello< /源><目标>你好{名称}!< /目标>< /trans-unit>< /身体>< /文件>< /xliff>
1 2 3 4
/ / /消息+ intl-icu.en.php翻译返回(“say_hello”= >“你好{名称}!”,);
谨慎
在前面的翻译格式,占位符通常是裹着%
(如。%的名字%
)。这%
性格与ICU MessageFormat语法不再有效,所以你必须重命名参数如果你升级从之前的格式。
一切都在花括号({…}
)是由格式化程序处理,取而代之的是它的占位符:
1 2 3 4 5
/ /打印“法比你好!”回声美元翻译- >反式(“say_hello”,(“名字”= >“法”]);/ /输出“Hello Symfoob娱乐下载ny !”回声美元翻译- >反式(“say_hello”,(“名字”= >Sob娱乐下载ymfony的]);
根据条件选择不同的信息
花括号语法允许“修改”的输出变量。这些函数是之一选择
函数。它就像PHP的switch语句并允许您使用不同的基于变量的值的字符串。一个典型的用法是性别:
1 2 3 4 5 6 7 8 9 10
# + intl-icu.en.yaml翻译/消息#“其他”关键是必需的,如果没有其他情况选择匹配invitation_title:> - - - - - - {organizer_gender、选择、女性{{organizer_name}已经邀请你去她的派对!男性}{{organizer_name}已经邀请你去他的聚会!}多个{{organizer_name}have invited you to their party!} other {{organizer_name} has invited you to their party!} }< /span>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
< !——/消息+ intl-icu.en翻译。xlf - - >< ?xml version = " 1.0 " encoding = " utf - 8 " ? ><xliff版本=“1.2”xmlns=“urn: oasis:名称:tc: xliff文档:1.2”><文件通过读=“en”数据类型=“明文”原始=“file.ext”><身体><trans-unitid=“invitation_title”><源>invitation_title< /源>< !——所需的“其他”关键是,如果没有其他情况下匹配选择- - ><目标>{organizer_gender、选择、女性{{organizer_name}已经邀请你去她的派对!男性}{{organizer_name}已经邀请你去他的聚会!}多个{{organizer_name}have invited you to their party!} other {{organizer_name} has invited you to their party!} }< /目标>< /trans-unit>< /身体>< /文件>< /xliff>
1 2 3 4 5 6 7 8 9 10
/ / /消息+ intl-icu.en.php翻译返回(/ / '其他'关键是必需的,而且如果没有其他情况选择匹配“invitation_title”= >”{organizer_gender、选择、女性{{organizer_name}已经邀请你去她的派对!男性}{{organizer_name}已经邀请你去他的聚会!}多个{{organizer_name}have invited you to their party!} other {{organizer_name} has invited you to their party!} }'< /span>,);
这可能看起来很复杂。所有功能的基本语法{variable_name, function_name, function_statement}
(在那里,你可以看到后,function_statement
一些函数是可选的)。在这种情况下,函数名选择
和它的声明中包含“案例”的选择。这个函数的应用organizer_gender
变量:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/ /打印“瑞安已经邀请你去他的聚会!”回声美元翻译- >反式(“invitation_title”,(“organizer_name”= >“瑞恩”,“organizer_gender”= >“男”]);/ /打印”约翰和简邀请你去他们聚会!”回声美元翻译- >反式(“invitation_title”,(“organizer_name”= >约翰和简的,“organizer_gender”= >“多”]);/ /打印“ACME公司已经邀请你去他们聚会!”回声美元翻译- >反式(“invitation_title”,(“organizer_name”= >“ACME公司”,“organizer_gender”= >“not_applicable”]);
的{…}
语法“文字”和“代码”之间交替模式。这允许您使用select语句的字面文本:
- 第一个
{organizer_gender、选择…}
块开始“代码”模式,这意味着organizer_gender
作为一个变量处理。 - 内
{…邀请你去她的派对!}
块让你回到“文字”模式,即文本不处理。 - 在这个街区,
{organizer_name}
又开始“代码”模式,允许organizer_name
作为一个变量处理。
提示
虽然它可能似乎只有把更多的逻辑她的
,他的
或他们的
switch语句,最好使用“复杂参数”的最外层的结构信息。字符串以这种方式更好的翻译和可读的,正如你所看到的多个
情况下,句子的其他部分可能的影响变量。
提示
直接可以翻译ICU MessageFormat消息代码,而不需要定义在任何文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
美元邀请=”{organizer_gender、选择、女性{{organizer_name}已经邀请你去她的派对!男性}{{organizer_name}已经邀请你去他的聚会!}多个{{organizer_name}have invited you to their party!} other {{organizer_name} has invited you to their party!} }'< /span>;/ /打印“瑞安已经邀请你去他的聚会!”回声美元翻译- >反式(美元邀请,(“organizer_name”= >“瑞恩”,“organizer_gender”= >“男”),/ /如果你愿意,所需的“+ intl-icu”后缀也定义为一个常数:/ /ob娱乐下载 Symfony \组件\ \ MessageCatalogueInterface:翻译:INTL_DOMAIN_SUFFIX“消息+ intl-icu”);
多元化的案例
另一个有趣的功能是复数
。它允许您处理多元化(如在你的消息。有3个苹果
vs有一个苹果
)。函数看起来很相似选择
功能:
1 2 3 4 5 6 7
# + intl-icu.en.yaml翻译/消息num_of_apples:> -{苹果,复数,= 0{没有苹果}= 1{有一个苹果…其他}{有#苹果!}}
1 2 3 4 5 6 7 8 9 10 11 12
< !——/消息+ intl-icu.en翻译。xlf - - >< ?xml version = " 1.0 " encoding = " utf - 8 " ? ><xliff版本=“1.2”xmlns=“urn: oasis:名称:tc: xliff文档:1.2”><文件通过读=“en”数据类型=“明文”原始=“file.ext”><身体><trans-unitid=“num_of_apples”><源>num_of_apples< /源><目标>{苹果,复数,= 0{没有苹果}= 1{有一个苹果…}其他{有#苹果!}}< /目标>< /trans-unit>< /身体>< /文件>< /xliff>
1 2 3 4 5 6 7 8
/ / /消息+ intl-icu.en.php翻译返回(“num_of_apples”= >'{苹果,复数,= 0{没有苹果}= 1{有一个苹果…其他}{有#苹果!}}’,);
多元化规则实际上是相当复杂和不同的语言。例如,俄罗斯使用不同的复数形式对数字以1;数字以2、3或4;数字以5、6、7、8、9;甚至一些例外!
为了正确地翻译这个,可能的病例复数
每个语言功能也不同。例如,俄罗斯一个
,几
,许多
和其他
,而英语只有一个
和其他
。可能情况下的完整列表可以在Unicode语言复数规则文档。通过加前缀=
(比如,你可以匹配精确值0
在上面的例子中)。
使用这个字符串变量和选择是一样的:
1 2 3 4 5
/ /打印”有一个苹果…”回声美元翻译- >反式(“num_of_apples”,(“苹果”= >1]);/ /打印“有23个苹果!”回声美元翻译- >反式(“num_of_apples”,(“苹果”= >23]);
请注意
你也可以设置一个抵消
多元化变量来确定是否应该抵消(如句子你和别人#
/你和#对方
)。
提示
当结合选择
和复数
功能,还有选择
外层的函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
{gender_of_host、选择、女性{{num_guests,复数,抵消:1 = 0{{主机}不给一个聚会。}= 1{{主机}邀请{客人}她的政党。}=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.} }} }< /code>
使用范围的消息
多元化的遗留Symfony的语法可以使用自定义范围(如对他一直有ob娱乐下载不同的消息,12-40 40 +)。ICU消息格式没有这个功能。相反,这个逻辑应该搬到PHP代码:
1 2 3 4 5 6 7 8 9 10 11 12 13
/ /而不是美元消息=美元翻译- >反式(“balance_message”,美元平衡);/ /用一个消息:/ /负无穷,0)哎呀!我下来| 0,1000]我还有钱|]1000年,正]我有很多钱/ /使用三种不同的消息为每个范围:如果(美元平衡<0){美元消息=美元翻译- >反式(“no_money_message”);}elseif(美元平衡<1000年){美元消息=美元翻译- >反式(“some_money_message”);}其他的{美元消息=美元翻译- >反式(“lots_of_money_message”);}
额外的占位符函数
除了这些,ICU MessageFormat附带一些其他有趣的功能。
序数
类似于复数
,selectordinal
允许您使用数字等级分类:
1 2 3 4 5 6 7 8 9 10 11 12
# + intl-icu.en.yaml翻译/消息finish_place:>——你完成{selectordinal,{#圣}两个{# nd} {# rd}其他{# th}} !#当只有格式化数字顺序(如上图),你也可以#使用“序数”函数:finish_place:你完成了{的地方,序数}!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
< !——/消息+ intl-icu.en翻译。xlf - - >< ?xml version = " 1.0 " encoding = " utf - 8 " ? ><xliff版本=“1.2”xmlns=“urn: oasis:名称:tc: xliff文档:1.2”><文件通过读=“en”数据类型=“明文”原始=“file.ext”><身体><trans-unitid=“finish_place”><源>finish_place< /源><目标>你做完了{selectordinal,{#圣}两个{# nd} {# rd}其他{# th}} !< /目标>< /trans-unit>< !——当只有格式化数字顺序(如上图),您还可以使用“序数”功能:- - ><trans-unitid=“finish_place”><源>finish_place< /源><目标>你做完了{,序数}!< /目标>< /trans-unit>< /身体>< /文件>< /xliff>
1 2 3 4 5 6 7 8 9 10 11 12 13
/ / /消息+ intl-icu.en.php翻译返回(“finish_place”= >“你完成{selectordinal,{#圣}两个{# nd} {# rd}其他{# th}} !”,/ /当只有格式化数字顺序(如上图),你可以/ /也使用“序数”功能:“finish_place”= >“你做完了{,序数}!”,);
1 2 3 4 5 6 7 8
/ /打印“你做完了第一!”回声美元翻译- >反式(“finish_place”,(“地方”= >1]);/ /打印“你做完了9日!”回声美元翻译- >反式(“finish_place”,(“地方”= >9]);/ /打印“你做完了23日!”回声美元翻译- >反式(“finish_place”,(“地方”= >23]);
可能的情况下也显示在Unicode语言复数规则文档。
日期和时间
日期和时间函数允许你格式日期在目标地区使用IntlDateFormatter:
1 2
# + intl-icu.en.yaml翻译/消息published_at:的出版{publication_date、日期}- {publication_date、时间短}’
1 2 3 4 5 6 7 8 9 10 11 12
< !——/消息+ intl-icu.en翻译。xlf - - >< ?xml version = " 1.0 " encoding = " utf - 8 " ? ><xliff版本=“1.2”xmlns=“urn: oasis:名称:tc: xliff文档:1.2”><文件通过读=“en”数据类型=“明文”原始=“file.ext”><身体><trans-unitid=“published_at”><源>published_at< /源><目标>发表在{publication_date、日期}- {publication_date、时间短}< /目标>< /trans-unit>< /身体>< /文件>< /xliff>
1 2 3 4
/ / /消息+ intl-icu.en.php翻译返回(“published_at”= >的出版{publication_date、日期}- {publication_date、时间短}’,);
的“函数声明”时间
和日期
功能之一短
,媒介
,长
或完整的
对应定义的常量IntlDateFormatter类:
1 2
/ /打印”发表在1月25日,2019 - 11点半”回声美元翻译- >反式(“published_at”,(“publication_date”= >新\ DateTime (“2019-01-25 11:30:00”)));
数字
的数量
格式化程序允许您使用Intl的格式化数字NumberFormatter:
1 2 3
# + intl-icu.en.yaml翻译/消息进展:”{进步,数字,百分比}工作完成的value_of_object:这工件值得{价值,数量,货币}”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
< !——/消息+ intl-icu.en翻译。xlf - - >< ?xml version = " 1.0 " encoding = " utf - 8 " ? ><xliff版本=“1.2”xmlns=“urn: oasis:名称:tc: xliff文档:1.2”><文件通过读=“en”数据类型=“明文”原始=“file.ext”><身体><trans-unitid=“进步”><源>进步< /源><目标>{进步,数字,百分比}的工作就完成了< /目标>< /trans-unit><trans-unitid=“value_of_object”><源>value_of_object< /源><目标>这个工件值得{价值,数量,货币}< /目标>< /trans-unit>< /身体>< /文件>< /xliff>
1 2 3 4 5
/ / /消息+ intl-icu.en.php翻译返回(“进步”= >”{进步,数字,百分比}工作完成的,“value_of_object”= >这工件值得{价值,数量,货币}”,);
1 2 3 4 5 6 7 8 9
/ /打印“82%的工作是完成”回声美元翻译- >反式(“进步”,(“进步”= >0.82]);/ /打印“100%的工作是完成”回声美元翻译- >反式(“进步”,(“进步”= >1]);/ /打印“这价值9988776美元的工件是主板市场”/ /如果我们翻译即法国,将显示为价值/ /“9 988 776,65€”回声美元翻译- >反式(“value_of_object”,(“价值”= >9988776.65]);