【问题标题】:django-admin makemessages: how does it work with txt, xml and other files?django-admin makemessages:它如何处理 txt、xml 和其他文件?
【发布时间】:2019-04-05 10:12:39
【问题描述】:

我正在翻译一个 Django 应用程序。我在特定扩展名的文件中有可翻译的字符串(.vue 文件,但现在这不是很重要)。

我必须运行 makemessages 命令来解析这些字符串并生成 .po 文件。

文档说:

ma​​kemessages:遍历当前目录的整个源代码树并拉取 标记为翻译的所有字符串。

此外,docs 声明默认文件扩展名是:html, txt, py,并给出了一个明确定义扩展名的示例:

django-admin makemessages --locale=de --extension=html,txt --extension xml

我的问题是:makemessages 应该如何处理像 txtxml 这样的非编译文件?我如何标记字符串以供翻译在这样的文件中?

我知道如何在模板或 .py 文件中执行此操作:

.html

{% trans "Text to be translated" %}

.py

gettext("Text to be translated")
# or
_("Text to be translated")

但是其他扩展呢? .txt.xml? ... 最终是 .vue?

【问题讨论】:

  • .vue 询问关于 Vue i18n 的 vue-taggeg 问题(实际上在官方文档中有详细描述)。 .txt, .xml 他们呢?你能在这些文件中使用gettext(){% trans %} 吗?
  • gettext()是一个python函数(从django.utils.translation导入),{% trans %}是一个在django模板中可用的标签,我尝试在.xml文件中使用gettext但它被忽略了
  • 嗯,这正是我的问题的重点。文档中提到了 txt 和 xml 文件:django-admin makemessages --locale=de --extension=html,txt --extension xml
  • 好的,知道了。稍微更新了您的问题。
  • 谢谢,确实更准确:)

标签: python django vue.js internationalization gettext


【解决方案1】:

makemessages 命令搜索要翻译的文件并调用(x)gettext utility 以提取标记为要翻译的字符串。根据您告诉它使用django 还是djangojs --domain,它的行为会有所不同。

当使用django 域时,它会通过django.utils.translation.templatize 运行非.py 文件以“将Django 模板变成xgettext 可以理解的东西”)。它基本上将整个文件转换为XXXXX,除了词法分析器确定与gettext相关的部分,它保持行号不变,等等。

>>> from django.utils.translation import templatize
>>> content = """This is a {% trans "test" %}!
... {# Translators: these comments remain intact for translators #}
... {% blocktrans %}Only applies to --domain=django and non-.py files {% endblocktrans %}
... 
... Everything else is {# ignored #}
... {% trans "EOM" %}
... :)"""
>>> print(templatize(content))
XXXX XX X  gettext(u'test') X
# Translators: these comments remain intact for translators
 gettext(u'Only applies to --domain=django and non-.py files ') SSSS SSSSSSS SS SSSSSSSSSSSSSSS SSS SSSSSSS SSSSS 

XXXXXXXXXX XXXX XX 
 gettext(u'EOM') 
XX
>>> 

因此,对于大多数非 Python、非 Django 模板文件,这将消除您的可翻译内容。

当使用djangojs 域时,Django 不会对文件执行任何此类预处理。 (对于早于0.18.3gettext 版本,makemessages 将调用django.utils.jslex.prepare_js_for_gettext,这会稍微不那么激进,如果需要,只需调整任何转义/正则表达式语法。

如果你运行makemessages -a -d djangojs -e "js,vue",Django 将告诉xgettext 使用--language=JavaScript 和一定数量的额外--keyword 配置来解析你的.js.vue 文件以支持gettext_noopgettext_lazy等(gettext 默认为 keywordspec_, gettext, dgettext:2, dcgettext:2, ngettext:1,2, dngettext:2,3, pgettext:1c,2, dpgettext:2c,3JavaScript)。 makemessages 也将传递 --from-code=UTF-8--add-comments=Translators 参数。

然后交给gettext根据这些规范进行解析,并根据--language指定的文件自己理解。

因此,使用makemessages 翻译.txt.xml 等文件的最佳选择是使用djangojs 域并查看gettext 基于--language=JavaScript 得到什么,所以你会标记你的字符串就像你对 JavaScript 一样。

或者对于 Jinja2 模板等,您可以使用替代解决方案,例如 Babel's Message Extraction

或者您甚至可以customize makemessages 根据您的要求将不同的参数传递给gettext

所以对于您的 Vue 示例...

如果您的 .vue 文件在 javascript 代码部分中包含对 gettext 的调用(默认解析似乎无法识别模板属性中的 gettext 调用等),您应该会发现 makemessages 将提取这些用于翻译的字符串(compilemessages 将在编辑.po 文件后生成所需的二进制文件)。

然后为了在代码运行时查看翻译,您需要使用Django JavaScript Catalog,因此请确保在代码中包含<script type="text/javascript" src="{% url 'javascript-catalog' %}"></script> 之类的内容,以便gettext 等函数实际存在。 (听起来您已经得到了这个,但为了完整起见包括在内。)

在您的 .vue 文件中,您可以使用以下内容:

<script> // trick to ensure xgettext doesn't omit the code below: </closetag> 
    data(){
        const _ = gettext;
        // gettext default JavaScript keywordspec includes "_" shortcut
        // and should extract the strings below by default
        // -- or you could just use gettext('my string') directly
        return {                                                           
            heading: _('This is my translatable heading'),                                               
            button_text: _('Click here'),                                                                                      
        }
    }
</script>

<template>
    <h1>{{ heading }}</h1>
    <button type="button">{{ button_text }}</button>
</template>

-- 字符串应该根据 Django 翻译机制当前激活的语言进行翻译。

【讨论】:

    【解决方案2】:

    如果您希望这些文件的任何内容是动态的,那么您需要对它们进行某种解析过程。

    绝对没有理由不能将它们视为 Django 模板并通过正常的 Django 模板渲染过程来渲染它们;显然,如果不知道您对这些文件做了什么,就不可能给您具体的建议,但您可能想使用render_to_string。就其本身而言,这与翻译或makemessages没有任何关系。

    【讨论】:

    • 让我解释一下:我打算使用gettext("Text to be translated") javascript 函数。此函数在已包含已翻译字符串的文件中定义。所以基本上,我运行makemessages 命令,它生成一个带有函数和一个大 JSON 对象(包含翻译的字符串)的 javascript 文件,然后在我的任何 .js 文件(希望是 .vue 文件)中,我会可以拨打gettext("Text to be translated")docs.djangoproject.com/en/2.1/topics/i18n/translation/#gettext
    • 好的。那么你的问题是什么?
    • 基本上,从 Vue.js 组件调用 gettext 函数是可行的(仅适用于现有的翻译字符串)。我的问题是,当我想通过运行 makemessages 将新字符串添加到翻译目录时,.vue 文件(或 .xml、.txt)被忽略。它们已被处理(--verbosity 2 告诉我),但翻译后的字符串不会添加到 .po 文件中。
    猜你喜欢
    • 1970-01-01
    • 2011-08-15
    • 2012-05-20
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 2011-09-16
    • 1970-01-01
    • 2018-08-26
    相关资源
    最近更新 更多