Flask的Jinja2模板引擎 — 本地化(7th)

一个强大的工具一般都支持扩展或插件的开发功能,来允许第三方通过开发新扩展或插件,扩充工具本身功能,并可以贡献给社区。Jinja2也不例外,Jinja2本身提供了一部分扩展,你可以在程序中启用。同时,你还可以创建自己的扩展,来扩充模板引擎功能。本篇会先介绍Jinja2自带的扩展”jinja2.ext.i18n”的使用,自定义扩展的开发会放在下一篇阐述。

在Flask中启用Jinja2扩展

任何时候使用Jinja2时,都需要先创建Jinja2环境,所以启用扩展的方法就是在创建环境时指定:

但是你在使用Flask时,其已经有了一个Jinja2环境,你不能再创建一个,所以你需要想办法添加扩展。Flask对于扩展不像过滤器或测试器那样封装了添加方法和装饰器,这样你就只能直接访问Flask中的Jinja2环境变量来添加。

Jinja2内置扩展

我们已经介绍了四个Jinja2内置扩展的使用:”jinja2.ext.autoescape”, “jinja2.ext.with_”, “jinja2.ext.do”和”jinja2.ext.loopcontrols”。除了这几个以外,Jinja2还有一个非常重要的扩展,就是提供本地化功能的”jinja2.ext.i18n”。它可以与”gettext”或”babel”联合使用,接下来我们采用”gettext”来介绍怎么使用这个本地化扩展。

创建本地化翻译文件

建议大家先去了解下Python gettext相关知识,篇幅关系本文就不准备细讲。这里我们使用Python源代码(记住不是安装包)中”Tools/i18n”目录下的工具来创建翻译文件。

  1. 首先我们生成翻译文件模板,在”Tools/i18n”目录中找到”pygettext.py”并运行

上述命令会在当前目录下生成一个名为”message.pot”的翻译文件模板,内容如下:

2. 将”message.pot”中”CHARSET”和”ENCODING”替换成”UTF-8″。同时你可以更改注释信息

修改完后,将其另存为翻译文件”lang.po”。

3.在”lang.po”中添加你要翻译的文字,比如

将其加在文件末尾。这里”msgid”指定了待翻译的文字,而”msgstr”就是翻译后的文字。

4. 生成”lang.mo”文件

我们依然使用”Tools/i18n”目录提供的工具,”msgfmt.py”:

执行完后,当前目录生成了”lang.mo”文件。注意,只有这个”*.mo”文件才能被应用程序识别。另外,推荐一个工具Poedit,很强的图形化po编辑工具,也可以用来生成mo文件,非常好用,Mac和Windows下都能用。

5. 将po, mo文件加入应用

我们在当前Flask工程下创建子目录”locale/zh_CN/LC_MESSAGES/”,并将刚才生成的”lang.po”和”lang.mo”文件放到这个目录下。这里”locale”子目录的名字可以更改,其他的个人建议不要改。

在模板中使用本地化

让我们在Flask应用代码中启用”jinja2.ext.i18n”,并加载刚创建的翻译文件。

这个”install_gettext_translations()”方法就是Jinja2提供来加载”gettext”翻译文件对象的。加载完后,你就可以在模板中使用本地化功能了。方法有两种:”{% trans %}”语句或”gettext()”方法。我们先来试下”{% trans %}”语句,在模板文件中,我们加上:

运行下,有没有看到页面上打印了”世界,你好!”,恭喜你,成功了!使用”gettext()”方法如下,效果同”{% trans %}”语句一样。

Jinja2还提供了”_( )”方法来替代”gettext( )”,代码看起来很简洁,个人推荐使用这个方法。

上面的例子是在程序中指定本地化语言,你也可以在请求上下文中判断请求头”Accept-Language”的内容,来动态的设置本地化语言。

翻译内容带参数

有时候,待翻译的文字内有一个变量必须在运行时才能确定,怎么办?我可以在翻译文字上加参数。首先,你要在po文件中定义带参数的翻译文字,并生成mo文件:

然后,你就可以在模板中,使用”{% trans %}”语句或”gettext()”方法来显示它:

上例中,我们把模板中的变量”name”赋给了翻译文字中的变量”user”。翻译文字上可以有多个变量。

新样式 (Newstyle)

Jinja2从2.5版本开始,支持新的gettext样式,使得带参数的本地化更简洁,上面的例子在新样式中可以写成:

不过使用新样式前,你必须先启用它。还记得我们介绍过Jinja2加载翻译文件的方法吗?对,就是”install_gettext_translations()”。调用它时,加上”newstyle=True”参数即可。

单/复数支持

英文有个特点就是名词有单/复数形式,一般复数都是单数后面加s,而中文就不区分了,哎,老外就是麻烦。所谓外国人创造的Python gettext,自然也对单/复数提供了特殊的支持。让我们现在po文件中,加上下面的内容,并生成mo文件:

什么意思呢,这个”msgid_plural”就是指定了它上面”msgid”文字的复数形式。而”msgstr”的[0], [1]分别对应了单/复数形式翻译后的内容。为什么这么写?你别管了,照着写就是了。

在模板中,我们加上下面的代码:

你会很惊奇的发现,当”num”变量为5时,页面显示”5个物品集”;而当”num”变量为1时,页面显示”1个物品”。也就是程序自动匹配单/复数。很神奇吧!

本来准备在本篇把扩展都介绍完的,发现单写个”i18n”后篇幅就很长了,只好把自定义扩展部分另起一篇。

完整实例:jinja2-7.tar

  • 版权声明: 本文源自互联网, 于8个月前,由整理发表,共 2894字。
  • 原文链接:点此查看原文

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: