[Flask/Jinja2]extendsやincludeを使い、メンテしやすいテンプレート構築を目指す
Flaskで、ヘッダー、フッターなど、複数のページで共通の部品を表示するときに使える手法を紹介します。
1. extends
公式チュートリアルでも紹介されている基本的な手法。
ベースとなるHTMLファイルを作成し、extends
でそのファイルを継承します。
具体的には、html,headあたりの枠組みとなるapplication.htmlを作成し、各ページではそれを継承してHTMLを記述していきます。
extendsの使い方例・サンプル
ルートパスにアクセスするとindex.htmlのテンプレートで出力が返ってくるとします。
コード
@app.route('/') def index(): title = "サンプルタイトル" return render_template('index.html',title=title)
テンプレート側では以下のように書きます。
application.html
<!DOCTYPE html> <html> <head> <title>{{title}}</title> </head> <body> <div> {% block body %} {% endblock %} </div> </body> </html>
index.html
{% extends "application.html" %} {% block body %} <h1>Hello</h1> <div> <p>Some content here.</p> </div> {% endblock %}
index.htmlでは、application.htmlを継承。
application.htmlで{% block body %}{% endblock %}
と記述された箇所に、index.htmlでの {% block body %}〜{% endblock %}
が出力されます。
出力HTML
<!DOCTYPE html> <html> <head> <title>サンプルタイトル</title> </head> <body> <div> <h1>Hello</h1> <div> <p>Some content here.</p> </div> </div> </body> </html>
このように、基本となるhtmlテンプレートをextendsすることで、head内の設定などは一元管理して使い回すことができます。
2. include
同じテンプレート部品を使い回すことができます。
extendsと似ていますが、個人的にはより使い勝手が良いです。
Ruby on Railsのパーシャルに近い機能。
includeの使い方例・サンプル
複数のページで共通して使うHeaderコンテンツを考えてみます。
コード
header.html
<div class="header"> Here shows header contents. </div>
さきほどのindex.htmlに追記します。
{% extends "application.html" %} {% block body %} {% include "header.html" %} <h1>Hello</h1> <div> <p>Some content here.</p> </div> {% endblock %}
別のページも作ってみます。
server.py
@app.route('/page') def page(): title = "Another page" return render_template('sample_page.html', title=title)
page.html
{% extends "sample.html" %} {% block body %} {% include "header.html" %} <h1>Other page</h1> <div> <p>Other content here.</p> </div> {% endblock %}
出力結果
パス : /
<!DOCTYPE html> <html> <head> <title>サンプルタイトル</title> </head> <body> <div> <div class="header"> Here shows header contents. </div> </div> <div> <h1>Hello</h1> <div> <p>Some content here.</p> </div> </div> </body> </html>
パス : /page
<!DOCTYPE html> <html> <head> <title>Another page</title> </head> <body> <div> <div class="header"> Here shows header contents. </div> </div> <div> <h1>Other page</h1> <div> <p>Other content here.</p> </div> </div> </body> </html>
これでHeaderコンテンツを変更したいときはheader.htmlの中身だけを書き換えれば良くなりました。
{ % include 〜 % }をどこに入れるか?も考慮します。
例えば、上記ではindex.htmlとpage.htmlの両方でincludeしていますが、このようなページ構成ならばapplication.htmlでincludeした方が運用が楽そうです。
extendsとincludeでは、includeの方がパーツを切り出して使いまわしやすい利点があります。
- ヘッダ、フッタ、サイドバーなど基本パーツをincludeを用いて構築
- 各種ページは基本ページを継承して各コンテンツを表示
- 使い回せる要素は切り出してinclude
という感じで作っていくと、メンテナンスしやすくなりそうです。
また、micro
という関数もあるようです。次の機会に調べてみます。
まとめ
- extends, includeを使うことでFlask+Jinja2の開発は効率化できる
- extendsは枠組みを継承、includeはピンポイントで、それぞれ部品ファイルを呼び出すことができる
ディスカッション
コメント一覧
まだ、コメントがありません