gettext如何处理动态内容?

时间:2009-11-20 20:23:59

标签: php internationalization gettext

在php(或者通常是gettext)中,当gettext看到变量为动态内容时会做什么?

我有两个案例。

1)假设我有<?=$user1?> poked John <?=$user2?>。也许在某种语言中,单词的顺序是不同的。 gettext如何处理? (不,我不是在构建facebook,这只是一个例子)

2)假设我在数据库中存储了一些类别。它们很少,但它们存储在数据库中。如果我<?php echo gettext($data['name']); ?>会怎么样?我希望翻译人员也翻译这些类别名称,但它是否必须在数据库中完成?

由于

4 个答案:

答案 0 :(得分:20)

您最好的选择是使用spritf()函数。然后,您将使用printf表示法来处理字符串中的动态内容。这是我刚才在这里找到的一个功能,可以轻松地为您处理:

function translate()
{
    $args = func_get_args();
    $num = func_num_args();
    $args[0] = gettext($args[0]);

    if($num <= 1)
      return $args[0];

    return call_user_func_array('sprintf', $args);

}

现在,例如1,您可能希望将字符串更改为:

%s poked %s

您将输入到translate()函数中,如下所示:

<?php echo translate('%s poked %s', $user1, $user2); ?>

您可以使用poEdit解析所有translate()函数。然后将字符串“%s poked%s”翻译成您想要的任何语言,而无需修改%s 字符串占位符。那些将分别由user(1)和user2的translate()函数输出替换。您可以在PHP手册中阅读更多关于sprintf()的更多高级用法。

问题#2。您需要创建一个poEdit可以解析的静态文件,其中包含类别名称。例如“misctranslations.php”:

<?php

_('Cars');
_('Trains');
_('Airplanes');

然后让poEdit解析misctranslations.php。然后,您可以使用<?php echo gettext($data['name']); ?>

输出类别名称翻译

答案 1 :(得分:4)

要建立一点Mark所说的......上述解决方案的唯一问题是必须始终手动维护静态列表,如果在所有其他字符串之前添加新字符串或者您完全更改现有字符串,您用于翻译的软件可能会混淆新字符串,您可能会丢失一些翻译。

我实际上正在撰写一篇关于此的文章(很快就会很快完成它!)但我提出的答案是这样的:

Gettext允许您存储字符串出现在.po文件内的代码中的行号。如果您完全更改字符串,.po编辑器将知道该字符串不是新的,但它是旧字符串(由于行号)。

我的解决方案是编写一个读取数据库的脚本,并创建一个包含所有gettext字符串的静态文件。 Mark的解决方案的最大区别是让数据库上的主键(让我们称之为ID)与新文件中的行号匹配。在这种情况下,如果您完全更改了一个原始翻译,则这些行仍然相同,并且您的翻译软件将识别字符串。

当然可能会有更新,更聪明的.po编辑器,但至少如果你的用新字符串给你带来麻烦,那么这将解决它们。

我的2美分。

答案 2 :(得分:3)

如果您的代码中有某处: <?=sprintf(_('%s poked %s'), $user1, $user2)?> 并且您的一种语言需要交换参数,这非常简单。只需翻译您的代码,如下所示: msgid "%s poked %s" msgstr "%2$s translation_of_poked %1$s"

答案 3 :(得分:1)

@Julian

我认为你的方法在实践中不会很好。想象一下,你在代码中移动了一些功能。行号不同,文件名也可能不同。

我认为管理翻译ID更改的唯一智能方法是尝试在.po文件中找到类似的ID。编辑器可以显示将新翻译文本与现有翻译文本合并的建议,如果它们非常相似并且代码中保存的行号中没有翻译字符串。