よちよちpython

独習 python/Qpython/Pydroid3/termux/Linux

テンプレートエンジンとは何か?Jinja2の基本2

前回
テンプレートエンジンとは何か Jinja2の基本1 - よちよちpython
に引き続き、テンプレートエンジンJinja2の基本的使用法について見ていきます。



実行環境


Androidスマホ
termux
Python3.7
JupyterNotebook



目次




Jinja2のテンプレートの基本的構文


テンプレートファイルは次の構文に沿って書きます。



記法 説明
{% ... %} statements 文、宣言・命令等
{{...}} expressions 式
{#...#} comments コメント
#...## line statements 行ステートメント


書き忘れていたが、テンプレートファイルの拡張子は何でもOK。html言語のテンプレートなら.html、またはテンプレートだと分かるように.tplにしたり.j2にしたり、好きに決めてよいそうです。



では、上の表を順に見ていきます。

statements ステートメント


{% ... %}で括ってその中に変数を定義したりif文やfor文などのプログラム文を書きます。

statements 変数の定義


setを使うとテンプレート内で使用する変数を定義できる。
変数number=1と定義する場合は

{% set number=1 %}

statements if文


if文で条件分岐ができます。
ifelifelsePythonと同じだが、コロン(:)が不要なことと、最後にendifを書いて条件分岐制御の文を終了させるところが違う。


例)

{% if x < 0 %}
xはゼロより小さい。

{% elif x == 0 %}
xはゼロ。

{% else %}
xはゼロより大きい。

{% endif %}

statements for文


for文で繰り返し。これもPythonとほとんど一緒だが(:)コロンが不要で、最後にendforで終わらせる。



例)
{% for i in x_list %}
{{ i }}
{% endfor %}

statements rawブロックでエスケープ


{% raw %}と{% endraw %}で挟まれたブロックな部分は全て文字として扱われて表示されます。
例えばPython\nと文字列表示させたいが自動的に改行されるのを防ぐ為に\\nエスケープさせるようなのと同じ。



例)

{% if item == 1 %}
1です。
{% endif %}


と文字列で表示させたい。そのまま書くとif文として扱われるのでrawブロックで挟んでエスケープさせ文字列表示させる。


{% raw %}
{% if item == 1 %}
1です。
{% endif %}
{% endraw %}

expressions 式


テンプレート内の{{ 変数 }}が、アプリケーションから渡された変数の値に置き換わって出力される。



テンプレートファイルとアプリケーションのPythonファイルを作り、アプリケーションを実行させてみます。
(%%!はJupyterNotebookでのマジックコマンドやコマンド実行の文)

%%writefile test_template.tpl

吾が輩は{{name}}である。
Writing test_template.tpl
%%writefile test_app.py

from jinja2 import Template, Environment, FileSystemLoader
 
env = Environment(loader=FileSystemLoader('.'))
template = env.get_template('test_template.tpl')
 
data = {'name': '犬'}
text = template.render(data) 
print(text)
Writing test_app.py
!python test_app.py
吾が輩は犬である。

アプリケーション側のdataという辞書型変数のnameに対応したvalueがrenderメソッドを通すことでテンプレートに渡された。



comments コメント


{# コメント #}でテンプレートファイル内にコメントを書くことができる。この部分は出力されない。



line statements 行ステートメント


line_statement_prefixを指定するとブロックの記述方法を変更することができる。
{% for i in numbers %}などと書いていたのを# for i in numbersとか自在に変形できるんだと。新しい言語を作ってるみたいで凄いね。

本当にそんな事ができるのか、テンプレートファイルとPythonファイルを作って確かめます。

%%writefile line_statements_test.tpl

💩 for member in members 
{{ member }}
💩 endfor 
Overwriting line_statements_test.tpl
%%writefile app_line_statements_test.py

from jinja2 import Template, Environment, FileSystemLoader
 
env = Environment(loader=FileSystemLoader('.'))

# ステートメントブロックの表記法変更
env.line_statement_prefix = '💩'

template = env.get_template('line_statements_test.tpl')
 
member_data = {'members': ['物部','大伴','蘇我']}
n_text = template.render(member_data) 
print(n_text)
Overwriting app_line_statements_test.py
!python app_line_statements_test.py
物部
大伴
蘇我

この子はできる子。



if文でも試してみる。ファイル名そのままで上書きする。

%%writefile line_statements_test.tpl

(-_-) if num < 5
5未満である。
(-_-) else
5より大きいと言えよう。
(-_-)endif
Overwriting line_statements_test.tpl
%%writefile app_line_statements_test.py

from jinja2 import Template, Environment, FileSystemLoader
 
env = Environment(loader=FileSystemLoader('.'))

# ステートメントブロックの表記法変更
env.line_statement_prefix = '(-_-)'

template = env.get_template('line_statements_test.tpl')
 
member_data = {'num': 7}
n_text = template.render(member_data) 
print(n_text)
Overwriting app_line_statements_test.py
!python app_line_statements_test.py
5より大きいと言えよう。

なんでもありやね。



おわりに


ここまで、先頭に挙げた表の4つのテンプレート構文の超基本的な使い方を見てきた。
Jinja2はあらゆる形式とタイプの記法、文章、レイアウトに対応できる非常に多量のドキュメントで構成されている。Jinja2公式サイトを見ると目眩がしてくる。Djangoで挫折するという噂はこの辺りにも理由があるのか。踏み込むと土坪にハマリそうなのでほどほどにしておきたい。次回はもう少しだけ足を踏み入れる。
Pythonのアプリケーション側も同時に見ていかないと分かりにくいので、それをやろう。

参考


Jinja — Jinja Documentation (2.10.x)

jinja2入門 その2 - Python学習講座