MENU

HTMLテンプレートのレイアウトを共通化しよう!(テンプレートの継承)【Flask初心者講座その6】

Flaskを使ったアプリケーション開発では、複数のHTMLページが似たようなレイアウトを持つことがよくあります。

例えば、ヘッダーやフッター、ナビゲーションバーなど、ページ全体に共通する部分がある場合などが言えます。このように共通部分を毎回手動で書くのは効率が悪く、エラーの元にもなります。そこで、Flaskのテンプレートエンジン「Jinja2」を活用し、HTMLテンプレートを継承して共通部分を一元管理する方法を学びましょう。

ベーステンプレートを作る

こんな感じでサイトを簡易サイトを作ってみました。もちろん飲食店などのサイトはCSSなどを使いますが、今回はflaskがメインなので省きます。

ほかのページを作りたいとき、もし、赤いブロックの外以外は使いまわすとして、使いまわすところをすべてのページに毎回コピペしてしまうと、後から修正するのが大変になります。例えば、ナビゲーションのリンクを1つ追加したい場合、全ページのHTMLを修正しなければならないのは非効率です。

Flaskのテンプレート継承では、「親テンプレート(ベーステンプレート)」を作成し、各ページがそれを継承することで、共通レイアウトを再利用できます。

  • 親テンプレート(base.html):全ページ共通の部分を定義(ヘッダー、フッターなど)
  • 子テンプレート(home.html、menu.html など):ページごとの内容だけを記述

個テンプレートには共通するところ以外の内容を赤いブロックの中に書けばいいですよね。

base.html ↓

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}飲食店のホームページ{% endblock %}</title>
</head>
<body>
    <header>
        <h1>美味しいレストラン</h1>
        <nav>
            <ul>
                <li><a href="/">ホーム</a></li>
                <li><a href="/">メニュー</a></li>
                <li><a href="/">お問い合わせ</a></li>
            </ul>
        </nav>
    </header>

    <main>
        {% block content %}{% endblock %}
    </main>

    <footer>
        <p>営業時間: 11:00 - 22:00 | 電話: **-****-****</p>
    </footer>
</body>
</html>

この base.html の中で、子テンプレートに継承される部分は {% block title %}{% block content %} 2か所の中の部分です。

子テンプレートで継承する

my_flask_app/            # プロジェクトのルートディレクトリ
│── app.py               
│── /templates/         
│   │── base.html        # 共通レイアウトのベーステンプレート
│   │── home.html        #子テンプレート

↑のようなディレクトリ構成の時、子テンプレートはhome.htmlだとして継承していきたいと思います。

templates/home.html

{% extends "base.html" %}

{% block title %}美味しいレストラン{% endblock %}

{% block content %}
    <h2>ようこそ!</h2>
    <p>当店は新鮮な食材を使った料理を提供しています。ぜひご来店ください!</p>
{% endblock %}

{% extends "base.html" %} を使うことで、base.html のレイアウトを継承しています。
その上で、{% block title %}{% block content %} を使って、ページごとの内容を上書きします。

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def home():
    return render_template('home.html')

if __name__ == '__main__':
    app.run(debug=True)

app.pyはこんな感じにして実際に表示してみると、

これで赤いブロック以外はしっかりと持ってこれていますね。実際に自分で何ページも書いてみると、この機能のありがたみがわかってくると思うので、ぜひ使う癖をつけてくださいね。

(赤いブロックに関しては説明用でcssをつけてますので、皆さんのコードでは赤いブロックは出てきませんのでご注意ください)

まとめ

サイト規模ページ数修正の手間(テンプレートなし)修正の手間(テンプレートあり)
小規模5ページすべてのHTMLを手作業で修正base.html だけ編集でOK
中規模30ページ30ファイルを修正する必要ありbase.html だけ編集でOK
大規模100ページ以上修正がほぼ不可能レベルbase.html の修正で一括反映

大規模サイトになるほど、テンプレート継承なしでは破綻する のがよく分かります。
もし100ページあったら、ナビゲーションメニューを変更するだけでも100ファイルを修正しなければなりませんが、
テンプレート継承を使えば、修正が一瞬で終わります!ぜひこの機能は脳に刻んでください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!