【问题标题】:Can xgettext be used to extract specific domain strings only?xgettext 只能用于提取特定的域字符串吗?
【发布时间】:2010-07-27 08:26:26
【问题描述】:

(真的很惊讶这没有在网上任何地方得到回答;过去几年有几篇帖子有类似的问题,但从未回答过。希望 Stackoverflow 的工作人员能来救援) p>

情况:

当使用 gettext 支持应用程序本地化时,有时希望使用 dgettext('domain', 'some text string') 指定一个“域”。然而,当运行 xgettext 时,所有用 dgettext(...) 包裹的字符串都被输出到一个文件中(默认:messages.po)。

举个例子:

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

有什么办法可以解决

menus.po
页脚.po

使用诸如 xgettext 之类的提取器?

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

【问题讨论】:

    标签: localization internationalization gettext xgettext


    【解决方案1】:

    我发现这样做的唯一方法是重新定义 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 是什么意思?函数的第一个参数?
    【解决方案2】:

    我不知道如何将不同的上下文放在不同的文件中,但是我确实发现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

    【讨论】:

    • 您在这里混淆了 domainscontexts - 它们是不同的东西,用途略有不同。上下文消除了同一个 PO 文件中(即同一个域中)其他相同字符串的歧义。
    【解决方案3】:

    最好通过代码分离或使用上下文消歧来实现这一点。

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

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

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

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

    但是,现实并不总是符合最佳实践,因此,如果您不能按照 Asevere 的建议重构代码(这可能是最好的答案),那么我可以提供大量技巧。


    您可以利用鲍里斯回答中提到的上下文标志 - 我们可以重新利用它,但前提是我们不打算使用上下文。

    我会重复一遍。 只有在您的代码不使用上下文时,此 hack 才会起作用

    一些 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 文件,其中包含我们的上下文破解的所有字符串。 (请注意,我们还修复了会破坏下一位的占位符字符集字段)

    我们现在可以使用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
    

    不正确,但有效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-04
      • 1970-01-01
      • 1970-01-01
      • 2011-04-24
      • 2017-12-21
      相关资源
      最近更新 更多