Skip to main content

テンプレートエンジン - Jinja2

なにをするもの?

テンプレートファイルを用意しておいて、{{ .. }} の部分を置き換えるもの。

templates/test-template.j2
タイトルは [ {{ title }} ] です。
著者は [ {{ author }} ] です。

出力例
タイトルは [ 方丈記 ] です。
著者は [ 鴨長明 ] です。

インストール

bash
pip install jinja2

コードからの呼び出しかた

py
from jinja2 import Environment, FileSystemLoader

script_dir = os.path.dirname(os.path.abspath(__file__))
template_dir = os.path.join(script_dir, 'templates')

env = Environment(
loader=FileSystemLoader(template_dir),
autoescape=False
)

template = env.get_template('test-template.j2')

r = template.render(
title='方丈記', # ← ★ ここの変数名がテンプレート内で置換される名前となる
author='鴨長明'
)

print(r)

ディクショナリのメンバ

j2
タイトル : {{ book.title }}
py
r = template.render(
book={ 'title': '方丈記', 'author': '鴨長明' }
)

繰り返し

j2
{% for title in titles -%}
タイトル : {{ title }}
{%- endfor %}
py
template.render(
titles=['方丈記', '徒然草', '枕草子']
)
  • -%} のようにマイナスをつけると改行を付与しない -%}
    • ので通常は、マイナスつきにする感じか
    • {%- .. -%} 両方つけたら1行にまとまる

繰り返し - sort あり

j2
{% for book in books | sort(attribute='year') -%}
{{ book.year }}年 - 『{{ book.title }}』 ({{ book.author }})
{%- endfor %}
py
books = [
{ 'title': '枕草子', 'author': '清少納言' , 'year': 1000 },
{ 'title': '方丈記', 'author': '鴨長明' , 'year': 1200 },
{ 'title': '徒然草', 'author': '兼好法師' , 'year': 1300 },
]
r = template.render(
books=books
)

・・のように、テンプレート側で並べ替えることもできるが、
こういう場合は おとなしく Python 側でやれば良い。

py
books = sorted(books, key=lambda x: x['year'])

変換する - filter

  • Jinja2 の「フィルタ」とは、値の変換をするもの
  • 先の sort は組み込みのフィルタ

たとえば、book オブジェクトを、 JSON で整形したものを出力したい場合

j2
データ : {{ book | tojson }}
  • このように書くと、あらかじめ定義した tojson という名前のフィルタが呼ばれる
  • tojson は ここでテキトウにつけた名前で、使う側と合わせていれば何でも良い
py
env.filters['tojson'] = lambda value: json.dumps(value, ensure_ascii=False, indent=2, sort_keys=True)
...
r = template.render(
book={ 'title': '方丈記', 'author': '鴨長明' }
)
出力例
データ : {
"title": "方丈記",
"author": "鴨長明"
}

エスケープ : {{ を出したいときはどうしたら・・。

j2
{{ '{{' aaa '}}' }}
j2
{% raw -%}
{{ aaa }}
{%- endraw %}

余談

Jinja という名前は、

Template → Temple → 神社 → Jinja

みたいな感じか。でもそれだと Shrine になっちゃうか・・などと思ったら

Jinja2 の開発者である Armin Ronacher 氏が日本を訪れた際、日本文化に触れてインスパイアされ、

ということらしい。 ChatGPT の言うことなのでホントかどうかは知らない。