[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はピンポイントで、それぞれ部品ファイルを呼び出すことができる
ディスカッション
コメント一覧
まだ、コメントがありません