3

我遇到了__函数问题,我不确定它是否是 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',具体取决于 的值$x。但如果我打电话__('Teams'),我会回来

Array
(
    [0] => Équipe
    [1] => Équipes
)

即使我删除该msgid "Teams"部分,仅保留复数定义也是如此。

在 Cake 1.3 中,__('Teams')将简单地返回 'Équipes'。(不知道它在 2.x 中会做什么,因为我完全跳过了它。)那么,这是谁的错误?

4

2 回答 2

2

重复的消息定义

这是有问题的:

msgid "Teams" <- same string
msgstr "Équipe"

msgid "Team"
msgid_plural "Teams" <- same string

第一种意味着您拥有或期望__('Teams')在应用程序代码中拥有,它期望返回一个字符串。

第二种情况是在解析 po 文件时创建不明确的数据。负责将 po 文件转换为数组格式的类是PoFileParser,它包含以下几行:

$messages[$singular] = $translation; // <- a string
...
$messages[$key] = $plurals; // <- an array

$messages用于查找翻译的数组在哪里,由翻译键索引。

所以,观察到行为的原因是因为这段代码:

__('Teams'); 

要去寻找$messages['Teams']

这段代码:

__n('Team', 'Teams', 2); 

将查找$messages['Teams'][<index>],并且该$messages数组将仅包含来自复数翻译的解析数据,这会覆盖文件中较早版本的字符串的“单数”版本。

代码级解决方案是确保所有 msgid 和 msgid_plural 键都是唯一的(因为它们本质上是相同的)。

错误的翻译定义

在未来的某个时候,您可能会发现类似__('Teams')的翻译非常有问题,这取决于使用松散词的方式,它们是翻译定义错误的指标。

举个例子,CakePHP 曾经在烘焙输出中有这种形式的翻译:

...
sprintf(__('Invalid %s', true), 'Team');
...

后来改为

__('Invalid Team', true)

因为 的翻译Invalid %s可以根据内容%s而改变 - 的翻译也可以%s

于 2016-05-16T13:39:17.327 回答
2

You have two Teams message IDs. The problem is that the CakePHP message file parser stores the messages in a key => value fashion, where the message ID is used as the key, resulting in the Teams messages for msgid_plural to override the Teams message from the preceding msgid.

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

Since gettext seems to be able to handle this, I'd say that it's at least a missing feature (which might be intentional), however it might even be a bug, I can't tell for sure (but I'd tend towards bug). For clarification, open an issue over at GitHub.

To (temporarily) workaround this issue you could use contexts.

于 2016-05-16T13:19:28.310 回答