よちよちpython

独習 python/Qpython/Pydroid3/termux/Linux

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

はじめに


Webフレームワークを扱うときに登場するテンプレートエンジンとは何者なのか。

そもそもテンプレートとは何か。
これだ!

f:id:chayarokurokuro:20191023222711j:plain


(ステッドラー日本さまより拝借)

コンピュータ用語では

テンプレートは、文書などのコンピュータデータを作成する上で雛形となるデータ。 最も抽象的なテンプレートは、レイアウトのみのデータで、テキストを流し込むことでレイアウトつき文書となる。具象的なテンプレートは、それ自体文書であり、数箇所の修正または空白への書き込みで目的の文書となる。


テンプレートエンジンは、テンプレートから文書を作る工程を自動化したソフトである。テンプレートに対し、テンプレートに埋め込むデータをデータモデルという。 (Wikipediaより)

とのこと。定型的な文書やフォーマットがテンプレートで、そこに差し込む値がデータモデルと思っていいんだろうか。そういうことにしとこ。



ぶっちゃけ、どこまでがテンプレートエンジンで、どこからがWebフレームワークの機能なのかよく分からんので、テンプレートエンジン単体の機能に焦点を当てて見ていこうというのが今回から数回にわたる予定の投稿の趣旨でござんす。

実行環境


Androidスマホ
termux
Python3.7
JupyterNotebook



※ 実行環境がスマホばかりでブログを投稿しているが、特にこだわっているとか取り憑かれているわけではありません。携帯していつでもどこでも書けるので。



目次




PythonでWebフレームワークを扱う時に「テンプレートエンジン」が頻繁に登場する。よく目にするものではjinja2makogenshiなど。超高速処理だとかXmlライクな構文でだとか、それぞれ売りや特徴があるようです。



こちらのサイトではテンプレートエンジンの比較がされています。
https://www.cmscom.jp/blog/af0ga8



Jinja2を見ていく


ここからは、Flaskの標準テンプレートエンジンで、ドキュメントビルダーSphinxで使われていて、Djangoのテンプレと同じ構文(DjangoからJinja2を作ったらしい)、htmlやxmlの他、markdownソースコード等どのような文章でも生成可能だというPython用テンプレートエンジンJinja2を教材にして使い方を見ていきます。



こちらを参考にさせて頂きます。
https://www.python.ambitious-engineer.com/archives/760

jinja2のインストール


jinja2は標準ライブラリではないので、先に pip install jinja2 でインストールしておきます。(Flaskをインストールしてあれば不要)


文字列テンプレートオブジェクトの{{変数}}にデータを埋め込む


Jinja2の基本的な使い方。

from jinja2 import Template
 
tpl_text = 'お茶会のおしらせ\n\n{{ name }}様\n\n {{ day }}にお茶会を開催致します。ご家族揃ってご参加下さい。'
template = Template(tpl_text)
 
data = {'name': '茶屋', 'day': '11月11日'}
disp_text = template.render(data) # 辞書で指定する
print(disp_text) 
お茶会のおしらせ

茶屋様

 11月11日にお茶会を開催致します。ご家族揃ってご参加下さい。

テンプレート文章tpl_textの二重波カッコ内の変数が、辞書型データdataのキーになっている。
テンプレート文章の変数をTemplateクラスに渡してインスタンス変数にし、renderメソッドにそのまま辞書型データを渡すだけでバリューがテンプレート文章の中の変数に格納されて表示された。



jinja2を使わず書くと…

data = {'name': '江崎', 'day': '11月11日', 'whatday': 'ポッキーとプリッツ'}

name=data["name"]
day=data["day"]
whatday=data["whatday"]

text = 'ねえねえ{0}さん、{1}は何の日か知ってる?\n{2}の日よ!'.format(name, day, whatday)

print(text)
ねえねえ江崎さん、11月11日は何の日か知ってる?
ポッキーとプリッツの日よ!

慣れているこちらの方が簡単に思える。

では、わざわざテンプレートエンジンを使うメリットとは何だろう?

たぶんテンプレートエンジンの真骨頂はここからだ。
「テンプレート」であるのでそれを別ファイルで用意して、制御するプログラムやデータを切り離して使えてスッキリ。
Excelで請求書のテンプレシートと請求データのシートを分けて作り、マクロで動かして顧客ごとに伝票を作るみたいなことができるようになる。

テンプレートとして切り離すことで、文書の完成予想図に専念できる。テンプレの作り替えも簡単。知らんけど。そしたら次に推定真骨頂を見ていきまひょか。

テンプレート側と制御側を切り離す


ファイルをテンプレートと制御するpyファイルに別けます。
同じフォルダに入れておく。

作業用フォルダの作成


テンプレートとPythonスクリプトの2つのファイルを保存する用のフォルダをマジックコマンドで作る。(JupyterNotebook以外はこのやり方は使えないのであしからず)

%mkdir JINJA2_Folder #フォルダ作成マジックコマンド

テンプレートファイルの作成


今しがた作成したフォルダの中にテンプレファイルをまたマジックコマンドで作ります。

%%writefile ./JINJA2_Folder/jinja2_test.tpl

# {{title1}}
---
{{text1}}

<br><br>
# {{title2}}
---
{{text2}}
Writing ./JINJA2_Folder/jinja2_test.tpl

制御用Pythonファイルの作成


同じく作成したフォルダにpyファイルをマジックコマンドで作成。

%%writefile ./JINJA2_Folder/control_jinja2_test.py

from jinja2 import Template, Environment, FileSystemLoader
 
env = Environment(loader=FileSystemLoader('./JINJA2_Folder'))
template = env.get_template('jinja2_test.tpl')
 
data = {'title1': 'はじめに', 'text1': '序文の文章 うんぬんかんぬん', 'title2': '目次', 'text2': '[:contents]'}     
disp_text = template.render(data) # 辞書で指定する
print(disp_text)
Writing ./JINJA2_Folder/control_jinja2_test.py

treeコマンドでフォルダ構成の確認


作成したフォルダに移動してtreeコマンドでディレクトリ構造を表示する。

※ treeコマンドをMacLinuxやtermux環境で使うにはインストールが必要。WindowsではコマンドプロンプトPowerShellで標準装備、GitBashではTree for Windowsをインストールすれば利用できる。

!cd JINJA2_Folder;tree
 .
├── control_jinja2_test.py
└── jinja2_test.tpl

0 directories, 2 files

JINJA2_Folderというフォルダの中にPythonファイルとテンプレートファイルが作成されたことが確認できた。

制御用Pythonファイルを実行する


ファイルを作ったので、JupyterNotebookからコマンドで実行させます。

!python ./JINJA2_Folder/control_jinja2_test.py
# はじめに
---
序文の文章 うんぬんかんぬん

<br><br>
# 目次
---
[:contents]

お! 上手く動いてくれましたよ、ザーボンさん!



ブログの投稿用markdown形式文章を想定してテンプレートを作った。データ用辞書にupdate関数で見出しのkeyと文章の中身のvalueを追加できるようにするとかすれば少しは使えるかも。


今回はここまで。次回からJinja2の構文を見ていきます。
続きテンプレートエンジンとは何か?Jinja2の基本2 - よちよちpython