使用邮件目录¶
介绍¶
这个 gettext
翻译系统使您能够将应用程序中使用的任何字符串标记为本地化,方法是将它们包装在如下函数中 gettext(str)
和 ngettext(singular, plural, num)
。为简明起见, gettext
函数通常别名为 _(str)
,因此您可以编写:
print(_("Hello"))
而不仅仅是:
print("Hello")
若要使字符串“Hello”可本地化,请执行以下操作。
消息目录是应用程序中使用的此类可本地化消息的翻译集合。它们通常存储在PO(便携对象)和MO(机器对象)文件中,其格式由GNU定义 gettext 工具和GNU translation project .
构建消息目录的一般过程如下所示:
使用工具(如
xgettext
)从代码库提取可本地化字符串,并将它们写入POT(PO模板)文件。复制特定区域设置的POT文件(例如,“en_US”),然后开始翻译消息
使用工具,如
msgfmt
要将区域设置PO文件编译为二进制MO文件,请执行以下操作稍后,当代码更改需要更新翻译时,您可以重新生成POT文件并将更改合并到各种特定于区域设置的PO文件中,例如使用
msgmerge
python提供 gettext
模块作为标准库的一部分,使应用程序能够使用适当生成的MO文件。
AS gettext
为翻译应用程序消息提供了坚实且得到良好支持的基础,但Babel并没有重新发明轮子,而是重用了这个基础设施,并使为Python应用程序构建消息目录变得更容易。
消息提取¶
Babel提供的功能类似于 xgettext
程序,只是内置了从Python源文件中提取,而可以使用简单的扩展机制添加对其他文件格式的支持。
不像 xgettext
,它通常为每个文件调用一次,所以在Babel中用于消息提取的例程对目录进行操作。而每个文件的方法 xgettext
类很好地处理项目。 Makefile
,Python项目很少使用 make
因此,需要一种不同的机制来从由许多Python项目组成的异构源文件集合中提取消息。
当邮件提取基于目录而不是单个文件时,需要有一种方法来配置应以何种方式处理哪些文件。例如,虽然许多项目可能包含 .html
文件,其中一些文件可能是不包含可本地化消息的静电Html文件,而其他文件可能是 Jinja2 模板,还有其他模板可能包含 Genshi 标记模板。有些项目甚至可能混合使用不同模板语言的HTML文件(不管是什么原因)。因此,从源文件中提取消息的方式不仅取决于文件扩展名,而且需要以精确的方式进行控制。
Babel接受一个配置文件来指定文件到提取方法的这种映射,如下所述。
前端¶
Babel提供了两个不同的前端来访问其使用消息目录的功能:
A 命令行界面 和
您选择哪一个取决于您项目的性质。对于大多数现代Python项目,distutils/setuptools集成可能更方便。
提取方式映射和配置¶
提取方法到Babel中的文件的映射是通过配置文件完成的。此文件将扩展全局模式映射到提取方法的名称,还可以为每个模式设置各种选项(哪些选项可用取决于特定的提取方法)。
例如,以下配置添加了从根式标记模板和文本模板中提取消息:
# Extraction from Python source files
[python: **.py]
# Extraction from Genshi HTML and text templates
[genshi: **/templates/**.html]
ignore_tags = script,style
include_attrs = alt title summary
[genshi: **/templates/**.txt]
template_class = genshi.template:TextTemplate
encoding = ISO-8819-15
# Extraction from JavaScript files
[javascript: **.js]
extract_messages = $._, jQuery._
配置文件语法基于中常见的格式 .INI
Windows系统上的文件,并且受 ConfigParser
Python标准库中的模块。节名称(方括号括起来的字符串)指定提取方法的名称和扩展全局模式,以指定应使用此提取方法的文件,并用冒号分隔。部分中的选项将传递给提取方法。可用的选项取决于使用的提取方法。
此配置中使用的扩展全局模式类似于大多数shell提供的全局模式。单个星号 (*
)是任意数量字符的通配符(路径名组件分隔符“/”除外),而问号 (?
)仅匹配单个字符。此外,后续的两个星号字符 (**
)可用于使通配符与任何目录级别匹配,因此模式 **.txt
匹配扩展名为的任何文件 .txt
在任何目录中。
以 #
或 ;
字符会被忽略,并可用于注释。空行也会被忽略。
备注
如果您正在使用BA贝尔提供的命令执行消息提取,以便集成到 setup.py
脚本,您还可以以不同的方式提供此配置,即作为关键字参数提供给 setup()
功能。见 总代理商/安装工具集成 更多信息。
默认提取方法¶
巴别塔自带了几个内置的提取器: python
(它从Python源文件中提取消息), javascript
和 ignore
(它不提取任何内容)。
这个 python
默认情况下,提取器映射到全局模式 **.py
,这意味着它将应用于所有具有 .py
任何目录中的扩展名。如果您指定自己的映射配置,此缺省映射将被丢弃,因此您需要显式地将其添加到您的映射中(如上面的示例所示)。
参考提取方法¶
为了能够使用简短的提取方法名称(如“genshi”),您需要 pkg_resources 已安装,并且实现该提取方法的软件包需要与其元数据一起安装( egg-info )
如果由于某些原因无法做到这一点,您需要在映射配置的Extract部分中将短名称映射到完全限定的函数名称。例如:
# Some custom extraction method
[extractors]
custom = mypackage.module:extract_custom
[custom: **.ctm]
some_option = foo
请注意,内置提取方法 python
和 ignore
默认情况下可用,即使 pkg_resources 未安装。属性中显式定义它们。 [extractors]
部分。
文字提取方法¶
添加用于提取可本地化方法的新方法很容易。首先,您需要实现一个符合以下接口的函数:
def extract_xxx(fileobj, keywords, comment_tags, options):
"""Extract messages from XXX files.
:param fileobj: the file-like object the messages should be extracted
from
:param keywords: a list of keywords (i.e. function names) that should
be recognized as translation functions
:param comment_tags: a list of translator tags to search for and
include in the results
:param options: a dictionary of additional options (optional)
:return: an iterator over ``(lineno, funcname, message, comments)``
tuples
:rtype: ``iterator``
"""
备注
此函数生成的元组中的任何字符串必须为 unicode
对象,或 str
使用纯ASCII字符的对象。这意味着,如果源包含使用其他编码的字符串,则对其进行解码是提取器实现的工作 unicode
物体。
接下来,您应该将该函数注册为入口点。这需要您的 setup.py
要使用的脚本 setuptools ,以及要与必要的元数据一起安装的软件包。如果已经解决了这一点,请将类似以下内容添加到您的 setup.py
脚本:
def setup(...
entry_points = """
[babel.extractors]
xxx = your.package:extract_xxx
""",
也就是说,将您的提取方法添加到入口点组 babel.extractors
,其中入口点的名称是人们将用来引用提取方法的名称,值是实现实际提取的模块和函数的名称(用冒号分隔)。
备注
如图所示 Referencing Extraction Methods ,声明入口点并不是严格的要求,因为用户仍然可以直接引用提取函数。但只要有可能,都应该声明入口点,以使配置更方便。
译者评论¶
首先,什么是评论标签。Comments标签是要在注释中搜索的文本摘录,仅在python前面的注释中搜索 gettext
呼叫,如以下示例所示:
# NOTE: This is a comment about `Foo Bar`
_('Foo Bar')
以上示例的注释标记为 NOTE:
,该标记的翻译器注释为 This is a comment about `Foo Bar
'.
目录模板中的结果输出将类似于::
#. This is a comment about `Foo Bar`
#: main.py:2
msgid "Foo Bar"
msgstr ""
现在,你可能会问,我为什么需要这个?
考虑一下这个简单的例子;您有一个名为“Manual”的菜单项。你知道这是什么意思,但当翻译看到这一点时,他们会想知道你的意思是:
文档或帮助手册,或
需要人工操作吗?
这是最简单的情况,翻译注释(如“安装手册”)有助于澄清情况,并使翻译人员更有效率。
备注
能否提取译者注释取决于使用的提取方法。Babel提供的Python提取器确实实现了此功能,但其他功能可能不会实现。