django-admin makemessages:它如何处理 txt、xml 和其他文件?

Mon*_*nja 4 python django gettext internationalization vue.js

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

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

文档说:

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

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

django-admin makemessages --locale=de --extension=html,txt --extension xml
Run Code Online (Sandbox Code Playgroud)

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

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

.html

{% trans "Text to be translated" %}
Run Code Online (Sandbox Code Playgroud)

.py

gettext("Text to be translated")
# or
_("Text to be translated")
Run Code Online (Sandbox Code Playgroud)

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

DrM*_*ers 7

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

使用django域时,它运行非.py文件django.utils.translation.templatize以“将 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
>>> 
Run Code Online (Sandbox Code Playgroud)

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

使用djangojs域时,Django 不会对文件执行任何此类预处理。(对于gettext比 更早的版本0.18.3makemessages会调用django.utils.jslex.prepare_js_for_gettext,这有点不那么激进,并且在必要时只调整任何转义/正则表达式语法)。

如果你运行makemessages -a -d djangojs -e "js,vue",Django会告诉xgettext解析您.js.vue处理文件--language=JavaScript和额外一定数量的--keyword配置来支持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指定的文件对文件进行自己的理解。

因此,翻译.txt.xml等文件的最佳选择makemessages是使用djangojs域并查看gettext基于 的内容--language=JavaScript,因此您可以像对 JavaScript 一样标记字符串。

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

或者您甚至可以自定义makemessagesgettext根据您的要求传递不同的参数。

因此,对于您的 Vue 示例...

如果你的.vue文件中包含的调用gettextJavaScript代码段(默认解析似乎没有拿起gettext模板属性中调用等),你会发现,makemessages将提取这些字符串翻译(和compilemessages将生成后所需的二进制文件.po文件编辑)。

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

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

>>> 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
>>> 
Run Code Online (Sandbox Code Playgroud)

-- 应根据 Django 翻译机制当前激活的语言礼貌来翻译字符串。