Flask入門|テンプレートの継承を理解しよう【チャプター2-02】

一つ前のページでは「Jinja2とは何か」について学習しました。
今回は テンプレートの継承 について見ていきましょう。
Chapter1:Flask入門編
Chapter2:Jinja2入門編
・Chapter2-1:Jinja2とは何か|テンプレートエンジン入門
・Chapter2-2:テンプレートの継承を理解しよう ◁今回はここ
・Chapter2-3:url_for関数を理解しよう
・Chapter2-4:render_template関数を理解しよう
・Chapter2-5:テンプレートと繰り返し処理
・Chapter2-6:テンプレートと分岐処理
Chapter3:フィルター編
Chapter4:フォーム編
Chapter5:データベース編
Chapter6:Flaskの便利機能編
Chapter7:アプリ開発編
FlaskではWebページをHTMLで作成する際に テンプレートエンジンJinja2 を使って、より柔軟な構成を実現できます。
ただし、複数のページで同じヘッダーやフッター、レイアウトを繰り返し書いていると、コードがどんどん冗長になります。
そこで登場するのが「テンプレートの継承」という仕組みです。
これを使えば、共通部分を一つのテンプレートにまとめ、必要に応じて個別のテンプレートから呼び出すことができます。
Pythonのクラスの継承を理解している人であれば、難しくない内容でしょう。
Jinja2のテンプレート継承とは?Flask開発を効率化する仕組みを解説
テンプレート継承とは、「共通部分(ベース)を定義して、他のテンプレートで使い回すことができる仕組み」です。
FlaskのテンプレートエンジンであるJinja2には、この機能が標準で備わっており、HTMLのヘッダーやフッター、サイドバーなどの繰り返し部分を一箇所にまとめることができます。
複数ページで共通レイアウトを再利用する理由
- 変更が必要な時、1ファイルだけ直せば全ページに反映される
- 同じコードを何度も書かなくて良くなる(=保守が楽)
- デザインや構成の統一感を保てる
extendsとblockを使った基本的なJinja2構文
テンプレート継承を使うには、主に以下の2つの文法を使います。
1. {% extends '親テンプレート名.html' %}
このコードがかかれたHTMLファイルは別のHTMLファイル(親テンプレート)を継承します。
2. {% block 任意の名前 %} 〜 {% endblock %}
テンプレートの継承を行う際に、このブロックで囲われた部分(blockタグの中)が対象となります。
- 親テンプレート:このブロックの中は子テンプレートが上書きできる
- 子テンプレート:このブロックの中の内容で親テンプレートを上書きする
<html> <head> <title>My Site</title> </head> <body> {% block 任意の名前 %} <!-- 子テンプレートに上書きさせるブロックの定義 --> ここに個別ページの内容が入ります。 <!-- 上書きされなければこの内容が表示される --> {% endblock %} </body> </html>
{% extends '親テンプレート名.html' %} <!-- 親テンプレートを継承する宣言 --> {% block 任意の名前 %} <!--継承元の内容を上書き --> <h1>トップページへようこそ!</h1> {% endblock %}
テンプレート継承の具体例|実践で学ぶextendsとblockの使い方
テンプレートを継承する例をふたつ見てみましょう。
ヘッダー・フッターを共通化した基本テンプレートの作成
まずはシンプルな継承の例から見てみましょう。
<!DOCTYPE html> <html> <head> <title>Flask Sample</title> </head> <body> <header> <h1>共通のヘッダー</h1> </header> {% block content %} <!-- 子テンプレートに上書きさせるブロックの定義 --> <!-- 子テンプレートで上書きする部分 --> {% endblock %} <footer> <p>共通のフッター</p> </footer> </body> </html>
{% extends 'base.html' %} <!-- base.htmlを継承する宣言 --> {% block content %} <!--継承元の内容を上書き --> <h2>トップページの内容です</h2> <p>Flaskテンプレート継承の使い方を学んでいます。</p> {% endblock %}
{% extends 'base.html' %} <!-- base.htmlを継承する宣言 --> {% block content %} <!--継承元の内容を上書き --> <h2>このサイトについて</h2> <p>このサイトはFlaskの学習をサポートするために作られました。</p> {% endblock %}
このようにすることで、「ヘッダー」や「フッター」はbase.html側で定義しておけば、どのページも共通レイアウトになります。
複数のblockを活用して柔軟なページ構成を作る方法
複数の場所で内容を差し替えたい場合は、block
をいくつも定義できます。
<html> <head> <title>{% block title %}デフォルトタイトル{% endblock %}</title> <!-- titleブロックの定義 --> </head> <body> <nav> {% block nav %}デフォルトナビゲーション{% endblock %} <!-- navブロックの定義 --> </nav> <main> {% block content %}{% endblock %} <!-- contentブロックの定義 --> </main> </body> </html>
{% extends 'base.html' %} {% block title %}Aboutページ{% endblock %} <!-- titleブロックを上書き --> {% block nav %} <!-- navブロックを上書き --> <ul> <li><a href="/">ホーム</a></li> <li><a href="/about">About</a></li> </ul> {% endblock %} {% block content %} <!-- contentブロックを上書き --> <h2>このサイトについて</h2> <p>このページではFlaskについて解説しています。</p> {% endblock %}
このようにすれば、ページごとにタイトルやナビゲーションの内容を変えることもできます。
まとめ
テンプレートの継承を使うことで、HTMLの共通レイアウトを定義し、個々のページでは必要な部分だけを変更することができます。
特にFlaskで複数ページを持つWebアプリを作る際には、この仕組みを活用することでコードをすっきり保てます。
次のチャプターでは、url_for
関数を使ってテンプレート内で動的にURLを生成する方法を学びます。
テンプレート継承と組み合わせることで、さらに効率的なWeb開発が可能になります。
練習問題:自己紹介ページをテンプレート継承を使って作成しよう!
後述するFlaskアプリとベーステンプレートが与えられているとします。
あなたはこのベーステンプレートを継承する profile.html
を作成し、自己紹介ページを完成させてください。
この問題の要件
以下の要件に従ってコードを完成させてください。
templates/profile.html
ファイルを新たに作成すること。profile.html
はbase.html
を継承して作成すること。{% block content %}
の中に以下の内容を表示すること:- 見出し(
<h2>
)として「自己紹介」と書くこと。 - 段落(
<p>
)で「こんにちは!私はFlaskを勉強中のプログラマーです。」と表示すること。 - 段落で「Pythonは基本を学び終え、今はWebアプリを作る方法を学んでいます。」と表示すること。
前提となるコードは以下の通り。
from flask import Flask, render_template app = Flask(__name__) @app.route('/') def show_profile(): return render_template('profile.html') if __name__ == '__main__': app.run(debug=True)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Flask練習サイト</title> </head> <body> <header> <h1>ようこそ!Flask学習ページへ</h1> </header> {% block content %} {% endblock %} <footer> <p>© 2025 Flask学習者の会</p> </footer> </body> </html>
正解コード
例えば、以下のようなプログラムが考えられます。
- 正解コード
-
{% extends 'base.html' %} {% block content %} <h2>自己紹介</h2> <p>こんにちは!私はFlaskを勉強中のプログラマーです。</p> <p>Pythonは基本を学び終え、今はWebアプリを作る方法を学んでいます。</p> {% endblock %}
FAQ|Flaskテンプレート継承の使い方
- Q1. Jinja2で複数のテンプレートを継承させることはできますか?
-
可能です。ただし直接の多重継承は推奨されず、基本は1つの親テンプレートから継承する設計にします。必要に応じてインクルード機能(
include
)と組み合わせることで柔軟に構成できます。
- Q2. blockタグの中に別のblockを書くことはできますか?
-
いいえ、blockのネスト(入れ子)はJinja2の仕様上サポートされていません。複雑な構成が必要な場合は、複数のblockを使い分けてページを構成するようにしましょう。
- Q3. extendsで指定するファイルパスはどこからの相対パスですか?
-
extends
で使うテンプレート名は、Flaskのテンプレートフォルダ(通常はtemplates/
)を基準としたパスです。拡張子(.html)も含めて記述するのが一般的です。
質問用コンタクトフォーム
この記事を書くにあたりAIを活用しています。
人間の目による確認も行っていますが、もし間違い等ありましたらご指摘頂けると大変助かります。