10

使用 gettext

单值

echo gettext( "Hello, world!\n" );

复数

printf(ngettext("%d comment", "%d comments", $n), $n);

英文谐音?

echo gettext("Letter");// as in mail, for Russian outputs "письмо"
echo gettext("Letter");// as in character, for Russian outputs "буква" 

与英文单词“character”一样,可以是人的字符,也可以是字母!gettext 应该如何识别同音异义词的正确翻译?

4

4 回答 4

9

您正在寻找的是gettext可以解决歧义的上下文,例如您的示例。您可以在文档中找到有关的信息。所需的方法仍然没有在 PHP 中实现,因此您可以使用php 文档中用户注释pgettext中所述的辅助方法。

if (!function_exists('pgettext')) {

  function pgettext($context, $msgid)
  {
     $contextString = "{$context}\004{$msgid}";
     $translation = dcgettext('messages', contextString,LC_MESSAGES);
     if ($translation == $contextString)  return $msgid;
     else  return $translation;
  }

}

在你的情况下,它会是

echo pgettext('mail', 'Letter');
echo pgettext('character', 'Letter');
于 2013-04-28T13:59:18.660 回答
3

在尝试使用 GNU xgettext 实用程序从源代码中提取字符串时,我遇到了上述 pgettext() 想法的一些问题。

起初它看起来会起作用。使用 --keyword 参数,我可以运行 xgettext 实用程序从测试脚本中提取这些上下文和消息字符串:

echo pgettext('Letter','mail');
echo pgettext('Letter','character');

并获得一个具有预期输出的 .pot 文件:

...
msgctxt "mail"
msgid "Letter"
msgstr ""

msgctxt "character"
msgid "Letter"
msgstr ""
...

但是 PHP *gettext() 函数不允许我传递上下文字符串 - 所以我无法获得翻译后的文本。

能够使用 GNU 实用程序让我的事情变得更容易,所以我的解决方案是使用这样的东西:

function _c( $txt ) { return gettext( $txt ); }

echo "<P>", _c( "mail:Letter" ), "\n";
echo "<P>", _c( "character:Letter" ), "\n";

现在我运行 xgettext 实用程序

xgettext ... --keyword="_c:1" ...

针对我的测试脚本。这会生成一个带有简单 msgid 的 .pot 文件,可以通过 PHP gettext() 函数访问该文件:

...
msgid "mail:Letter"
...
msgid "character:Letter"
...

接下来,我将 .pot 模板作为 .po 文件复制到各种 LC_MESSAGE 文件夹并编辑翻译文本:

...
msgid "mail:Letter"
msgstr "Russian outputs for Mail: \"письмо\""

msgid "character:Letter"
msgstr "Russian outputs for Letter of the Alphabet: \"буква\""
...

我的测试脚本有效:

...
Russian outputs for Mail: "письмо"

Russian outputs for Letter of the Alphabet: "буква" 
...

xgettext 的文档在这里: http ://www.gnu.org/software/gettext/manual/html_node/xgettext-Invocation.html

(我仍然对 poedit 和“复数”文本有问题,但这是另一个主题。)

于 2013-08-11T05:29:56.250 回答
3

对于像我这样使用 Poedit 的人,您需要关注。首先创建函数。我正在使用一个名为 _x 的,就像 WordPress 使用的一样:

if (!function_exists('_x')) {

function _x($string, $context)
{
  $contextString = "{$context}\004{$string}";
  $translation = _($contextString);
  if ($translation == $contextString)  
     return $string;
  return $translation;
}
}

然后在 poedit 上,您需要在 Sources Keywords 选项卡上输入以下内容:

_x:1,2c
_

因此,当您需要使用上下文翻译时,您可以使用 _x 函数。例如:

<?php
echo    _x('Letter', 'alphabet');
echo    _x('Letter', 'email');
echo    _('Regular translation');

我从这些链接中获取了所有信息:

于 2016-08-26T21:02:05.130 回答
1

我制作了一个包来为 PHP 中缺少 pgettext 提供一个简单的解决方案。

这里

您需要安装软件包,composer require datalinx/gettext-context然后您可以使用

echo pgettext('Mail', 'Letter'); // Echoes: письмо
echo pgettext('Character', 'Letter'); // Echoes: буква

还实现了复数和域覆盖函数(npgettext、dpgettext、dnpgettext)。

于 2020-09-26T16:14:10.897 回答