Flaskでテンプレートディレクトリを指定する
動機
PythonにはFlaskというRubyでいうsinatraライクなマイクロフレームワークがあり、こいつのテンプレートエンジンにはJinja2というPHPでいうSmartyライクなテンプレートエンジンが使われている。
で、Flaskでユニットテストを書いていた時に本番環境とテスト用のディレクトリ分けたいと思った。
というのはディレクトリ構造同じにしておいて期待通りのテンプレートがちゃんとレンダリングされてればいいかぐらいのノリだったため。
Jinja2から直接テンプレートディレクトリを指定する
ググってもやはり日本語情報は引っかからなかったのと公式ドキュメントとりあえず10分ほど探してみても見つからないということで、とりあえずついったーに投げたら反応あるかもという他力本願全開で投げたらid:shimizukawaさんからレスを頂いた(id:shimizukawaさん情報ありがとうございました!)
id:shimizukawaさんから頂いた案としては以下。
from jinja2 import Environment, FileSystemLoader env = Environment(loader=FileSystemLoader('templates')) template = env.get_template('index.html') template.render()
ただid:shimizukawaさんもFlask側から設定する方法は分からない、分かったら教えてほしいということだったのでこの情報を基に調べてみることに。
Flask側からテンプレートディレクトリを指定する
調べるやいなや公式ドキュメントのAPIの章に思いっきり書いてあった・・・
使い方はflaskインスタンスのjinja_loader属性にFileSystemLoader('hoge_dir')みたいな感じで割り当ててやればよい。
例は以下。
2010/11/9 修正
id:shimizukawaさんから
app = FileSystemLoader('hoge_dir')
だとappを上書きしていると指摘を受けたので修正しました。
app.jinja_loader = FileSystemLoader('hoge_dir')
ここでのappという変数はflaskインスタンス(チュートリアルのコードと同じ)
そしてview関数の方は元々あるFlask.render_template()関数を呼び出す
@app.route("/") def index(): from flask import render_template return render_template('index.html')
もうちょっと全体が見えるように書いたのが以下。
from flask import Flask from jinja2 import FileSystemLoader app = Flask(__name__) app.jinja_loader = FileSystemLoader('hoge_dir') @app.route("/") def index(): from flask import render_template return render_template('index.html')
これで割とすっきりしたかなと思う。
ただ、テスト時にはテンプレートのディレクトリは変えてやらないといけない事にご注意を。
でもまあloaderの存在は知らなかったので教えてもらわなかったら未だにドキュメントと格闘していたかもしれない。
全体のソースコード
コード片じゃ分かりにくと思うのでサンプルコードをユニットテスト付きでZIP公開。
http://d.hatena.ne.jp/aroma_black/files/yourapplication.zip?d=download
不満点
flask.config.form_object()メソッドみたいにさくっと出来たらいいなと思った。
そうすれば設定ファイルが全部外だし出来るし。
これはそのうち・・・