Djangoメモ(13) : extendsとblockでテンプレートの継承
A Complete Beginner's Guide to Djangoのチュートリアルを参考にテンプレートを継承してみる。
親テンプレート作成と継承
テンプレートに共通部分がある場合は共通部分を親テンプレートとして定義し、子テンプレートに個別の処理を記述するのがメンテンナンスしやすい。
最初に親テンプレートとなるtemplates/base.html
を下記内容で新規作成する。
{% load static %}<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>{% block title %}Django Boards{% endblock %}</title> <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}"> </head> <body> <div class="container"> <ol class="breadcrumb my-4"> {% block breadcrumb %} {% endblock %} </ol> {% block content %} {% endblock %} </div> </body> </html>
{% block %}
, {% endblock %}
は領域を確保するタグで、子テンプレートでこのblock内のHTMLを置き換えることができる。
{% block title %}Django Boards{% endblock %}
のようにデフォルト値を指定することもでき、子テンプレートで何も設定されない場合はこのデフォルト値が使用される。
続いて、親テンプレートを継承するようにtemplates/home.html
とtemplates/topics.html
を編集する。
templates/home.html
は以下の通り。
{% extends 'base.html' %} {% block breadcrumb %} <li class="breadcrumb-item active">Boards</li> {% endblock %} {% block content %} <table class="table"> <thead class="thead-dark"> <tr> <th>Board</th> <th>Posts</th> <th>Topics</th> <th>Last Post</th> </tr> </thead> <tbody> {% for board in boards %} <tr> <td> <a href="{% url 'board_topics' board.pk %}">{{ board.name }}</a> <small class="text-muted d-block">{{ board.description }}</small> </td> <td class="align-middle">0</td> <td class="align-middle">0</td> <td></td> </tr> {% endfor %} </tbody> </table> {% endblock %}
最初の行の{% extends 'base.html' %}
タグは親テンプレートとしてbase.html
を継承することを意味している。
そして{% block breadcrumb %}
内の<li class="breadcrumb-item active">Boards</li>
が親テンプレートの{% block breadcrumb %}
に挿入されることになる。
templates/topics.html
は以下の通り。
{% extends 'base.html' %} {% block title %} {{ board.name }} - {{ block.super }} {% endblock %} {% block breadcrumb %} <li class="breadcrumb-item"><a href="{% url 'home' %}">Boards</a></li> <li class="breadcrumb-item active">{{ board.name }}</li> {% endblock %} {% block content %} <!-- just leaving it empty for now. we will add core here soon. --> {% endblock %}
{% block title %}
タグでデフォルト値から変更しているが、{{ block.super }}
で親テンプレートのデフォルト値を再利用できる。結果として、board.name
が"Python"の場合は"Python - Django Boards"になる。これでテンプレートの継承は完了。
ナビゲーションバー追加
ナビゲーションバー(BootstrapのNavbarを利用)を追加するためにtemplates/base.html
を以下のように編集。
{% load static %}<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>{% block title %}Django Boards{% endblock %}</title> <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}"> </head> <body> <nav class="navbar navbar-expand-lg navbar-dark bg-dark"> <div class="container"> <a class="navbar-brand" href="{% url 'home' %}">Django Boards</a> </div> </nav> <div class="container"> <ol class="breadcrumb my-4"> {% block breadcrumb %} {% endblock %} </ol> {% block content %} {% endblock %} </div> </body> </html>
ページにアクセスするとナビゲーションバーが追加されている。
このように共通で使用する要素を親テンプレートに定義すると便利。
参考:フォント変更
チュートリアルではフォント変更をしているのでナビゲーションバーのロゴ部分(.navbar-brand
)のフォントを変更してみる。
Google Fontsにアクセスして自分の好きなフォントを選択する。
チュートリアルではPeralta
を使っているがPacifico
を使ってみる。
図のように追加方法が表示されるのでtemplates/base.html
を編集。
<head> <meta charset="utf-8"> <title>{% block title %}Django Boards{% endblock %}</title> <link href="https://fonts.googleapis.com/css?family=Pacifico" rel="stylesheet"> <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}"> <link rel="stylesheet" href="{% static 'css/app.css' %}"> </head>
css/app.css
を下記内容で新規作成。
.navbar-brand { font-family: 'Pacifico', cursive; }
これでフォントが変わる。
まとめ
- テンプレートの共通部分は親テンプレートにまとめる
{% extends 'base.html' %}
は親テンプレートとしてbase.html
を継承{% block %}
,{% endblock %}
で領域を確保し、子テンプレートで該当ブロックを置き換える{% block %}
にはデフォルト値を指定することも可能{{ block.super }}
で親テンプレートのデフォルト値を参照可能