本記事の背景
-
Jinja2はFlaskだけではなく、Django(ジャンゴ)のフロントエンド側で記述できる言語で、HTMLと組合わせで使われている。HTMLのタグをプログラム言語のように扱えるロジックを組み込むことができるようになる便利な記述法である。かつJavascriptと組み合わせで使用することも可能で、バックエンド側から引渡されたデータを条件分岐、ループなどを活用して、扱うことができる。
-
Jinja2はプログラミング言語としては、Pythonとかなりに似ているため、実装上において、どんなプログラマーでも同じようなプログラムになるので、メンテナンスの手間があまりかからない、そして読みやすくなっている。
-
Jinja2はhtmlモジュールを分割と継承の仕組みが用意されているため、共通部分とカスタマイズ部分をそれぞれうまく組み合わせることで、HTMLのモジュール化ができる。
本記事は、初心者向けのJinja2の基本的な事例を解説する。本格的な開発する場合、必要に応じて、HTMLの設計を行い、分割と継承の仕組みを公式ページから習得することをお勧めします。
Jinja2のデメリット
- JavaScriptとの組み合わせができるものの、親和性が高くないため、場合によっては、難解な部分もある。
- レンダリングで動くが、レンダリングで引き渡さない場合は動作しないため、使い分けを意識する必要がある。
- CSSとの組み合わせについてはほとんど考慮されていない
- JavaScriptのように動的なイベントハンドラーやイベントリスナーを簡単に付与することはできない。あくまでも静的なページデータの生成を意識している。
- バックエンド(Python)からJavascriptへ変数を引き渡す時に特別な仕掛けを作ることが必要
- マルチプロセス実装する場合は、バグが出やすい(これはFlask自身にも言えること)
本記事の対象者
- JavaScriptの基礎文法を理解している
- Flaskの基礎を取得している
- HTML/CSSのタグを理解している
- Python基礎文法を理解している
※上記で未収得の場合は下記の関連情報を先に参照し、習得、理解してください。
関連情報
- JavaScript超入門(var/let/const解説付)
- とほほJavascript入門(必要に応じて逆引き)
- Flask構築手順
- Jinja2入門
HTML内でJinja2を使用する事例
本記事はPythonからではなく、主にHTMLに実装する場合のJinja2の記述について紹介する
Flaskのrender_template()の引数をHTMLへデータを引渡しする時に以下のケースについて事例を示す。
- 変数
- 辞書型変数
- 1次元リスト
- 2次元リスト
- Form
- 表示/非表示の切り替え
呼び出し元
呼び出し元のFlask(Python)は以下に示す
@app.get('/')
def index():
# 変数
user_name = 'yamada takao'
# 辞書型変数
dict_data = {"name":"gao jun", "age": 25}
# 1次元リスト
li_01 = [10,20,30,40,50]
# 2次元リスト
li_02 = [[1,2,3],[4,5,6],[7,8,9]]
# Form
form = SelectMultiStore()
# 表示Flag
flag = 1
return render_template('index.html',
user_name=user_name,
dict_data=dict_data,
li_01=li_01,
li_02=li_02,
flag = flag,
form=form
)
表示側(HTML+Jinja2)
Jinja2の基礎
Jinja2は「{{ }}」または「{% %}」を用いて、HTML内に記述する
- 変数の表示
{{ user_name }}
- 分岐ブロックの記述例
{% if user_name %}
<div>{{user_name}}</div>
{% endif %}
以下はいくつかの組み合わせの例を記述してある
<html lang=“ja”>
<head>
<meta charset=“UTF-8“ />
<title>Form</title>
<script src="https://cdn.jsdelivr.net/npm/jquery/dist/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://unpkg.com/multiple-select@1.5.2/dist/multiple-select.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://unpkg.com/multiple-select@1.5.2/dist/multiple-select.min.css">
<link rel="stylesheet" href="/static/table.css">
</head>
<body style="background: #dae5ee;">
<h4>Jinja2 test demo</h4>
<hr>
<div>1. 変数</div>
<div>user name: {{ user_name }}</div>
<hr>
<div">2. 辞書型変数</div>
<div>
{% for key, value in dict_data.items() %}
{{key}} : {{value}}<br>
{% endfor %}
</div>
<hr>
<div>3. 1次元リスト</div>
<div>
{% for value in li_01 %}
{{value}}
{% endfor %}
</div>
<hr>
<div>4. 2次元リスト</div>
<div>
{% for l1 in li_02 %}
{% for v in l1 %}
{{ v }}
{% endfor %}<br>
{% endfor %}
</div>
<hr>
{% if flag == 1 %}
<form method="POST" action="/show_data">
<h3>{{form.stores}}</h3>
<h3>{{form.category}}</h3>
{{ form.submit() }}</h3>
</form>
{% endif %}
<hr>
<script>
$(function () {
$('select').multipleSelect({
width: 400,
selectedList: 100,
classes:'.multi__etc',
});
});
</script>
</body>
</html>