获取本文的示例代码,点击这里
1. 安装使用flask-babel
flask插件flask-babel可以很方便的帮助我们实现国际化(i18n)。包括语言文字,时区,时间日期,数字,货币等。
使用pip安装flask-babel插件:
$ pip install flask-babel
构建一个最简单的flask web应用程序:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def create_app():
app = Flask(__name__)
app.config.from_object('app.config')
init_babel(app)
return app
def init_babel(app):
babel = Babel(app)
@babel.localeselector
def get_locale():
return 'zh'
@babel.timezoneselector
def get_timezone():
return 'UTC'
- config.py文件是flask框架将要使用的配置文件,在这里面可以做flask以及flask-babel等插件的配置
- 可以在config.py里通过设置BABEL_DEFAULT_LOCALE和BABEL_DEFAULT_TIMEZONE来指定babel默认使用的语言和时区
- 也可以使用localeselector和timezoneselector两个装饰器申明babel使用的默认语言以及时区选项, 需要注意的是,这两个装饰器的设置将会覆盖config.py里的设置
- localeselectort和timezoneselector装饰的函数,被调用一次之后就会缓存,可以在业务代码中使用refresh()清除缓存
- localeselectort和timezoneselector装饰的函数实质上是向Babel()对象中添加locale_selector_func和timezone_selector_func两个成员,然后由babel框架回调实现最终的设置
2. 语言文字翻译
flask-babel通过封装gettext(),ngettext()以及lazy_gettext()方法实现文字翻译功能。
gettext和ngettext是为英文中单数和复数时名词后加s翻译到其它语言时使用的
lazy_gettext和gettext的区别在于,lazy_gettext只有在文字被使用的时候,才会被翻译
这里有有以下两个路由:
1
2
3
4
5
6
7
@app.route('/hello')
def hello():
return gettext('hello, China')
@app.route('/')
def index():
return render_template('index.html')
并且有模板文件index.html:
1
2
3
<!DOCTYPE html>
<h1>{ { _('Test Sample') }}</h1>
<h1>{ { _('Hello World!') }}</h1>
- 在模板文件中,也可以使用gettext(), 这里使用‘_’代替
利用flask-babel翻译文字步聚:
2.1 创建babel.cfg文件,并在里面加入:
1
2
3
[python: **.py]
[jinja2: **/templates/**.html]
extensions=jinja2.ext.autoescape,jinja2.ext.with_
- 这段的主要意思是告诉pybabel从当前目录以及子目录下所有.py文件和templates/及其子录下所有.html文件里抽取所有需要被翻译的文字,即被gettext(), ngettext()以及_()方法传入的文字
2.2 在项目根目录下,使用下面的命令生成messages.pot文件
$ pybabel extract -F babel/babel.cfg -o babel/messages.pot app
- 这里要注意的是-F和-o后接的路径是运行pybabel命令的当前路径的相对路径,而最后的app这个参数则是告诉pybabel命令去哪里找**.py和**/templates/**.html文件
如果还需要翻译lazy_gettext传入的语言,可以在上面命令基础上使用-k参数:
$ pybabel extract -F babel/babel.cfg -k lazy_gettext -o babel/messages.pot app
在生成的messages.pot里,你可以看到所有使用类似于gettext()传递的参数,都出现在了msgid中。
2.3 创建文字对应的.po文件
使用命令
$ pybabel init -i babel/messages.pot -d app/translations -l zh
会将中文翻译文件放在translations/zh/LC_MESSAGES下,命名为messages.po。
- 这里需要注意的是translations目录一定要和Flask对象app在同一级目录,否则翻译不会生效
2.4 翻译语言
在messages.po文件里,将每段文字的对应翻译放在msgstr中。
2.5 编译生成.mo文件
使用命令
$ pybabel compile -d app/translations
编译.po文件生成相应的.mo文件,flask-babel最终也是使用.mo文件。在服务器中设置语言为zh,重启服务器,访问对应的url就可以看到中文网页了。
2.6 增量更新messages.po文件
如果代码中需要翻译的文字有变化,使用命令
$ pybabel update -i messages.pot -d app/translations
可以在原来已经翻译好的.po文件基础上动态更改,而不会像pybabel init一样将之前辛苦翻译的.po文件内容全部丢掉。
3. 格式化时间日期
假如有如下路由
1
2
3
4
@app.route('/time')
def time():
from flask_babel import format_datetime
return format_datetime(datetime.now())
在语言为’zh’时,返回结果是:2019年5月5日 下午10:56:04
当语言为’en’时,返回结果是:May 5, 2019, 10:54:17 PM
format_datetime()方法还可以带一个格式参数,用来定义输出的时间日期的样式,如’dd mm yyyy’。
4. 其它格式化
flask-babel还提供了一些其它常用的格式化方法,如
- format_currency: 格式化货币
- format_percent: 格式化百分比
- format_decimal: 格式化数字
等,可以自行尝试。