Flask + jinja でレイアウトの指定 (extends タグ) のテンプレートを ソースコード文字列 で指定する

Pocket

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.globalsrender_template_string のキーワード引数によってテンプレート内の引数に渡し、 最終的に extends タグに渡るようにすればよいのだ。

サンプルコードは以下の通り。

これを実行して http://localhost:5000/ にアクセスすると、以下のようになるはずだ。

extends タグや include ステートメントに渡しているパラメータが、 文字列ではなくて変数名であること注目して欲しい。

ポイントとしては、 共通で使うレイアウト用のテンプレートオブジェクトを、 before_first_request のタイミングで最初のリクエストが処理される前に一度だけ作成していること。
同じ文字列であればキャッシュされる flask.render_template_string とは異なり、 キャッシュ機能のない Jinja2 の from_string API を 毎リクエスト で呼び出すのは効率が悪いためだ。

Flask + jinja でレイアウトの指定 (extends タグ) のテンプレートを ソースコード文字列 で指定する” への1件のコメント

  1. ピンバック: Pydroid で オフライン&セルフホスト の Web アプリを動かす | Aqua Ware つぶやきブログ

コメントを残す

メールアドレスが公開されることはありません。