
過去の記事でルーティングというのを勉強しました。ルーティングごとにPython側で書いてそれをブラウザで表示するというものでしたね。ただHello Flaskのような短い文章だけではなくもっと数十行、数百行書くときがでますよね。そんなときPython側でブラウザで、表示させたいものを書くのは大変しんどいです。
このような場合、HTMLテンプレートエンジン(Jinja2)を活用することが非常に有効です。FlaskはJinja2というテンプレートエンジンを標準で使用しており、これを利用することで、Python側のコードとHTMLの表示を分けることができます。こうすることで、Pythonのコードが複雑になった場合でも、HTMLはシンプルに保つことができます。
HTMLテンプレートとPythonコードを分ける
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def home():
return render_template('index.html')
if __name__ == '__main__':
app.run(debug=True)
render_template
関数を使って、テンプレートファイル(通常はtemplates
フォルダ内にあるHTMLファイル)をレンダリングします。
render_template
は、HTMLファイル(テンプレート)をブラウザに表示するための関数です。そのため
from flask import Flask, render_templateとして使えるようにしないとだめです。
Python側はこれで大丈夫ですので、index.htmlファイルを作っていきましょう。
templatesファルダとindex.htmlファイルを作る

templatesファルダを作って、その中にindex.htmlファイルを作ってください。templatesというファルダ名に関しては変えないでください。
なぜかというとFlaskでは、デフォルトでrender_template
関数はtemplates
フォルダ内のHTMLファイルを探すように設計されています。FlaskアプリケーションでHTML管理する際に、ファイルがどこにあるのかを明確にわかるようになっています。
index.htmlを書こう
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>サンプルページ</title>
</head>
<body>
<h1>ようこそ!</h1>
<p>これはFlaskで表示されているHTMLページです。</p>
</body>
</html>
このindex.htmlが@app.route('/')
内のrender_template
関数で引き渡されているのでindex.htmlがメインページとして表示されることになります。
ただこれだけだとHTMLを表示しているだけで、なぜFlaskを使う必要があるのかという疑問が湧いてくると思いますが、Python側の情報をJinja2を使ってHTMLに表示することができるんです。それを紹介していきます。
index.htmlでPython側の情報を表示する
<<head>
<meta charset="UTF-8">
<title>{{ title }}</title>
</head>
<body>
<h1>{{ message }}</h1>
<p>これはFlaskのJinja2を使ったHTMLレンダリングの例です。</p>
</body>
</html>
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def home():
return render_template('index.html', title="Flask入門", message="Jinja2でHTMLを動的に表示!")
if __name__ == '__main__':
app.run(debug=True)
render_template()
の第二引数以降には、HTMLテンプレートに渡したい 変数(キーワード引数) を指定できます。これにより、PythonのデータをHTMLテンプレート内で動的に利用できます。
ここで指定した 変数名 は、HTML内で {{ 変数名 }}
の形で使えます。

実際に実行してみると、HTML側の<h1>
のタグの中身は「Jinja2でHTMLを動的に表示!」と書いていないのに、ちゃんと表示されていますよね。これはPython側の情報を、HTMLに送っているということです。
次はPythonの機能をHTML側で使ってみましょう。
HTMLにPythonを書いてみる
if文使ってみよう
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/user/<name>')
def user(name):
return render_template('index.html', username=name)
if __name__ == '__main__':
app.run(debug=True)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>ユーザーページ</title>
</head>
<body>
<h1>こんにちは、{{ username }} さん!</h1>
{% if username == "admin" %}
<p>管理者としてログインしています。</p>
{% else %}
<p>一般ユーザーとしてログインしています。</p>
{% endif %}
</body>
</html>
Python側では動的ルーティングを使って情報を動的にして、HTML側に送っています。もし動的ルーティングについて学習がまだの人は下の記事からご覧ください。

Jinja2ではPythonの if
や for
のような 制御構文 をHTMLテンプレート内で使うことができます。ただし、Jinja2の書き方は Pythonと少し異なる ので注意が必要です。
Jinja2では {% if 条件 %} ... {% endif %}
という形で使います。
上記のHTMLの条件分岐の場合は
http://127.0.0.1:5000/user/admin
にアクセスすると「管理者としてログインしています」と表示 http://127.0.0.1:5000/user/taro
にアクセスすると「一般ユーザーとしてログインしています」と表示(admin以外の場合なのでtaro以外でも一般ユーザーになります。)
if文を実際に体感しよう

今まで習ってきた動的ルーティング。render_templateなどが一つの簡易アプリケーションになったのが体感できたでしょうか?これでHTML内でif
文が使う方法などが学べましたね。
次はif
文ではなくfor
文もやってみましょう。
for文を使ってみよう
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/items')
def items():
item_list = ["りんご", "バナナ", "みかん","梨","モモ"]
return render_template('items.html', items=item_list)
if __name__ == '__main__':
app.run(debug=True)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>商品一覧</title>
</head>
<body>
<h1>商品一覧</h1>
<ul>
{% for item in items %}
<li>{{ item }}</li>
{% endfor %}
</ul>
</body>
</html>
Jinja2では {% for item in items %} ... {% endfor %}
という形でfor文を使います。
items
というリストをHTMLでfor文を使って一つずつ表示している場合、りんご、バナナ、みかん、梨、モモ程度ならHTMLに直接書き込んでも大した手間にはならないです。だけど、情報が100個、1000個になると、その作業はかなり面倒です。そこで、Python側で情報を追加したり、更新したりすることで、HTMLを自動的に更新し、表示できるようにすれば、作業が大変楽になりますよね。
なのでfor文を使って表示しましょう.
for文を実際に使ってみましょう

これでfor文を使うことができましたね。このようにHTML内でfor文を使うことができれば膨大なデータを表示するときに大変役に立ちます。皆さんもぜひ使ってくださいね。
Jinjaという拡張機能は便利


拡張機能の検索窓で「Jinja」と検索すると上の画像のようなJInjaという拡張機能が出てきます。この拡張機能はHTML側でPythonコードを書くとき、色づけがされなくて視認性が悪くなります。それを改善してくれるものですので入れることをお勧めします。(コード数長くなってくると案外色づけされるだけで、視認性の面で役に立ってきます。)
ぜひ入れてみてね