こんにちは。AWS CLIが好きな福島です。
インフラエンジニアのキャリアがメインの私が社内でPythonを使ったアプリ開発の学習をする機会があったため、先日から学んだことをアウトプットしています。
先日、Flask
とBootstrap
入門に関するブログを書きましたが、
今回はJinja2入門のブログをまとめたいと思います。
参考情報
Jinja2とは
一言で言うと、テンプレートエンジンです。
テンプレートエンジンとは以下のイメージで、テンプレートと入力データを基に新たな成果物を生成するソフトウェアです。
上記ではJinja2を使うメリットを感じられないかもしれませんが、以下などの機能により柔軟な成果物の生成やテンプレート管理の簡素化をすることができます。
for
,if
などの利用- テンプレートから他のテンプレートの読み込み(include)機能
Jinja2を使ってみる
まずは、Jinja2をインストールします。
pip install Jinja2
次に以下のフォルダ構成でファイルを作成します。
フォルダ構成
sample-jinja ├── app.py └── templates └── index.html
index.html
こんにちは! {{ name }} さん!
app.py
from jinja2 import Environment, FileSystemLoader, select_autoescape env = Environment( ## 読み込みたいフォルダを指定 loader= FileSystemLoader("templates"), autoescape=select_autoescape() ) ## 読み込みたいファイルを指定 template = env.get_template("index.html") print(template.render(name="kazuya")
ファイルの準備が完了したら、python app.py
を実行します。
index.htmlのname
に入力データのkazuya
が値が入り表示されていることが分かります。
$ python app.py こんにちは! kazuya さん! $
Jinja2はFlaskに組み込まれている
実は以前ブログを書いたFlaskにJinja2は組み込まれています。
そのため以降は、FlaskからJinja2を呼び出しながら、Jinja2で出来ることを書いていきたいと思います。
Flaskから呼び出す場合は、以下のようにrender_template
モジュールを利用します。
app.py
from flask import Flask, render_template app = Flask(__name__) @app.route("/<name>") def index(name): return render_template("index.html",name=name)
index.html
こんにちは! {{ name }} さん!
ファイルを変更したら、flask run --debug
を実行します。
http://127.0.0.1:5000/任意の値
にアクセスすると以下の通り表示されます。
$ flask run --debug * Debug mode: on WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Running on http://127.0.0.1:5000 Press CTRL+C to quit * Restarting with stat * Debugger is active! * Debugger PIN: 114-794-361
変数展開
上記のサンプルコードで察している方もいると思いますが、{{ 変数名 }}
で変数を展開することができます。
もう少し具体的には、以下の通りです。
index.html
には、{{ 変数名 }}
のように書く。app.py
では、render_template(index.html, 変数名=値)
のように書く。
以下のように、複数の変数を渡すこともできます。
index.html
{{ comment }}! {{ name }} さん!
app.py
from flask import Flask, render_template app = Flask(__name__) @app.route("/<name>") def index(name): return render_template("index.html", comment="おはよう", name=name)
また、辞書を渡すこともできます。
index.html
には、{{ 変数名.キー名 }}
もしくは{{ 変数名["キー名"] }}
のように書く。app.py
では、render_template(index.html, 変数名=辞書型のデータ))
のように書く。
index.html
{{ param.comment }}! {{ param['name'] }} さん!
app.py
from flask import Flask, render_template app = Flask(__name__) @app.route("/<name>") def index(name): param = {"comment": "Hello, World", "name": name} return render_template("index.html", param=param)
for文
{% for 変数名 in データ %}
、{% endfor %}
を使うことでプログラミングにおけるfor文と同じような動きをさせることができます。
Pythonの処理と組み合わせると動的にコンテンツを展開できるので、便利ですね。
index.html
{% for user in users %} <li>{{ user }}</li> {% endfor %}
app.py
from flask import Flask, render_template app = Flask(__name__) @app.route("/") def index(): users = ["Alice", "Bob", "Charlie"] return render_template("index.html", users=users)
上記はリスト型を渡していますが、辞書型を渡すこともできます。
index.html
{% for param in params %} <li>{{ loop.index }} {{ param.name }}: {{ param.age }}</li> {% endfor %}
{{ loop.index }}
は、Jinja2の特殊な変数となり、ループ数に応じて1,2,3のように数字が入ります。
(辞書型を使う際に必須な値という訳ではないです。)
ちなみに0から数字を開始したい場合は、{{ loop.index0 }}
を利用することができます。
他に利用できる値の詳細は以下を確認ください。
app.py
from flask import Flask, render_template app = Flask(__name__) @app.route("/") def index(): params = [ { "name": "Alice", "age": 21, }, { "name": "Bob", "age": 29, }, { "name": "Charlie", "age": 34, }, ] return render_template("index.html", params=params)
if文
if文も使うことができます。以下はname
変数の値がある場合は、name
の値を表示し、
name
変数の値がない場合は、Name Not Found
の値を表示します。
わざわざ2つのテンプレートを用意する必要がないため、便利ですね。
index.html
{% if name %} <li>{{ name }}</li> {% else %} <li>Name Not Found</li> {% endif %}
app.py
from flask import Flask, render_template app = Flask(__name__) @app.route("/") def index(): return render_template("index.html") @app.route("/<name>") def index2(name): print(name) return render_template("index.html", name=name)
テンプレートの読み込み(include)
続いて、テンプレートの読み込みについての説明です。
Webアプリを作る際に、複数のWebページを作る場合があります。
その際に共通となるヘッダーやフッターは、1つのテンプレートに定義し、 別のテンプレートから参照させることができたら便利だと思います。
そのような場合にテンプレートの読み込み(include)を使います。
今回は、index.html
からheader.html
とfooter.html
を読み込みます。
sample-jinja ├── app.py └── templates └── footer.html └── header.html └── index.html
まず、header.html
とfooter.html
を作ります。
header.html
<h1>ヘッダー!!</h1>
footer.html
<h1>フッター!!</h1>
次にindex.html
には、{% include '読み込みたいテンプレート名' %}
のように書きます。
index.html
{% include 'header.html' %} こんにちは!! {{ name }} さん!! {% include 'footer.html' %}
app.py
from flask import Flask, render_template app = Flask(__name__) @app.route("/<name>") def index(name): return render_template("index.html", name=name)
以下のようにheader.html
とfooter.html
をindex.html
から読み込めていることが分かります。
終わりに
今回は、Jinja2入門に関するブログをまとめてみました。
どなたかのお役に立てれば幸いです。