pip install flask-babelhtml
先初始化一个Flask-Babel的实例python
from flask import Flask from flask.ext.babel import Babel app = Flask(__name__) babel = Babel(app)
Flask-Babel提供了两个Flask应用配置项:flask
app.config.update( DEBUG=True, BABEL_DEFAULT_LOCALE='zh' )
当程序里没指定时,就会采用这些默认设置。那么如何在程序里指定呢?Flask-Babel提供了两个装饰器”localeselector”和”timezoneselector”,分别用来设置语言和时区:缓存
@babel.localeselector def get_locale(): return 'zh' @babel.timezoneselector def get_timezone(): return 'UTC'
这里的设置将会覆盖应用配置项中”BABEL_DEFAULT_LOCALE”和”BABEL_DEFAULT_TIMEZONE”。上面的程序不是个好例子,常见的状况是从当前用户会话中,或者从服务器环境中获取语言/时区设置。服务器
装饰器”localeselector”和”timezoneselector”修饰的函数,被调用一次后就会被缓存,也就是不会被屡次调用。可是有时候,当切换用户时,咱们想重新用户会话中从新获取语言/时区设置,此时能够在登陆请求中调用”refresh()”方法清缓存:babel
from flask_babel import refresh @app.route('/login') def login(): ... # Get new user locale and timezone refresh() ... # Render response
Flask-Babel封装了Python的”gettext()”方法,你能够在视图函数中使用它:app
from flask_babel import gettext, ngettext @app.route('/trans') @app.route('/trans/<int:num>') def translate(num=None): if num is None: return gettext(u'No users') return ngettext(u'%(num)d user', u'%(num)d users', num)
Flask-Babel还提供了”lazy_gettext()”方法,它的做用同”gettext()”相似,区别是它在文字被使用时才会被翻译,因此能够用来在上下文环境外定义要翻译的文字,好比:函数
from flask_babel import lazy_gettext hello = lazy_gettext(u'Hello World') @app.route('/lazy') def lazy(): return unicode(hello)
一样在模板中,咱们也可使用”gettext()”方法,更简单的咱们能够用”_()”方法代替:测试
<!doctype html> <title>{{ _('Test Sample') }}</title> <h1>{{ _('Hello World!') }}</h1>
在Flask请求中,咱们来渲染此模板:spa
@app.route('/') def index(): return render_template('hello.html')
启动应用,访问上面的视图,验证下程序是否正常运行。你们应该能够看到”gettext()”方法里的文字被显示出来了,目前尚未被翻译。
Babel中的”pybabel”命令来建立翻译文件
[python: **.py] [jinja2: **/templates/**.html] extensions=jinja2.ext.autoescape,jinja2.ext.with_
这个文件告诉”pybabel”要从当前目录及其子目录下全部的”*.py”文件,和templates目录及其子目录下全部的”*.html”文件里面搜寻可翻译的文字,即全部调用”gettext()”,”ngettext()”和”_()”方法时传入的字符串。同时它告诉”pybabel”,当前Jinja2模板启用了autoescape和with扩展。
pybabel extract -F babel.cfg -o messages.pot . 打开”messages.pot”,你会发现,上例中”No users”, “Test Sample”等文字都出如今”msgid”项中了,很强大吧。参数”-F”指定了Babel配置文件;”-o”指定了输出文件名。
首先记得将”messages.pot”中的”#, fuzzy”注释去掉,有这个注释在,将没法编译po文件。而后修改里面的项目信息内容如做者,版本等
pybabel init -i messages.pot -d translations -l zh
打开刚才生成的中文po翻译文件,将咱们要翻译的内容写入”msgstr”项中,并保存:
#: flask-ext3.py:31 msgid "No users" msgstr "没有用户" #: flask-ext3.py:32 msgid "%(num)d user" msgid_plural "%(num)d users" msgstr[0] "%(num)d个用户" #: templates/hello.html:2 msgid "Test Sample" msgstr "测试范例" #: templates/hello.html:3 msgid "Hello World!" msgstr "世界,你好!"
pybabel compile -d translations
pybabel update -i messages.pot -d translations
Flask-Babel不只能够翻译文字,还能够自动翻译日期格式,运行下面的例子:
from flask_babel import format_datetime from datetime import datetime @app.route('/now') def current_time(): return format_datetime(datetime.now())
假设当前系统时间是”2016-3-20 11:38:32″,在locale是en的状况下,会显示”Mar 20, 2016, 11:39:59 AM”;而在locale是zh的状况下,会显示”2016年3月20日 上午11:38:32″。
“format_datetime()”方法还能够带第二个参数指定输出格式,如”full”, “short”, “yyyy-MM-dd”等
Flask-Babel提供了”format_number”和”format_decimal”方法来格式化数字,使用方法同上例中的”format_datetime”很是相似,只需传入待格式化的数字便可:
from flask.ext.babel import format_decimal @app.route('/num') def get_num(): return format_decimal(1234567.89)
上面的数字,在locale是en的状况下,会显示”1,234,567.90″;而在locale是de的状况下,会显示”1.234.567,89″。
既然能够格式化数字,天然也少不了货币格式化显示的功能了。咱们可使用”format_currency”方法,它同”format_decimal”的区别是它必须传入两个参数,第二个参数指定了货币类型:
from flask_babel import format_currency @app.route('/currency') def currency(): return format_currency(1234.5, 'CNY')
上面的数字”1234.5″,在类型(即第二个参数)是”CNY”的状况下,会显示”¥1,234.50″;而在类型是”USD”的状况下,会显示”US$1,234.50″。
Flask-Babel还提供了格式化百分数”format_percent”,和格式化科学计数”format_scientific”的方法等