Flask Vue.js全栈开发|第19章:国际化
Synopsis: 接下来将让我们的应用支持多种语言,后端 API 使用 Flask-Babel 模块,会根据你的 HTTP 请求中 Accept-Language 头部来判断你当前最适合阅读的语言,而前端 Vue.js 则使用 vue-i18n 插件来实现页面上文件的翻译
本系列的最新代码将持续更新到: http://www.madmalls.com/blog/post/latest-code/
1. Flask-Babel
我们在后端提供 Flask-Babel
插件来简化 API 接口提示信息的翻译工作
1.1 安装
会同时安装另外两个模块:
Babel
: Python 支持国际化的模块pytz
: 支持本地时区的模块
1.2 配置
修改 back-end/config.py
:
修改 back-end/app/extensions.py
:
修改 back-end/app/__init__.py
:
from flask import Flask, request from app.extensions import cors, db, migrate, mail, babel ... def configure_extensions(app): ... # Init Flask-Babel babel.init_app(app) @babel.localeselector def get_locale(): # return 'zh' # 这样设置的话,所有用户永远显示中文 return request.accept_languages.best_match(app.config['LANGUAGES'])
客户端请求 request
对象中 Accept-Language
头部 指定了客户端语言和区域设置首选项,该头部的内容可以在浏览器的首选项页面中配置,默认情况下通常从计算机操作系统的语言设置中导入,比如我的:
总之,上面的 best_match()
方法会从当前应用所支持的语言列表中,帮你选择最佳语言
1.3 标记哪些文本需要翻译
可以使用 flask_babel.gettext()
和 flask_babel.lazy_gettext()
来标记 Python 代码或 Jinja2
模板中需要翻译的文本,由于我们的后端 API 没有使用 Jinja2
模板,所以只演示用户 API 中一些提示信息的翻译
修改 back-end/app/api/users.py
:
from flask_babel import gettext as _ ... @bp.route('/users/', methods=['POST']) def create_user(): '''注册一个新用户''' data = request.get_json() if not data: return bad_request(_('You must post JSON data.')) ...
这里将 'You must post JSON data.'
文本标记为待会要翻译的内容,同理,你可以将所有你觉得需要翻译的文本全部用 _()
函数标记起来(因为 gettext
用的地方太多,为了简便,将它重命名为 _
)
如果要翻译有格式化符号的字符串,比如:
则需要使用如下语法:
注意: 在
.po
文件中翻译时,要保留%(username)s
#: app/api/users.py:187 #, python-format msgid "You are now following %(username)s." msgstr "你已成功关注了%(username)s"
1.4 翻译
(1)babel.cfg
pybabel
命令需要你提供一个配置文件,让它知道从哪些目录及文件中去查找 _()
等标记
创建 back-end/babel.cfg
:
(2).pot
现在我们可以使用 pybabel extract
命令从源文件中提取待翻译的文本,并生成 POT
模板文件
(venv)$ pybabel extract -F babel.cfg -o messages.pot . extracting messages from app\__init__.py extracting messages from app\extensions.py extracting messages from app\models.py extracting messages from app\api\__init__.py extracting messages from app\api\auth.py extracting messages from app\api\comments.py extracting messages from app\api\errors.py extracting messages from app\api\messages.py extracting messages from app\api\notifications.py extracting messages from app\api\ping.py extracting messages from app\api\posts.py extracting messages from app\api\roles.py extracting messages from app\api\tokens.py extracting messages from app\api\users.py extracting messages from app\utils\decorator.py extracting messages from app\utils\elasticsearch.py extracting messages from app\utils\email.py extracting messages from app\utils\tasks.py writing PO template file to messages.pot
运行完命令后,就在当前目录中生成了名为 messages.pot
的文件,内容类似如下:
# Translations template for PROJECT. # Copyright (C) 2019 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # FIRST AUTHOR <EMAIL@ADDRESS>, 2019. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2019-04-19 22:16+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.6.0\n" #: app/api/users.py:20 msgid "You must post JSON data." msgstr "" #: app/api/users.py:24 msgid "Please provide a valid username." msgstr "" #: app/api/users.py:27 msgid "Please provide a valid email address." msgstr "" #: app/api/users.py:29 msgid "Please provide a valid password." msgstr "" #: app/api/users.py:32 msgid "Please use a different username." msgstr "" #: app/api/users.py:34 msgid "Please use a different email address." msgstr ""
(3).po
有了 messages.pot
模板文件后,就可以翻译到各种语言的 .po
文件,比如要翻译为中文,则执行如下命令:
(venv)$ pybabel init -i messages.pot -d app/translations -l zh creating catalog app/translations\zh\LC_MESSAGES\messages.po based on messages.pot
这将会在当前目录下生成名为 translations
的翻译目录,它的子目录中存在 messages.po
文件,然后你需要做的就是将英文翻译成对应的中文即可:
0 条评论
评论者的用户名
评论时间暂时还没有评论.