可以使用xgettext仅提取特定的域字符串吗?

时间:2010-07-27 08:26:26

标签: localization internationalization gettext xgettext

(真的很惊讶,这在网上任何地方都没有回答;在过去的几年里,他们发布了类似的问题,但从未接听过。我们希望Stackoverflow工作人员可以来救援)

情况:

使用gettext支持应用程序本地化时,有时希望使用dgettext('domain','some text string')指定'domain'。但是,在运行 xgettext 时,所有用dgettext(...)包装的字符串都会吐出到一个文件中(默认值为:messages.po)。

给出以下示例:

dgettext('menus', 'login link');
dgettext('menus', 'account link');
dgettext('footer', 'copyright notice');
dgettext('footer', 'contact form');

有没有办法结束

menus.po
footer.po

使用xgettext等提取器?

需要PHP响应,但我相信这应该适用于所有语言

3 个答案:

答案 0 :(得分:2)

我发现这样做的唯一方法是重新定义gettext函数......

示例:

function _menus ($str) {
    return dgettext('menus', $str);
}

function _footer ($_str) {
    return dgettext('footer', $str);
}

_menus('login link');
_menus('account link');
_footer('copyright notice');
_footer('contact form');

否则,您只需运行以下命令:

xgettext [usual options] -k --keyword=_menus:1 -d menus
xgettext [usual options] -k --keyword=_footer:1 -d footer

再见!

答案 1 :(得分:1)

我不知道如何将不同的上下文放在不同的文件中,但我确实发现xgettext可以将域名提取到po文件中的msgctxt字段中。对于PHP,默认情况下不会这样做。要启用此功能,请使用例如--keyword = dgettext:1c,2(在poedit中,将“dgettext:1c,2”添加到关键字列表中)。

另见:

http://developer.gnome.org/glib/2.28/glib-I18N.html

https://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/xgettext-Invocation.html

答案 2 :(得分:1)

最好通过代码分离或使用上下文消歧来实现此目的。

如果您可以将菜单代码与页脚代码分开,那么您可以真正地将它们视为不同的域,并从已知位置相应地提取它们。

如果模块化分离是不可能的并且所有代码都在一起,那么实际上你应该使用上下文而不是域。例如

translate( 'A string', 'myproject', 'some module' ) 

"myproject"是您的域名,"some module"消除字符串歧义。

但是,现实并不总是与最佳实践保持一致,所以如果你不能像Asevere所说的那样重构你的代码(这可能是最好的答案),那么我就会提供大量的黑客攻击。


你可以利用鲍里斯回答中提到的上下文标志 - 我们可以重新调整这个用途,但前提是我们不会使用上下文。

我会重复一遍。 只有当您的代码不使用上下文时,此黑客才有效。

一些PHP拥有两个域(包括两个中使用的一个字符串) -

<?php // test.php
dgettext( 'abc', 'foo' );
dgettext( 'abc', 'bar' );
dgettext( 'xyz', 'bar' );

我们可以作弊,并将域参数视为我们打算将其作为消息上下文(msgctxt字段)。从命令行中提取:

xgettext -LPHP --keyword=dgettext:1,2c -o - test.php \
         | sed 's/CHARSET/utf-8/' \
         > combined.pot

这将生成一个combined.pot文件,其中包含我们的上下文hack的所有字符串。 (注意我们还修复了占位符字符集字段,这将破坏下一位)

我们现在可以使用msggrep将给定上下文的所有消息过滤为单独的文件。请注意,我们还会删除上下文字段,因为我们没有使用它。

msggrep -J -e foo -o - combined.pot | sed '/^msgctxt/d' > foo.pot
msggrep -J -e bar -o - combined.pot | sed '/^msgctxt/d' > bar.pot

不正确,但有效。