HTML5技术

Flask 开发全球化应用 - Ray Liang

字号+ 作者:H5之家 来源:博客园 2015-11-24 08:55 我要评论( )

Flask 开发全球化应用 从C#世界迈入python总是令人有一种如释重负之感,同样的效果同样的功能,只需要付出1/10不到的代价,可能正是Python所倡导的简美哲学所带来的威力。 我还深深地记得在ASP.NET中做全球化的经历,可谓是苦不堪言。由于 .net 是采用xml格

Flask 开发全球化应用

从C#世界迈入python总是令人有一种如释重负之感,同样的效果同样的功能,只需要付出1/10不到的代价,可能正是Python所倡导的简美哲学所带来的威力。

我还深深地记得在ASP.NET中做全球化的经历,可谓是苦不堪言。由于 .net 是采用xml格式的资源文件作为资源承载格式,导致对全球化资源的引用就必须要采用严格的合乎c#命名规范。这样一来在资源的使用过程中就增加“命名”这一复杂度。以前从不认为有什么问题,不过一但转译成多国版本或者要对资源文件进行更新就会面临着巨大的工作量。
而且ASP.NET官方推荐的全球化做法则更是坑人,简直就是将“Quickly and duty”发挥到了极至,一但做了也只好陷入永不休止似的维护地狱之中。

还是直到在接触 Web2Py 时才发现他们对全球化的做法有点像样了,Web2Py中没有了中间关键字命名,而是将自然用词直接作为资源的搜索关键字,这对于长期用ASP.NET开发全球化项目的我无疑是一咱脑洞大开的过程。而且,制作默认语言模板的工作量还是巨大的这个过程仍然需要手工处理,因此我一直在寻找更好的应用方案。

直至在Flask 中遇到了 Flask-Babel 这个插件。花了10多分钟就能上手了,看到它的用法简直是让人兴奋不已——简单、省事。

Flask-Babel 就是在Flask中对Babel的插件,它有几个很让人印象深刻的特色:

Flask-Babel 的用法 将 Flask-Babel 加载至 Flask 的应用上下文 from flask import Flask from flask.ext.babel import Babel app = Flask(__name__) app.config.from_pyfile('babel.cfg') babel = Babel(app) babel.cfg 配置文件

babel.cfg 是一个放置于Flask项目根目录下的Babel配置文件,它是一个固定的配置,以下是官方推荐的写法:

[python: **.py] [jinja2: **/templates/**.html] extensions=jinja2.ext.autoescape,jinja2.ext.with_

如果采用了 Flask-Assets 插件的话需要修改一下 extensions 的设置

[python: **.py] [jinja2: **/templates/**.html] extensions=jinja2.ext.autoescape,jinja2.ext.with_,webassets.ext.jinja2.AssetsExtension gettext()/_()

接下来就可以在python代码内或者jinia页面内使用 gettext() 方法引用全球化资源。其实此时我们并没有任何的资源文件,但这正是Babel最吸引人的地方——先使用再生成资源。

在 python 代码内可以这样使用 gettext()

from flask import Flask, render_template from flaskext.babel import Babel, gettext as _ app = Flask(__name__) app.config['BABEL_DEFAULT_LOCALE'] = 'zh' babel = Babel(app) @app.route('/') def hello(): s = _("Saturday") return render_template('index.html', day=day) if __name__ == '__main__': app.debug = True app.run()

以上代码中_("Saturday")就是从资源中获取名为Saturday的资源,如果没有资源文件或者没有找到对应的区域就会直接输出"Saturday"

然后就是在 jinja 模板内使用:

<p>{{ _("Hello, world!") }}</p> <p>{{ _("It's %(day)s today", day=day) }}</p>

同理,在其它的代码和模块内就是以这两种方式使用全球化资源。

生成翻译模板

这是很重要的一步,也是Babel最省时省力的一步。Babel可以从代码和模板中抽出用了gettext()的所有的资源名并生成到默认语言模板内。生成这个模板后就可以翻译成各种需要的本地化语言。

只需要在命令行内键入以下命令

$ pybabel extract -F babel.cfg -o messages.pot .

就会在Flask的项目根目录下生成 messages.pot 的默认语言模板

翻译模板

接下来就是从默认模板翻译成指定区域语言的资源文件了,也是通过命令行处理:

$ pybabel init -i messages.pot -d translations -l zh

这个指令的执行结果是按照messages.pot将 中文(zh)资源文件(message.po)生成至 translations 目录。

目录结构如下:

. ├── babel.cfg ├── messages.pot ├── static ├── templates └── translations └── zh └── LC_MESSAGES └─ message.po

message.po 就是目标资源文件,现在就可以打开并进行相关的翻译工作了。*.po 文件只是一个文本可以直接编辑,或者可以选择一些专用的po编程工具也成。我比较推荐使用POEdit

注 当指区域时需要使用区域简写而不是区域全名,如果指定 zh-CN(简体中文)的话就直接采用 zh 否则指令会出错。

message.po 文件

以下是 message.op的内容

# Chinese translations for PROJECT. # Copyright (C) 2015 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # Ray <csharp2002@hotmail>, 2015. #, fuzzy msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: csharp2002@hotmail.com\n" "POT-Creation-Date: 2015-03-29 22:46+0800\n" "PO-Revision-Date: 2015-03-29 21:49+0800\n" "Last-Translator: Ray <csharp2002@hotmail.com>\n" "Language-Team: zh <LL@li.org>\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: views.py:103 #,fuzzy, python-format msgid "Articles tagged with:%(value)s" msgstr "标记%(value)s主题的文章"

注: ,fuzzy 这个关键字,如果需要编译资源文件成为 *.mo的话则需要将它删除,否则资源文件编译器会直接忽略掉整个资源文件而不进行编译。

编译资源

编译过程很简单,只需要执行以下指令 translations 下所有的 *.po 文件就会被编译成二进制的 *.mo 资源文件。

$ pybabel compile -d translations 更新默认模板

这可谓是 Babel 一个很为开发者着想的功能,因为我们的程序资源必定是需要变更与维护的,自然而然地资源文件的内容必定会有增减。当我们翻译了N种语言副本之后如果没有相关工具而是由手工来做的话那将是一种极为可怕的工作过程。幸运的是我们只需要执行以下的指令,babel将为更新默认模板和所有从此模板生成的所有资源文件的内容:

$ pybabel update -i messages.pot -d translations 区域切换

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 【Vue 入门】使用 Vue2 开发一个展示项目列表的应用 - zhangjk

    【Vue 入门】使用 Vue2 开发一个展示项目列表的应用 - zhangjk

    2017-04-30 16:00

  • 在Delphi下使用迅雷APlayer组件进行免注册开发 - Delphi力量

    在Delphi下使用迅雷APlayer组件进行免注册开发 - Delphi力量

    2017-04-28 15:00

  • 随应潮流-基于ABP+Angularjs现代化应用软件开发框架(1)-总体介绍 - 在路在的张

    随应潮流-基于ABP+Angularjs现代化应用软件开发框架(1)-总体介绍 -

    2017-04-22 08:04

  • vue2.0版cnode社区项目搭建及实战开发 - sandisen

    vue2.0版cnode社区项目搭建及实战开发 - sandisen

    2017-04-20 14:00

网友点评