i18n 扩展

Import name:jinja2.ext.i18n

Jinja2 当前只附带一个扩展,就是 i18n 扩展。它可以与 gettextbabel联合使用。如果启用了 i18n 扩展, Jinja2 提供了 trans 语句来标记被其包裹的字符串为可翻译的,并调用 gettext

在启用虚拟的 __ 函数后,之后的 _gettext 调用会被添加到环境的全局变量。那么一个国际化的应用应该不仅在全局,以及在每次渲染中在命名空间中提供至少一个gettext 或可选的 ngettext 函数。

环境方法

在启用这个扩展后,环境提供下面的额外方法:

  • jinja2.Environment.installgettext_translations(_translations, newstyle=False)
  • 在该环境中全局安装翻译。提供的翻译对象要至少实现 uggettextungettextgettext.NullTranslationsgettext.GNUTranslations类和 Babel‘s 的 Translations 类也被支持。

Changed in version 2.5: 添加了新样式的 gettext

  • jinja2.Environment.installnull_translations(_newstyle=False)
  • 安装虚拟的 gettext 函数。这在你想使应用为国际化做准备但还不想实现完整的国际化系统时很有用。

Changed in version 2.5: 添加了新样式的 gettext

  • jinja2.Environment.installgettext_callables(_gettext, ngettext, newstyle=False)
  • 在环境中把给出的 gettextngettext 可调用量安装为全局变量。它们应该表现得几乎与标准库中的 gettext.ugettext() 和gettext.ungettext() 函数相同。

如果激活了 新样式 ,可调用量被包装为新样式的可调用量一样工作。更多信息见 新样式 Gettext

New in version 2.5.

  • jinja2.Environment.uninstall_gettext_translations()
  • 再次卸载翻译。
  • jinja2.Environment.extracttranslations(_source)
  • 从给定的模板或源中提取本地化字符串。

对找到的每一个字符串,这个函数生产一个 (lineno,function,message) 元组,在这里:

  • lineno 是这个字符串所在行的行号。
  • functiongettext 函数使用的名称(如果字符串是从内嵌的 Python代码中抽取的)。
  • message 是字符串本身(一个 unicode 对象,在函数有多个字符串参数时是一个 unicode 对象的元组)。如果安装了 BabelBabel 集成 可以用来为babel 抽取字符串。

对于一个对多种语言可用而对所有用户给出同一种的语言的 web 应用(例如一个法国社区安全了一个多种语言的论坛软件)可能会一次性加载翻译并且在环境生成时把翻译方法添加到环境上:

  1. translations = get_gettext_translations()
  2. env = Environment(extensions=['jinja2.ext.i18n'])
  3. env.install_gettext_translations(translations)

get_get_translations 函数会返回当前配置的翻译器。(比如使用 gettext.find

模板设计者的 i18n 扩展使用在 模板文档 中有描述。

新样式 Gettext

New in version 2.5.

从版本 2.5 开始你可以使用新样式的 gettext 调用。这些的启发源于 trac 的内部gettext 函数并且完全被 babel 抽取工具支持。如果你不使用 Babel 的抽取工具,它可能不会像其它抽取工具预期的那样工作。

标准 gettext 调用和新样式的 gettext 调用有什么区别?通常,它们要输入的东西更少,出错率更低。并且如果在自动转义环境中使用它们,它们也能更好地支持自动转义。这里是一些新老样式调用的差异:

标准 gettext:

  1. {{ gettext('Hello World!') }}
  2. {{ gettext('Hello %(name)s!')|format(name='World') }}
  3. {{ ngettext('%(num)d apple', '%(num)d apples', apples|count)|format(
  4. num=apples|count
  5. )}}

新样式看起来是这样:

  1. {{ gettext('Hello World!') }}
  2. {{ gettext('Hello %(name)s!', name='World') }}
  3. {{ ngettext('%(num)d apple', '%(num)d apples', apples|count) }}

新样式 gettext 的优势是你需要输入的更少,并且命名占位符是强制的。后者看起来似乎是缺陷,但解决了当翻译者不能切换两个占位符的位置时经常勉励的一大堆麻烦。使用新样式的 gettext ,所有的格式化字符串看起来都一样。

除此之外,在新样式 gettext 中,如果没有使用占位符,字符串格式化也会被使用,这使得所有的字符串表现一致。最后,不仅是新样式的 gettext 调用可以妥善地为解决了许多转义相关问题的自动转义标记字符串,许多模板也在使用自动转义时体验了多次。