Pythonを使っていると複数のコードで共通して使用しているコードがあることに気付きます。その作業を完全に覚えていればいいのですが毎回ウェブで調べてコードを記述して、とすると目的の作業は同じなのにシートごとにコード記述方法が違ってしまい見にくくなってしまいます。
そんなことを解消するのが「Pythonチートシート」です。
今回は「 jinja2 を用いてHTMLファイルを作成 」するコードを紹介します。
◆ Mac OS
◆ Python 3
◆ JupyterLab
想定する利用シーン
Pythonで作成した変数やlistの値をHTMLの一部に挿入したいなぁ
HTMLで複数箇所に同じテキストを一度に入れたりテンプレート化したいな
Jinja2 とは
Jinja2とは、「python用のhtml作成時に使用できるテンプレートエンジン」です。
Jinja is a fast, expressive, extensible templating engine. Special placeholders in the template allow writing code similar to Python syntax. Then the template is passed data to render the final document.
引用:Jinja2 HP
前準備 フォルダの作成
このコードの実行によりファイル名を読み込むフォルダ・ファイルはこのJupyterLabで作成した「.ipynb」ファイルとの相対パスで場所を示します。
今「.ipynb」を保存しているフォルダと同じ階層に「templates」と「results」というフォルダを作成してください。
1 2 3 4 |
任意のフォルダ - .ipynb (本ファイル) - templates (フォルダ) - results (フォルダ) |
各コードの紹介時に使用するテキストファイルを示しますが、それらは作成した「templates」フォルダの中に保存してください。
Jinja2のインストールと動作確認
それでは実際にコードを紹介します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# Jinja2のインストール !pip install jinja2 # 基本的なJinja2の実行 from jinja2 import Template tpl_text = '私の名前は{{ name }}で、年齢は{{ age }}です' template = Template(tpl_text) data = {'name': 'Mark', 'age': '30'} disp_text = template.render(data) # 辞書で指定する print(disp_text) # 実行結果:私の名前はMarkで、年齢は30です # 実行結果 # > 私の名前はMarkで、年齢は30です |
Jinjaでは {{ … }} : Expressions を用いてテンプレート (template)となるテキストを作成し (7行目)、そのテンプレート中の {{ … }} : Expressionsに入れ込むパラメータ (parameter) を指定します (10行目)。その後テンプレートとパラメータをrenderingする(11行目)ことで、実行結果に示すようにテンプレート中にパラメータの文字列・値を入れることができます。
テンプレート中の {{ … }} : Expressionsは以下のようにPythonの記述通り四則演算すること
1 2 3 4 5 6 7 8 9 10 11 12 |
# 四則演算 from jinja2 import Template tpl_text = '私の名前は{{ name }}で、年齢は{{ age + 7 }} です' template = Template(tpl_text) data = {'name': 'Mark', 'age': 30} disp_text = template.render(data) # 辞書で指定する print(disp_text) # 実行結果:私の名前はMarkで、年齢は30です # 実行結果 #> 私の名前はMarkで、年齢は37 です |
上記の例はシンプルなテキストだったので一つのコード中に全て記載しましたが、一般的にjinjaを使用する際には、以下の3ファイルに構成を分けることが主流です。
- template (htmlのテンプレート)
- parameter (テンプレート中に挿入したいパラメータ)
- rendering (jinjaを実行)
Jinja2の基本 (ファイル準備)
それでは、実際の運用に即した形式でJinja2の使用方法を見ていきます。まずはじめに以下の3ファイルを準備します。
- template (htmlのテンプレート)
- parameter (テンプレート中に挿入したいパラメータ)
- rendering (jinjaを実行)
templateファイルの準備
本実行ファイルと同じディレクトリに作成した[templates]というフォルダに[sample_01.txt]というtxtファイルを作成し、以下のテンプレートの記載をします。
1 2 3 |
<h2> jinja2のテスト </h2> これは jinja2のテストです。 私の名前は {{ name }}で、年齢は {{ age }}です。 |
parameterファイルの作成
parameterファイルはjsonファイルで用意します。以下のコードを実行することで、「str」で定義したjsonファイルが「template」フォルダ中に作成されます。
1 2 3 4 5 6 7 8 9 |
import json str = { 'name' : 'Mark', 'age' : 30 } with open('./templates/parameter_01.json', 'w') as f: json.dump(str, f, ensure_ascii=False) |
renderコードの作成
ここまでで作成した[templateファイル]と[parameterファイル]を読み込んでjinjaでrendering、ここではhtmlテンプレート中にパラメータで設定した情報を入れ込むことをしていきます。templateファイルを読み込むために必要なjinjaの機能としてEnvironment
があり、以下のように記載します。
env = Environment(loader=FileSystemLoader('テンプレートファイル配置ディレクトリのルート'))
template = env.get_template(‘テンプレートファイル名’)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
from jinja2 import Template, Environment, FileSystemLoader import json #テンプレート読み込み env = Environment(loader=FileSystemLoader('./templates', encoding='utf8')) template = env.get_template('sample_01.txt') #パラメータファイル読み込み with open('./templates/parameter_01.json') as f: parameters = json.load(f) #レンダリングして出力 rendered = template.render(parameters) print(rendered) #レンダリングしてhtml出力 rendered_html = template.render(parameters) with open('./results/result_01.html', 'w') as f: f.write(rendered_html) |
実行結果
作成した「results」フォルダ中に「result_01.html」が作成されて、Jinja2のインストールと動作確認時と同じHTML文が出力されました。
Jinja2 {% … %} Statementsの利用
jinjaではテンプレート中に{% ... %}
:Statementsを入れ、{{ ... }}
:Expressionsと組み合わせることでhtml中でもpythonのようにfor文やif文処理を行うことができます。
以下に各コードごとの処理について解説していいきます。
for文
ここでは、複数のlist状になっている項目をfor文で繰り返し、文章形式とテーブル形式で表示させるようにします。 前準備として以下の[templateファイル]と[parameterファイル]を作成します。
templateファイルの準備
本実行ファイルと同じディレクトリに作成した[templates]というフォルダに[sample_02_for loop.txt]というtxtファイルを作成し、以下のテンプレートの記載をします。
なお {# … #}中の記載はコメントアウトされてJinja2のrendering時には現れません。
for文の作成には、{% for (変数) in (Expression) %} の形で記載します。Pythonの時のように「: (コロン)」は不要なので気を付けましょう。 またfor文 Statementsの終わりを示す際には{% endfor %} が必要なため忘れないようにしましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
{# for文のsample #} <html> <body> <h2>jinjaとfor文</h2> 商品と値段一覧 {% for item in data_list %} <p>{{ item.name }}は{{ item.price }}です。</p> {% endfor %} <h2>table形式</h2> <table border=1> <tr> <th>商品</th> <th>値段</th> <th>店名</th> </tr> {% for item in data_list %} <tr> <td>{{ item.name | e}}</td> <td>{{ item.price | e}}</td> <td>{{ item.store | e}}</td> </tr> {% endfor %} </table> </body> </html> |
parameterファイルの作成
parameterファイルはjsonファイルで用意します。以下のコードを実行することで、「data」で定義したjsonファイルが「template」フォルダ中に作成されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
data = { 'data_list' : [ { 'name': 'リンゴ', 'price' : 150, 'store' : 'A-mart' }, { 'name': 'バナナ', 'price' : 100, 'store' : 'Super-B' } ] } with open('./jinja2/templates/parameter_02.json', 'w') as f: json.dump(data, f, ensure_ascii=False) |
renderコードの作成
ここまでで作成した[templateファイル]と[parameterファイル]を読み込んでjinja2でrenderingします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
from jinja2 import Template, Environment, FileSystemLoader import json #テンプレート読み込み env = Environment(loader=FileSystemLoader('./templates', encoding='utf8')) template = env.get_template('sample_02_for loop.txt') #パラメータファイル読み込み with open('./templates/parameter_02.json') as f: parameters = json.load(f) #レンダリングして出力 rendered = template.render(parameters) print(rendered) #レンダリングしてhtml出力 rendered_html = template.render(parameters) with open('./results/result_02.html', 'w') as f: f.write(rendered_html) |
実行結果
作成した「results」フォルダ中に「result_02.html」が作成されて、以下のHTML文が出力されました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<html> <body> <h2>jinjaとfor文</h2> 商品と値段一覧 <p>リンゴは150です。</p> <p>バナナは100です。</p> <h2>table形式</h2> <table border=1> <tr> <th>商品</th> <th>値段</th> <th>店名</th> </tr> <tr> <td>リンゴ</td> <td>150</td> <td>A-mart</td> </tr> <tr> <td>バナナ</td> <td>100</td> <td>Super-B</td> </tr> </table> </body> </html> |
if文
ここでは取得したパラメータの値がプラスかマイナスかの結果に応じて、html中の文字の色を変更させるif文を作成します。
templateファイルの準備
本実行ファイルと同じディレクトリに作成した[templates]というフォルダに[sample_03_if_change color.txt]というtxtファイルを作成し、以下のテンプレートの記載をします。
if文の作成には、{% if …(Expression & 条件) %} の形で記載します。Pythonの時のように「: (コロン)」は不要なので気を付けましょう。 条件分岐の「elif」「else」はPythonと同様の使用方法です。またif文 Statementsの終わりを示す際には{% endif %} が必要なため忘れないようにしましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
{# if文のsample, 数値がプラスで緑色、マイナスで赤色 #} <html> <body> <h2>jinjaとif文</h2> <p>色の凡例</p> <p><span style="color: #008000;">緑色(プラス)</span></p> <p><span style="color: #ff0000;">赤色(マイナス)</span></p> {% for item in data_list %} {% if item.profit > 0 %} <p><span style="color: #008000;">{{ item.profit }}でプラスです。</span></p> {% elif item.profit == 0 %} <p>{{ item.profit }}でプラスマイナス0です。</p> {% else %} <p><span style="color: #ff0000;">{{ item.profit }}でマイナスです。</span></p> {% endif %} {% endfor %} </body> </html> |
ここでは次のparameterファイルで設定する「profit」の数値がプラスであれば緑色、マイナスであれば赤色で修飾し、±0であれば黒字のままとします。
parameterファイルの作成
parameterファイルはjsonファイルで用意します。以下のコードを実行することで、「data」で定義したjsonファイルが「template」フォルダ中に作成されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
data = { 'data_list' : [ { 'name': 'リンゴ', 'price' : 150, 'profit' : 1000 }, { 'name': 'バナナ', 'price' : 100, 'profit' : -500 }, { 'name': 'レモン', 'price' : 200, 'profit' : 0 } ] } with open('./jinja2/templates/parameter_03.json', 'w') as f: json.dump(data, f, ensure_ascii=False) |
renderコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
from jinja2 import Template, Environment, FileSystemLoader import json #テンプレート読み込み env = Environment(loader=FileSystemLoader('./templates', encoding='utf8')) template = env.get_template('sample_03_if_change color.txt') #パラメータファイル読み込み with open('./templates/parameter_03.json') as f: parameters = json.load(f) #レンダリングして出力 rendered = template.render(parameters) print(rendered) #レンダリングしてhtml出力 rendered_html = template.render(parameters) with open('./results/result_03.html', 'w') as f: f.write(rendered_html) |
実行結果
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<html> <body> <h2>jinjaとif文</h2> <p>色の凡例</p> <p><span style="color: #008000;">緑色(プラス)</span></p> <p><span style="color: #ff0000;">赤色(マイナス)</span></p> <p><span style="color: #008000;">1000でプラスです。</span></p> <p><span style="color: #ff0000;">-500でマイナスです。</span></p> <p>0でプラスマイナス0です。</p> </body> </html> |
最後に
jinja2を使用することでPythonとHTMLの連携が可能となり、これを活用することでPythonを用いたWordpressへの自動投稿を高い自由度で行えるようになりました。複雑な記事の作成のためには、テンプレート中の{% ... %}
:Statementsを入れ、{{ ... }}
:Expressionsの記載と、parameterをどう作成するかが鍵となると考えます。
「Pythonチートシート」で毎回よく使う作業のPythonコードをまとめ、今回は「jinja2 を用いてHTMLファイルを作成」するコードを紹介しました。
他にもいろいろなチートシートを用意しておりますので以下から確認してみてください。
コメント