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のクラスの継承を理解している人であれば、難しくない内容でしょう。

あわせて読みたい
【Python入門】クラス継承でコードを整理しよう【レッスン5-5】
【Python入門】クラス継承でコードを整理しよう【レッスン5-5】

<<前のページ

Flaskの記事一覧

次のページ>>

Jinja2のテンプレート継承とは?Flask開発を効率化する仕組みを解説

テンプレート継承とは、「共通部分(ベース)を定義して、他のテンプレートで使い回すことができる仕組み」です。

FlaskのテンプレートエンジンであるJinja2には、この機能が標準で備わっており、HTMLのヘッダーやフッター、サイドバーなどの繰り返し部分を一箇所にまとめることができます。

【Python】勉強猫がノートパソコンを前にして学習を始める様子。記事内の学習スタート用イラスト

複数ページで共通レイアウトを再利用する理由

  • 変更が必要な時、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 %}
【Python】勉強猫がノートパソコンを見ながら考え込む様子。記事内の休憩用イラスト

テンプレート継承の具体例|実践で学ぶ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側で定義しておけば、どのページも共通レイアウトになります。

コードを書いてみよう

上記の3つのHTMLコードと下記のPythonコードを保存し、実行してみましょう。

その際以下のような階層になるように保存してください。

任意のフォルダ/
├── app.py
└── templates/(フォルダ)
    ├── base.html
    ├── index.html
    └── about.html

使用するPythonコードは下記。ルート /about にアクセスすると、about.html が呼び出され、base.html を継承しつつ独自の内容を表示します。

from flask import Flask, render_template
app = Flask(__name__)

@app.route('/')
def index():
    # templates/index.html を表示する
    return render_template('index.html')

@app.route('/about')
def about():
    # templates/about.html を表示する
    return render_template('about.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開発が可能になります。

練習問題:自己紹介ページをテンプレート継承を使って作成しよう!

【Python】勉強猫がノートパソコンに向かい、練習問題に挑戦する様子。記事内の休憩用イラスト

後述するFlaskアプリとベーステンプレートが与えられているとします。

あなたはこのベーステンプレートを継承する profile.html を作成し、自己紹介ページを完成させてください。

この問題の要件

以下の要件に従ってコードを完成させてください。

  • templates/profile.html ファイルを新たに作成すること。
  • profile.htmlbase.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>

正解コード

例えば、以下のようなプログラムが考えられます。

Q
正解コード
{% extends 'base.html' %}

{% block content %}
  <h2>自己紹介</h2>
  <p>こんにちは!私はFlaskを勉強中のプログラマーです。</p>
  <p>Pythonは基本を学び終え、今はWebアプリを作る方法を学んでいます。</p>
{% endblock %}

<<前のページ

Flaskの記事一覧

次のページ>>

FAQ|Flaskテンプレート継承の使い方

Q
Q1. Jinja2で複数のテンプレートを継承させることはできますか?

可能です。ただし直接の多重継承は推奨されず、基本は1つの親テンプレートから継承する設計にします。必要に応じてインクルード機能(include)と組み合わせることで柔軟に構成できます。

Q
Q2. blockタグの中に別のblockを書くことはできますか?

いいえ、blockのネスト(入れ子)はJinja2の仕様上サポートされていません。複雑な構成が必要な場合は、複数のblockを使い分けてページを構成するようにしましょう。

Q
Q3. extendsで指定するファイルパスはどこからの相対パスですか?

extendsで使うテンプレート名は、Flaskのテンプレートフォルダ(通常はtemplates/)を基準としたパスです。拡張子(.html)も含めて記述するのが一般的です。

質問用コンタクトフォーム

この記事を書くにあたりAIを活用しています。

人間の目による確認も行っていますが、もし間違い等ありましたらご指摘頂けると大変助かります。

記事URLをコピーしました