如何使用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”]);

{…}语法在“文字”和“代码”模式之间交替。这允许你在选择语句中使用文字文本:

  1. 第一个{organizer_gender, select,…}Block启动“编码”模式,这意味着organizer_gender作为变量处理。
  2. {…邀请你参加她的派对!}Block将您带回到“文字”模式,这意味着文本没有被处理。
  3. 在这个方块里,{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.} }} }

传统Symfony语法中的复数可以用于自定义范围(例如,0-12ob娱乐下载、12-40和40+有不同的消息)。ICU消息格式不具有此功能。相反,这个逻辑应该移动到PHP代码中:

12 3 4 5 6 7 8 9 10 11 12 13
//代替消息翻译->反式(“balance_message”平衡);//这样的信息:/ /负无穷,0)哎呀!我输了,但我还有钱,我有很多钱//为每个范围使用三个不同的消息:如果平衡<0){消息翻译->反式(“no_money_message”);}elseif平衡<1000){消息翻译->反式(“some_money_message”);}其他的消息翻译->反式(“lots_of_money_message”);}

其他占位符函数

除此之外,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]);
此工作,包括代码示例,是根据创作共用BY-SA 3.0许可证。