Flaskによる共通テンプレートの体験

# はじめに
Flaskにおける共通テンプレートの使用方法を記載します。
本記事を読むことで、Flaskの共通テンプレートってこういうものなんだなぁ、くらいの理解ができることをゴールとします。
共通テンプレートを学習する際の第一歩として本記事を見ていただけたら幸いです。

# 共通テンプレートとは
共通テンプレートとは、複数のページで共通する構造、記述をまとめて管理するテンプレートファイルです。
共通テンプレートを使用することにより、同じ内容を複数ファイルに記述しなくて済むため、効率的に開発したり、複数ページにわたる修正を簡略化できたりします。

## 例えば
Qiitaの画面で考えてみます。

Qiitaには、ホーム画面([https://qiita.com/](https://qiita.com/))やタイムライン画面([https://qiita.com/timeline](https://qiita.com/timeline))が存在します。
各画面は、見た目の構造はほぼ同じですが、URLから異なるファイルで生成されていることが見て取れます。
このような場合、共通する構造をテンプレートファイルとして用意しておき、異なる箇所だけファイルごとに記述して画面を作成することができます。
※実際にQiitaの画面がどのように作られているかは知りません。

# 実践
それでは、どのように共通テンプレートを使用するの実践していきます。
まず、共通テンプレートを使用しない場合のコードを確認します。
次に、同じ画面を共通テンプレートを使用して作成した場合のコードを確認します。

## 事前準備
- flaskのインストールは下記コマンドで実施してください。
```
pip install flask
```

- 下記内容で、app.pyを作成してください。
```app.py
from flask import Flask, render_template

app = Flask(__name__)

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

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

if __name__ == '__main__' :
    app.run()
```

## 共通テンプレートを使用しない場合
### 構成
```
.
├── app.py
└── templates
    ├── index.html
    └── hoge.html
```

### ファイル
下記内容でhtmlファイルを作成します。

```index.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <title>index</title>
</head>

<body>
    <div class="header">
        IndexHeader
    </div>
    <h1>インデックス</h1>
    <div class="footer">
        いんでっくすふったー
    </div>
</body>

</html>
```
```hoge.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <title>hoge</title>
</head>

<body>
    <div class="header">
        HogeHeader
    </div>
    <h1>ホゲ</h1>
    <div class="footer">
        ほげふったー
    </div>
</body>

</html>
```

### 実行
下記コマンドでサーバを開始します。
```
python app.py
```

### 実行画面
ブラウザのアドレスバーに http://127.0.0.1:5000/ を入力してindex.htmlに対応する画面を確認します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1237378/15b24cc1-8f8e-0955-5089-d8c6ddc328ba.png" width=80%>

続けて、 http://127.0.0.1:5000/hoge を入力してhoge.htmlに対応する画面を確認します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1237378/0cb86d19-f10d-a9f9-8baa-b6f3b247c8c4.png" width=80%>


次は、共通テンプレートを使用して画面を作成します。


## 共通テンプレートを使用する場合
### 構成
```
.
├── app.py
└── templates
    ├── index.html
    ├── hoge.html
    └── layout.txt
```

### ファイル
- 下記内容でlayout.htmlを作成します。
```layout.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <title>{% block title %}{% endblock  %}</title>
</head>

<body>
    <div class="header">
        {% block header %}{% endblock  %}
    </div>
    <h1>{% block content %}{% endblock  %}</h1>
    <div class="footer">
        {% block footer %}{% endblock  %}
    </div>
</body>

</html>
```

ここで注目したいのが、「{% block XXXXX %}{% endblock  %}」の記述です。
この箇所に設定したい値を、各htmlファイルで記述していきます。
**共通テンプレートに「{% block XXXXX %}{% endblock  %}」と書いておけば、取り込んだ他のhtmlファイル内で値を設定できる**、ということです。


では、共通テンプレートを取り込む各htmlファイルを下記内容で作成します。

```Django:index.html
{% extends 'layout.html' %}

{% block title %}
index
{% endblock  %}

{% block header %}
IndexHeader
{% endblock header %}

{% block content %}
インデックス
{% endblock  %}

{% block footer %}
いんでっくすふったー
{% endblock  %}
```

```Django:hoge.html
{% extends 'layout.html' %}

{% block title %}
hoge
{% endblock  %}

{% block header %}
HogeHeader
{% endblock header %}

{% block content %}
ホゲ
{% endblock  %}

{% block footer %}
ほげふったー
{% endblock  %}
```

各ファイルとも、使用する共通テンプレートを以下の記述で指定しています。
```django
{% extends 'layout.html' %}
```
記述の方法は、extendsの後に、共通テンプレートファイル名を指定してあげればOKです。

次に、共通テンプレートの「{% block XXXXX %}{% endblock %}」の位置に表示したい値を記述します。
記述は、値を「{% block XXXXX %}」と「{% endblock %}」囲むことで表示できます。
例えば、共通テンプレートの「{% block title %}{% endblock %}」に値を表示したい場合は、取り込んだhtml内では以下のように記述をします。
```django
{% block title %}XXXXX{% endblock  %}
```

### 実行
下記コマンドでサーバを開始します。
```
python app.py
```

### 実行画面
index.html、hoge.htmlともに共通テンプレートを使用しない場合と同じに表示になりました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1237378/15b24cc1-8f8e-0955-5089-d8c6ddc328ba.png" width=80%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1237378/0cb86d19-f10d-a9f9-8baa-b6f3b247c8c4.png" width=80%>

# 最後に
覚えてしまえば共通テンプレートを使用した方が簡単にhtmlファイルを作れると感じました。


# 参考
- https:\//shigeblog221.com/python-flask5/