Python の軽量な Webアプリケーション フレームワーク として有名な Flask。
この Flask を使うと たった一ひとつのソースファイルで簡単に Webアプリケーション を作成できる。
Flask では Jinja2 というテンプレートエンジンを採用している。
通常はテンプレートソースを .html ファイルにテンプレートソースを書き出して ファイル名を指定してそのテンプレートを読み出すのだが、 flask.render_template_string を使えば Python ソースコード上で定義した テンプレート文字列 を使うことができる。
しかし、 extends ステートメントや include ステートメントを使ってレイアウト用などのテンプレートを呼び出す際に、 そのテンプレートを ファイル名 で指定する方法の情報しか出てこない。
これでは、 ひとつのソースファイルで記述できない。
テンプレートソース文字列 を使ってテンプレートの継承を行う方法を、メモがてらまとめておく。
以下のサンプルは Flask を使ったものだが、 Django で Jinja2 を使用した場合も同じように対応できると思われる。
サンプル実装
extends タグ や include ステートメント では、 与えられた文字列のテンプレートファイルをテンプレートローダーが探し出して、 テンプレートの継承関係を解決する仕組みになっている。
Jinja のドキュメントには書かれていないが、 文字列ではなく Jinja の Template オブジェクト を与えると、そのテンプレートをそのまま使ってくれるようだ。
つまり、 あらかじめ Template オブジェクトを作成しておいて、 それを jinja_env.globals
や render_template_string
のキーワード引数によってテンプレート内の引数に渡し、 最終的に extends タグに渡るようにすればよいのだ。
サンプルコードは以下の通り。
これを実行して http://localhost:5000/ にアクセスすると、以下のようになるはずだ。
extends
タグや include
ステートメントに渡しているパラメータが、 文字列ではなくて変数名であること注目して欲しい。
ポイントとしては、 共通で使うレイアウト用のテンプレートオブジェクトを、 before_first_request
のタイミングで最初のリクエストが処理される前に一度だけ作成していること。
同じ文字列であればキャッシュされる flask.render_template_string
とは異なり、 キャッシュ機能のない Jinja2 の from_string
API を 毎リクエスト で呼び出すのは効率が悪いためだ。
ピンバック: Pydroid で オフライン&セルフホスト の Web アプリを動かす | Aqua Ware つぶやきブログ