【Flask】テンプレートの継承を理解しよう|Chapter2-2

一つ前のページでは「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:エラーハンドリングとデバッグ編
Chapter7:アプリ開発編
FlaskではWebページをHTMLで作成する際に テンプレートエンジンJinja2 を使って、より柔軟な構成を実現できます。
ただし、複数のページで同じヘッダーやフッター、レイアウトを繰り返し書いていると、コードがどんどん冗長になります。
そこで登場するのが「テンプレートの継承」という仕組みです。
これを使えば、共通部分を一つのテンプレートにまとめ、必要に応じて個別のテンプレートから呼び出すことができます。
Pythonのクラスの継承を理解している人であれば、難しくない内容でしょう。

- Flask開発を Stream Deck でボタン化しよう!
- 
Flaskは非常に軽量かつシンプルなフレームワークですが、それゆえに定型作業が多く、開発は単調な作業の連続になりがちです。 それこそがFlaskのメリットであり、習得難易度が低い理由でもありますが、単調な作業は退屈で、ミスも起こりやすいでしょう。 そこで役に立つのが Stream Deck 。 このような定型手順が多い作業を “ボタン化” することで視覚化。 圧倒的に 効率的 かつ ストレスフリー な開発環境が簡単に手に入ります↓↓ あわせて読みたいFlask開発をStreamDeckでボタン化しようあわせて読みたいプログラマー向けStream Deckの選び方|初心者でも失敗しないモデル比較ガイド
Jinja2のテンプレート継承とは?|基本構文と具体例
テンプレート継承とは、「共通部分(ベース)を定義して、他のテンプレートで使い回すことができる仕組み」です。
Jinja2にはこの機能が標準で備わっており、HTMLのヘッダーやフッター、サイドバーなどの繰り返し部分を一箇所にまとめることができます。
- 変更が必要な時、1ファイルだけ直せば全ページに反映される
- 同じコードを何度も書かなくて良くなる(=保守が楽)
- デザインや構成の統一感を保てる

extendsとblockを使ったテンプレート継承の基本構文
テンプレート継承を使うには、主に以下の2つの文法を使います。
親テンプレート(継承される側)
親テンプレート:ブロックの中の部分は子テンプレートから上書きできる
{% block 任意の名前 %} 〜 {% endblock %}テンプレートの継承を行う際に、このブロックで囲われた部分(blockタグの中)が対象となります。
子テンプレート(継承する側)
子テンプレート:このブロックの中の内容で親テンプレートを上書きする
{% extends '親テンプレート名.html' %}このコードがかかれたHTMLファイルは別のHTMLファイル(親テンプレート)を継承します。

テンプレート継承の具体例|extendsとblockの使い方
テンプレートを継承する例をふたつ見てみましょう。
ヘッダー・フッターを共通化した基本テンプレートの作成
まずはシンプルな継承の例から見てみましょう。
<!-- 親テンプレートは単体でも表示できるよう、DOCTYPE宣言から全て書く -->
<!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開発が可能になります。
- サイト改善アンケート|1分だけ、ご意見をお聞かせください
- 
本サイトでは、みなさまの学習をよりサポートできるサービスを目指しております。 
 そのため、ご利用者のみなさまの「プログラミングを学習する理由」などをアンケート形式でお伺いしています。ご協力いただけますと幸いです。 アンケート
練習問題:テンプレート継承を使って自己紹介ページを作成しよう!

後述する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)も含めて記述するのが一般的です。






