flask 若需多国语言支持,可使用 flask-babel 扩展实现。

基本使用步骤为,安装扩展并初始化,用 gettext() 函数设置需要被翻译的字符串。创建 babel.cfg 映射文件,然后使用 pybabel 依次生成 .pot .po .mo 翻译文件,当内容发生变化时使用 pybabel 更新翻译内容。

第一步 初始化

from flask import Flask
from flask_babel import Babel

app = Flask(__name__)
app.config.update(
    DEBUG = True,
    TEMPLATES_AUTO_RELOAD = True,
    BABEL_DEFAULT_LOCALE = 'zh',
    BABEL_DEFAULT_TIMEZONE = 'Asia/Shanghai',
)
babel = Babel(app)

第二步 要翻译的内容

标准方法是直接使用 gettext()ngettext() 函数,例如:

from flask-babel import gettext, ngettext

gettext(u'User Name:')
gettext(u'Value: %(value)s', value=42)
ngettext(u'%(num)s Apple', u'%(num)s Apples', number_of_apples)

lazy_gettext()
(待续)

在 jinja2 模板中
jinja2 模板中即可使用 {{ gettext(u'User Name') }} 方法,也可以直接使用更简单的别名形式 {{ _(u'User Name') }}

第三步 创建映射文件

在项目目录创建 babel.cfg 配置文件,添加以下内容:

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

第四步 生成 pot 模板文件

使用终端,如果有虚拟环境先激活,进入项目目录(babel.cfg 所在目录),执行命令:

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

该命令会将项目中设置了 gettext() 的内容映射到 pot 文件中。

第五步 生成 po 文件

执行以下命令,会在当前目录创建 translates 目录,并在该目录中创建相应语言的子目录及 po 文件。

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

生成的文件结构:translations/zh/LC_MESSAGES/messages.po

第六步 编译 mo 文件

flask-babel 最终使用 mo 文件作为程序的语言文件,使用以下命令将翻译好的 po 文件转换成 mo 文件。

pybabel compile -d translations

如果使用 poedit 工具翻译 .po 文件,程序会自动生成对应的 .mo 文件。

更新 pot 文件

当项目内容发生变化时,应更新 message.pot 模板文件:

更新 pot 模板文件

pybael extract -F babel.cfg -o messages.pot .

更新 po 翻译文件

pybabel update -i messages.pot -d translations

Ubuntu 的一个坑

系统为 Ubuntu Desktop 16.04.4,flask 项目运行在 venv 环境中,按上述步骤操作,在使用 pybabel 生成 .pot 发生错误:

Traceback (most recent call last):
  File "/home/herald/flask/bin/pybabel", line 11, in <module>
    sys.exit(main())
  File "/home/herald/flask/lib/python3.5/site-packages/babel/messages/frontend.py", line 908, in main
    return CommandLineInterface().run(sys.argv)
  File "/home/herald/flask/lib/python3.5/site-packages/babel/messages/frontend.py", line 832, in run
    return cmdinst.run()
  File "/home/herald/flask/lib/python3.5/site-packages/babel/messages/frontend.py", line 467, in run
    for filename, lineno, message, comments, context in extracted:
  File "/home/herald/flask/lib/python3.5/site-packages/babel/messages/extract.py", line 157, in extract_from_dir
    dirpath=absname,
  File "/home/herald/flask/lib/python3.5/site-packages/babel/messages/extract.py", line 212, in check_and_call_extract_file
    strip_comment_tags=strip_comment_tags
  File "/home/herald/flask/lib/python3.5/site-packages/babel/messages/extract.py", line 241, in extract_from_file
    strip_comment_tags))
  File "/home/herald/flask/lib/python3.5/site-packages/babel/messages/extract.py", line 303, in extract
    func = entry_point.load(require=True)
  File "/home/herald/flask/lib/python3.5/site-packages/pkg_resources/__init__.py", line 2228, in load
    self.require(*args, **kwargs)
  File "/home/herald/flask/lib/python3.5/site-packages/pkg_resources/__init__.py", line 2245, in require
    items = working_set.resolve(reqs, env, installer)
  File "/home/herald/flask/lib/python3.5/site-packages/pkg_resources/__init__.py", line 808, in resolve
    if not req_extras.markers_pass(req):
  File "/home/herald/flask/lib/python3.5/site-packages/pkg_resources/__init__.py", line 993, in markers_pass
    return not req.marker or any(extra_evals) or req.marker.evaluate()
  File "/home/herald/flask/lib/python3.5/site-packages/pkg_resources/_vendor/packaging/markers.py", line 278, in evaluate
    return _evaluate_markers(self._markers, current_environment)
  File "/home/herald/flask/lib/python3.5/site-packages/pkg_resources/_vendor/packaging/markers.py", line 203, in _evaluate_markers
    lhs_value = _get_env(environment, lhs.value)
  File "/home/herald/flask/lib/python3.5/site-packages/pkg_resources/_vendor/packaging/markers.py", line 185, in _get_env
    "{0!r} does not exist in evaluation environment.".format(name)
pkg_resources.extern.packaging.markers.UndefinedEnvironmentName: 'extra' does not exist in evaluation environment.

解决办法为升级 setuptools:

(venv)$ pip install --upgrade setuptools

参考