iMind Developers Blog

iMind開発者ブログ

Flaskでテンプレートのincludeやextends

概要

Flask+Jinjaテンプレートでincludeやextendsを用いてデザインを共通化する。下記を実装。

  • 要素の一部をパーツ化して読み込む(include)
  • HTMLの大枠の部分を共通化する(extends)

バージョン情報

  • Flask==1.1.1

サンプルHTML

こんなHTMLがあったとする。

<!DOCTYPE html>

<html>

  <head>
    <script type="text/javascript">// ここの中身個別実装</script>
  </head>

  <body>

    <header>共通ヘッダ</header>

    <div class="title">タイトルA</div> <!-- ここ個別実装 -->

    <div>
      <div class="content">ここ、コンテンツ</div> <!-- ここ個別実装! -->
      <div class="part1">共通パーツ1</div>
      <div class="part1">共通パーツ2</div>
    </div>

    <footer>共通フッタ</footer>

  </body>

</html>

こんな感じでスクリプト、タイトル、コンテンツの3つのポイントを個別に実装し、それ以外のところは共通化したい。

include

includeはテンプレートのパーツを読み込める。

下記2つのパーツを作成。

parts1.html

<div class="part1">共通パーツ1</div>

parts2.html

<div class="part2">共通パーツ2</div>

これを親のテンプレートから include で読み込む。

(略)

    <div class="title">タイトルA</div> <!-- ここ個別実装 -->

    <div>
      <div class="content">ここ、コンテンツ</div> <!-- ここ個別実装! -->
      {% include parts1.html %}
      {% include parts2.html %}
    </div>

(略)

これで include を記述した場所に parts1.html, parts2.html が記述した情報が

extends

extends はベースになる枠組みを継承する。

まずは親になるテンプレートを作成する。個別実装したい箇所は {% block name %} を指定しておく。

frame.html

<!DOCTYPE html>

<html>

  <head>
    {% block script %}{% endblock %}
  </head>

  <body>

    <header>共通ヘッダ</header>

    <div class="title">{% block title %}{% endblock %}</div> <!-- ここ個別実装 -->

    {% block content %}{% endblock %}

    <footer>共通フッタ</footer>

  </body>

</html>

これを extends して block で指定した部分だけ実装する。

{% extends 'frame.html' %}

{% block script %}
  // スクリプトの実装
{% endblock %}

{% block title %}ログイン{% endblock %}

{% block content %}
  <div>
    <div class="content">ここ、コンテンツ</div> <!-- ここ個別実装! -->
    {% include "parts1.html" %}
    {% include "parts2.html" %}
  </div>
{% endblock %}

これでサンプルHTMLの同じ内容が出力できる。

extendsとsuper

extendsは名前の通り継承するので、継承した側で実装しなければ親テンプレートの内容が利用される。

parent.html

<html>
  <title>
    {% block example %}
      | サイト名
    {% endblock %}
  </title>
</html>

何も記述しなかった場合。

{% extends 'parent.html' %}

prent.htmlの内容がそのまま表示される

<html>
  <title>
    
      | サイト名
    
  </title>
</html>

blockに記述した場合。

{% extends 'parent.html' %}

{% block example %}
  ページタイトル
{% endblock %}

blockの中身がchildで指定した値になる。

<html>
  <title>
    
  ページタイトル

  </title>
</html>

childのblock内でsuperを呼び出してみる。

{% extends 'parent.html' %}

{% block example %}
  ページタイトル {{ super() }}
{% endblock %}

superした部分に親のブロックで記述した値が出力される。

<html>
  <title>
    
  ページタイトル | サイト名

  </title>
</html>

改定履歴

Author: Masato Watanabe, Date: 2020-02-01, 記事投稿