テンプレートエンジン - 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 の言うことなのでホントかどうかは知らない。