我遇到了__
函数的问题,我不确定它是否是Cake(3.2.8),Aura \ Intl或我的代码中的错误。我在Cake 1.3中尝试了同样的事情,它的工作方式与我预期的一样,但我的期望可能就是这样,因为这就是它在1.3中的工作方式。 : - )
当我构建菜单时,我使用__('Teams')
之类的内容,但我也有使用__n('Team', 'Teams', count($player->teams))
之类的内容的页面。 i18n shell分别将这些提取到default.pot中,所以当我将它翻译成法语时,就像这样:
msgid "Teams"
msgstr "Équipe"
msgid "Team"
msgid_plural "Teams"
msgstr[0] "Équipe"
msgstr[1] "Équipes"
如果我拨打__('Team')
,我会正确地返回'Équipe',如果我拨打__n('Team', 'Teams', $x)
,我会正确地返回'Équipe'或'Équipes',具体取决于{{1}的值}}。但如果我打电话给$x
我就会回来
__('Teams')
即使我删除Array
(
[0] => Équipe
[1] => Équipes
)
部分,只留下复数定义,也是如此。
在Cake 1.3中,msgid "Teams"
只会返回'Équipes'。 (不知道它在2.x中会做什么,因为我完全跳过它。)那么,这是谁的错误?
答案 0 :(得分:2)
您有两个Teams
条消息ID。问题是CakePHP消息文件解析器以key => value
方式存储消息,其中消息ID用作密钥,导致Teams
msgid_plural
消息覆盖Teams
来自前一个msgid
的消息{1}}。
<强> https://github.com/cakephp/cakephp/blob/3.2.8/src/I18n/Parser/PoFileParser.php#L149 强> 的 https://github.com/cakephp/cakephp/blob/3.2.8/src/I18n/Parser/PoFileParser.php#L172 强>
<强> https://github.com/cakephp/cakephp/blob/3.2.8/src/I18n/Parser/MoFileParser.php#L137-L140 强>
由于gettext
似乎能够解决这个问题,我说它至少是一个缺失的功能(可能是故意的),但它甚至可能是一个错误,我无法确定(但我倾向于犯错误)。有关说明,请在at GitHub上打开一个问题。
要(暂时)解决此问题,您可以使用上下文。
答案 1 :(得分:2)
这是有问题的:
msgid "Teams" <- same string
msgstr "Équipe"
msgid "Team"
msgid_plural "Teams" <- same string
第一个意味着你已经或者期望在应用程序代码中有__('Teams')
,它希望返回一个字符串。
第二种情况是在解析po文件时创建不明确的数据。负责将po文件转换为数组格式的类是the PoFileParser,其中包含以下行:
$messages[$singular] = $translation; // <- a string
...
$messages[$key] = $plurals; // <- an array
其中$messages
是用于查找翻译的数组,由翻译键索引。
因此,观察到的行为的原因是因为这段代码:
__('Teams');
将寻找$messages['Teams']
此代码:
__n('Team', 'Teams', 2);
将寻找$messages['Teams'][<index>]
,而$messages
数组将仅包含来自复数翻译的解析数据,其覆盖了&#34; singular&#34;文件中较早的字符串版本。
代码级解决方案是确保所有msgid和msgid_plural密钥都是唯一的(因为它们本质上是相同的)。
您可能会在将来的某个时候发现像__('Teams')
这样的翻译非常有问题,这取决于如何使用这个松散的词,它们是不良翻译定义的指标。
举一个例子,CakePHP曾经在烘焙输出中翻译过这个表格:
...
sprintf(__('Invalid %s', true), 'Team');
...
__('Invalid Team', true)
因为Invalid %s
的翻译可能会根据%s
的内容而改变 - %s
的翻译也是如此。