【Python】Flask入門 テンプレートをextends(継承)して共通化する方法

Flask

はじめに

しげっち
しげっち

Flaskの機能であるextendsの使用方法について解説するよ!

Webページを作成していく上で、共通のレイアウトで構成された複数のページを作成することがあると思います。

共通のレイアウト部分に手を加えることになった場合、ページの数だけ修正していく必要があり、非常に非効率です。

Flaskでは、共通のレイアウト部分をベースのファイルに記述し、そのベースを継承(extends)してWebページを作成することができます。

そうすることで、共通のレイアウト部分は一箇所修正するだけとなり、継承先のページは差分だけ記載すればよくなります。

Flask学習におすすめの本を紹介します。
⇨【Python】Flask入門におすすめの本 3選

フォルダ構成について

下記のフォルダ構成を例に説明していきます。

.
├── app.py     :pythonファイル
├── static
│   └── style.css :CSSファイル
└── templates
    ├── index.html :サンプルページ1
    └── second.html :サンプルページ2

まずはapp.pyファイルを下記のように記載します。

rom flask import Flask, render_template

app = Flask(__name__)

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

@app.route('/second')
def second():
    data = ['ABC','DEF','GHI']
    return render_template('second.html', data = data)

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

次にstyle.cssを記載します。

body{
    margin: 10px;
    background-color: whitesmoke;
}

h1{
    color: blue;
    font-size:34pt;
}

p{
    font-size:14pt;
}

pre {
    background-color: white;
    font-size: 11pt;
    padding:12
}

div.footer{
    margin: 50px 0px;
}

次にextendsを使用しない場合と使用した場合の違いを見ていきますが、
どちらの場合でも、上記で記載したapp.pystyle.cssファイルの内容は同一となります。

extendsを使用しない場合

まずはextendsを使用しない場合の記載方法を見ていきます。

index.htmlを下記のように記載します。

<!DOCTYPE html>
<html lang="jp">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet"
        href="{{url_for('static', filename='style.css')}}">
   <title>トップページ</title>
</head>
<body ></body>
    <h1>インデックスページです</h1>
    <p>トップページのサンプル</p>
    <div class="footer">
        copyright 2021 hogehoge
    </div>
</body>
</html>

続いてsecond.htmlです。

<!DOCTYPE html>
<html lang="jp">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet"
    href="{{url_for('static', filename='style.css')}}">
    <title>セカンドページ</title>
</head>
<body>
    <h1>セカンドページです</h1>
    <p>セカンドページのサンプル</p>
    <pre>{{ data }}</pre>

   <div class="footer">
        copyright 2021 hogehoge
    </div>
</body>
</html>

これを実行すると下記の様な2つのページになります。

index.htmlsecond.htmlの中身を見比べてみてください。
どちらにもCSSの読み込み、h1タグ、pタグ、footerの記述があります。

仮にh1タグをh2タグに修正するとなるとそれぞれのファイルを修正する必要が出てきます。
例では2つのファイルだけですが、これが4つ、5つとなってくると大変な作業となります。

にゃーすけ
にゃーすけ

共通のレイアウトはなるべく一箇所にまとめたいにゃ

そこでextendsの出番です。

extendsを使用する場合

しげっち
しげっち

まずは、共通のレイアウトを一箇所にまとめたファイルを作成しよう!

<!DOCTYPE html>
<html lang="jp">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet"
    href="{{url_for('static', filename='style.css')}}">

    <title>{% block title %}{% endblock %}</title>
</head>
<body>
    <h1>{% block head %}{% endblock %}</h1>

    {% block content %}{% endblock %}

    <div class = 'footer'>
        {% block footer %}{% endblock %}    
    </div>
</body>
</html>

layout.htmlという名前で作成しました。
このファイルの中で、これまでにない記載があります。

{% block xxxx %}{% endblock %}

このブロックの位置に、継承先のファイル(index.htmlまたはsecond.html)は独自の内容を表示させることができます。

これだけでは分かり辛いと思いますので、実際にindex.htmlを記載してみます。

{% extends "layout.html" %}
        
{% block title %}
トップページ
{% endblock %}

{% block head %}
インデックスページです
{% endblock %}

{% block content %}
<p>トップページのサンプル</p>
{% endblock %}

{% block footer %}
copyright 2021 hogehoge
{% endblock %}

extends(継承)をしない場合のindex.htmlの内容と比べるとかなりすっきりしました。

{% extends “layout.html” %}

最上部に記載があるextendslayout.htmlを指定しています。
こうすることで、layout.htmlで記載したベースとなるhtmlの内容がindex.htmlに反映されるようになります。

htmlタグ、headタグ、bodyタグといった基本的な構文もlayout.htmlから反映されるので、index.htmlに記載する必要がありません。

2行目以降のブロックにはそれぞれ名前がつけられています。

{% block title %} titleという名前
{% block footer %} footerという名前

例えば、layout.htmlにある{% block title %} の箇所に
index.htmlに記載した{% block title %}の内容が反映されます。

実行すると下記のように表示されます。

CSSの内容もきちんと反映されていますね。

ブラウザからページのソースを確認してみましょう。
下記のようにindex.htmlで記載した内容にlayout.htmlの内容が継承されて、
きちんとしたhtmlが出来上がっています。

それでは、もう一つのページであるsecond.htmlも記載してみましょう

{% extends "layout.html" %}

{% block ti %}
セカンドページ
{% endblock %}

{% block head %}
セカンドページです
{% endblock %}

{% block content %}
<p>セカンドページのサンプル</p>
<pre>{{ data }}</pre>
{% endblock %}

{% block footer %}
copyright 2021 hogehoge
{% endblock %}

共通のレイアウト部分をlayout.htmlに移行したことでこちらもかなりシンプルになりましたね。

まとめ

今回はFlaskの機能の一つであるextends(継承)について解説しました。
extendsを使用した場合と使用しない場合で、記述量にかなり差があることがご理解いただけたと思います。

前回はhtml側でif文やfor文を使用する方法について解説しました。

しげっち
しげっち

最後まで見ていただきありがとうございます。

Flask学習におすすめの本を紹介します。
⇨【Python】Flask入門におすすめの本 3選

次回はフィルターについて解説します。

Flask入門まとめページ

タイトルとURLをコピーしました