Flask-Babelメモ

hgwebcommitのi18nでFlask-Babelを使ったのでメモ。
Flask-BabelはFlaskのBabelヘルパー。
Flask-Babel — Flask Babel 1.0 documentation

インストール

pip install Flask-Babel

flaskext.babelを使えるようになる。

Flask-Babelをアプリケーションに適用する

applicationからBabelオブジェクトを作る
Flaskのインスタンスを引数にしてBabelのインスタンスを作っておく。
babelオブジェクトのデコレータメソッドでlocaleを取得するように書く。

# coding:utf-8
from flask import Flask, g, request
from flaskext.babel import Babel

app = Flask(__name__)
app.config.from_pyfile('mysettings.cfg')

babel = Babel(app) # Babelオブジェクトを作っておく

@babel.localeselector
def get_locale():
    # この場合はブラウザのAccept Languagesを見るようになっている。
    return request.accept_languages.best_match(['ja', 'ja_JP', 'en'])

if __name__ == '__main__':
    # 開発サーバ起動など以下略

これで言語の自動切替が有効になった。

翻訳対象のテキストでgettextを使うように変更する

翻訳対象の部分ではgettext/ngettextやgettext_lazyを使う。

from flaskext.babel import gettext
# from flaskext.babel import gettext as _ # こうするのもありかも

@app.route('/')
def index():
    return gettext('hello world!')

# モジュールロード時に実行される部分などはgettext_lazyを使う
HELLO_MESSAGE = gettext_lazy('hello!')

@app.route('/hello')
def hello():
    return HELLO_MESSAGE

Jinjaテンプレートのほうでもgettextを使えるようになっている。

<p>
  message: {{ gettext('Hello world!') }}
</p>

翻訳用のファイルを作成する

Babelのpybabelコマンドで翻訳対象のテキストを抽出する。
まずは、pybabelの設定babel.cfgを作成する。

[python: **.py]
[jinja2: **/templates/**.html]
extensions=jinja2.ext.autoescape,jinja2.ext.with_

pybabelコマンドで各言語の翻訳ファイルの元となるテンプレートのpotファイルを作成する。

$ pybabel extract -F babel.cfg -k lazy_gettext -o messages.pot .

作成したpotファイルから各言語の翻訳ファイルを作成する。
初回はinitで作成する。

$ pybabel init -i messages.pot -d translations -l ja

これで翻訳用のmessages.poファイルが作成される。
poファイルの翻訳が終わったらコンパイルする。

$ pybabel compile -d translations

これで実行時に使用するmessages.moができる。fuzzyマークされているとスキップされるので注意する。

更新する場合

gettextの対象が増えた場合は、pybabel extractを実行後、各言語のpoファイルを更新する。

$ pybabel update -i messages.pot -d translations

更新したpoを編集して再度pybabel compileでmoファイルを作成する。
Acceptヘッダによる切り替えの確認は、FirefoxのQuick Locale Switcherなどを使うと簡単。