Pythonのテンプレートエンジン Jinja2
PythonのJinja2についてのメモ
インストール
pipまたはパッケージシステムで。自分はMsys2環境なのでpacman
でインストール
% pacman -S mingw-w64-x86_64-python-jinja
pipの場合は
% pip install jinja2 # Windows
% sudo pip3 install jinja2 # Linux
テンプレートの読み込み方法
直接文字列を指定
jinja2.Template
クラスのコンストラクタに文字列を渡すことでテンプレートの作成が可能です。ちなみにJinja2はUTF-8しかサポートしていないようです
from jinja2 import Template
# 文字列からテンプレートを作成
template = Template('My name is {{name}}')
txt = template.render(name='Nanashi')
print(txt)
My name is Nanashi
ファイルから読み込み
jinja2.Environment
クラスを作成し、そこからファイルを読み込みます
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader(searchpath=['python']))
template = env.get_template('test.j2')
txt = template.render(name='Gonbei')
print(txt)
My name is Gonbei
FileSystemLoader
のsearchpath
引数にはファイルを検索するパスを指定可能です
テンプレート記述方法
デリミタ
テンプレートテキストの中でJinja2のテンプレートエンジンで処理される特別な意味を持つ箇所 (デリミタ)は以下の4つです
{% ... %}
for Statements (if文やforループなど){{ ... }}
for Expressions (変数の値で置換){# ... #}
for Comments (コメント。出力には含まれない)# ... ##
for Line Statements (Statementsの簡易記法。有効化が必要)
if文
{% if ... %}
により変数による出力切り替えが可能です
My name is {{name}}
{% if gender == 'male' %}
I am a man
{% else %}
I am a woman
{% endif %}
txt = template.render(name='Gonbei', gender='male')
print(txt)
My name is Gonbei
I am a man
for文
{% for ... %} ... {% endfor}
により、ブロック内のテキストを繰り返し生成することが可能です
{% for person in members %}
My name is {{person.name}}.
{%- if person.gender == 'male' %}
I am a man
{%- else %}
I am a woman
{%- endif %}
{% endfor %}
class Person:
def __init__(self, name, gender):
self.name = name
self.gender = gender
env = Environment(loader=FileSystemLoader(searchpath=['python']))
template = env.get_template('test.j2')
txt = template.render(members=[Person('Mike', 'male'),
Person('Nancy', 'female')])
print(txt)
My name is Mike.
I am a man
My name is Nancy.
I am a woman
{%-
と-
を付加しているため、前後の改行が削除されて出力されています
マクロ
マクロを定義して、繰り返し出てくる記述を簡略化することができます
{% macro print_person(name, gender) -%}
- Name: {{name}}, Gender: {{gender}}
{%- endmacro %}
{% for person in members -%}
{{print_person(person.name, person.gender)}}
{% endfor %}
class Person:
def __init__(self, name, gender):
self.name = name
self.gender = gender
env = Environment(loader=FileSystemLoader(searchpath=['python']))
template = env.get_template('test.j2')
txt = template.render(members=[Person('Mike', 'male'),
Person('Nancy', 'female')])
print(txt)
- Name: Mike, Gender: male
- Name: Nancy, Gender: female
Call
call
を使用することで、マクロにブロックを挿入することができます。マクロのブロックを挿入したい箇所でcaller()
を呼び出します
{% macro print_person_desc(name, gender) -%}
- Name: {{name}}, Gender: {{gender}}
{{caller()}}
{%- endmacro %}
{% for person in members %}
{% call print_person_desc(person.name, person.gender) -%}
**{{person.description}}**
{%- endcall %}
{% endfor %}
class Person:
def __init__(self, name, gender, description=None):
self.name = name
self.gender = gender
self.description = description
env = Environment(loader=FileSystemLoader(searchpath=['python']))
template = env.get_template('test.j2')
txt = template.render(members=[Person('Mike', 'male', 'I like orange'),
Person('Nancy', 'female', 'I like apple')])
print(txt)
- Name: Mike, Gender: male
**I like orange**
- Name: Nancy, Gender: female
**I like apple**
最近のコメント