Flask Vue.js全栈开发|第19章:国际化

  • 原创
  • Madman
  • /
  • /
  • 0
  • 3296 次阅读

flask vuejs 全栈开发-min.png

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 安装

(venv)$ pip install flask-babel
(venv)$ pip freeze > requirements.txt

会同时安装另外两个模块:

  • Babel: Python 支持国际化的模块
  • pytz: 支持本地时区的模块

1.2 配置

修改 back-end/config.py

LANGUAGES = ['zh', 'en']

修改 back-end/app/extensions.py

from flask_babel import Babel
...

# Flask-Babel plugin
babel = Babel()

修改 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 头部 指定了客户端语言和区域设置首选项,该头部的内容可以在浏览器的首选项页面中配置,默认情况下通常从计算机操作系统的语言设置中导入,比如我的:

Accept-Language: zh-CN,zh;q=0.9,en;q=0.8

总之,上面的 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 用的地方太多,为了简便,将它重命名为 _

如果要翻译有格式化符号的字符串,比如:

'You are now following %s.' % username

则需要使用如下语法:

_('You are now following %(username)s.', username=username)

注意: 在 .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

[python: madblog.py]
[python: app/**.py]

(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 文件,然后你需要做的就是将英文翻译成对应的中文即可:

# Chinese translations for PROJECT.
# Copyright (C) 2019 ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2019.
#

                                
                            
未经允许不得转载: LIFE & SHARE - 王颜公子 » Flask Vue.js全栈开发|第19章:国际化

分享

作者

作者头像

Madman

如需 Linux / Python 相关问题付费解答,请按如下方式联系我

0 条评论

暂时还没有评论.

专题系列