データベースとのやり取り、ユーザーからのリクエスト受付などのタスクとブラウザへの表示タスクを分けておかないとメンテナンスが大変。
Flaskでは後半の表示部分をJinja2というtemplate engineで処理している。
ここをもう一度ちゃんと押さえておく。
基本中の基本
template/
にhtmlファイルを置くとflaskアプリから参照される。
hello.py
from flask import Flask, render_template from flask_script import Manager app = Flask(__name__) manager = Manager(app) #flask_scriptを導入して拡張した部分 @app.route('/') def index(): return render_template('index.html') #render_templateを使ってtemplate/index.htmlの中身を読み込む @app.route('/user/<name>') def user(name): return render_template('user.html', name=name) #name=nameの左側のnameはtemplate(user.html)のなかでプレースホルダ({{}}の中身)として名付けられた引数としてのname。右側のnameはここで得られた変数としてのname。ああややこしい。別のなまえにしときゃいいのに。 if __name__ == '__main__': manager.run() #managerを通して起動
index.html
<h1>Hello, World!</h1>
user.html
<h1>Hello, {{ name }}!</h1>
htmlファイルと言ってもヘッダーはなくてもいいようだ。titleタグとかはちゃんとそのまま使える。
if条件分岐の利用
user.htmlを
{% if name == 'hoge' %} <h2>Hello, {{ name }}!</h2> {% else %} <h2>Hello, Stranger.</h2> {% endif %}
とすると
http://127.0.0.1:5000/user/hoge
だと
Hello, hoge!
http://127.0.0.1:5000/user/hogehoge
だと
Hello, stranger.
となる。
forループの利用
from flask import Flask, render_template from flask_script import Manager app = Flask(__name__) manager = Manager(app) @app.route('/') def index(): return render_template('index.html', comments = ["test1", "test2", "test3"] ) if __name__ == '__main__': manager.run()
index.html
<ul> {% for comment in comments %} <li>{{comment}}</li> {% endfor %} </ul>
こういう組み合わせで
- test1
- test2
- test3
と返ってくる
またマクロを使って コメントを読み取る部分とリストを作る部分を分けて
{% macro render_comment(comment) %} <li>{{comment}}</li> {% endmacro %} <ul> {% for comment in comments %} {{ render_comment(comment) }} {% endfor %} </ul>
このように記述したり
更にmacroを別のファイルにしてインポートすることも
template/macros.html
{% macro render_comment(comment) %} <li>{{comment}}</li> {% endmacro %}
index.html
{% import 'macros.html' as macros %} <ul> {% for comment in comments %} {{ macros.render_comment(comment) }} {% endfor %} </ul>
この場合macros.htmlに複数マクロを並べておいて流用できたりするわけだね。