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」的方法等