gettext
是通用的 gnu 国际化方案,考虑与 flask 框架的结合,采用 flask-babel 库来支持
使用pip3 install Flask-Babel
安装库
运行过程:
1.前端在切换语言时设置 locale cookie 为对应的值,如【en,zh】;
2.后端接收请求时根据客户端的 locale 值渲染返回不同的语言;
操作步骤:
1.在hello.py
(主入口,即flask app
定义的文件)同级目录创建babel.cfg
配置文件
[python: **.py]
[jinja2: **/templates/**.html]
extensions=jinja2.ext.autoescape,jinja2.ext.with_
复制代码
2.生成翻译模板
pybabel extract -F babel.cfg -o messages.pot .
复制代码
注意后面的点(.),表示当前目录,该命令在当前目录生成 messages.pot 文件
3.生成翻译
pybabel init -i messages.pot -d translations -l zh
复制代码
zh 表示中文,其他语言则改为对应的。编译生成 translations/zh/LC_MESSAGES/messages.po 文件,翻译其中的字符串
# Chinese translations for PROJECT.
# Copyright (C) 2021 ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2021.
#
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2021-03-04 21:39+0800\n"
"PO-Revision-Date: 2021-03-04 21:39+0800\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: zh\n"
"Language-Team: zh <LL@li.org>\n"
"Plural-Forms: nplurals=1; plural=0\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.9.0\n"
#: hello.py:19
msgid "hello"
msgstr "你好世界"
#: templates/index.html:12
#, python-format
msgid "%(text)s"
msgstr "%(text)s"
复制代码
最终的目录结构如下
├── babel.cfg
├── hello.py
├── messages.pot
├── templates
│ └── index.html
└── translations
└── zh
└── LC_MESSAGES
├── messages.mo
└── messages.po
复制代码
4.编译翻译文件
pybabel compile -d translations
复制代码
执行生成对应的 mo 文件,为机器识别的文件
5.更新翻译
修改程序后如果要更新翻译,需要用前面的命令重新生成 messages.pot 文件,然后将更新的内容 merge 到原来的翻译
pybabel update -i messages.pot -d translations
复制代码
6.完整的代码如下
from flask import Flask, render_template, request, make_response, jsonify
from flask_babel import Babel, gettext as _
app = Flask(__name__)
app.config['BABEL_DEFAULT_LOCALE'] = 'en' # 设置默认语言为 en
app.config['JSON_AS_ASCII'] = False
babel = Babel(app)
@babel.localeselector
def get_locale(): # 核心,当网站含有locale的cookie,且符合['zh', 'en']
cookie = request.cookies.get('locale')
if cookie in ['zh', 'en']:
return cookie
return request.accept_languages.best_match(app.config.get('BABEL_DEFAULT_LOCALE')) # 没有cookie时,默认为 en
@app.route('/test') # 测试页面
def test():
text = _('hello') # 需要翻译的文本
return render_template('index.html', text=text)
@app.route('/set_locale/<locale>') # 用ajax请求来设置cookie
def set_locale(locale):
res = _('hello')
response = make_response(jsonify(message=locale + ' set successfully :' + res,))
if locale:
response.set_cookie('locale', locale)
return response
if __name__ == '__main__':
app.debug = True
app.run()
复制代码
一些问题
1.使用lazy_gettext
实际应用中有些需要翻译的文件是作为库引入的,这时上面的处理方式会失效,可以使用lazy_gettext
替代 gettext,只需修改 import 即可
from flaskbabel import Babel, lazygettext as _
复制代码
官方文档
评论