テンプレートの拡張

Djangoの便利な機能の一つに、 テンプレートの拡張機能 があります。ウェブサイトを作る時、どのページでも同じHTMLタグを使うことがありますよね。たとえば、ヘッダーやフッター部分は、どのページでも同じものを使いませんか?そういう時に、便利な機能です。

この機能を使えば、ウェブサイトの共通部分(ヘッダーやフッター、メニューバーなど)に変更を加えたい時、全てのHTMLファイルに対して、同じ作業を繰り返さなくてすみます。一箇所だけ変更すれば、その変更は全てのページに適用されます。

ベースとなる骨組みのテンプレートファイルの作成

ベーステンプレートは、ウェブサイトの全てのページの骨組みともいうべきテンプレートです。

blog/templates/blog/ に、 base.html というファイル名で、ベーステンプレートファイルを作ってみましょう。

blog
└───templates
└───blog
base.html
post_list.html

base.html ファイルを開いて post_list.html の内容を全部 base.html にコピーしたら、以下の様になるでしょう。

{% load staticfiles %}
<html>
<head>
<title>Django Girls blog</title>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
<link href='//fonts.googleapis.com/css?family=Lobster&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="{% static 'css/blog.css' %}">
</head>
<body>
<div class="page-header">
<h1><a href="/">Django Girls Blog</a></h1>
</div>
<div class="content container">
<div class="row">
<div class="col-md-8">
{% for post in posts %}
<div class="post">
<div class="date">
{{ post.published_date }}
</div>
<h1><a href="">{{ post.title }}</a></h1>
<p>{{ post.text|linebreaks }}</p>
</div>
{% endfor %}
</div>
</div>
</div>
</body>
</html>

コピーしたら BODYタグ 部分を、以下の内容に書き換えましょう。 BODYタグ は、わかりますよね? <body> から </body> までの部分のことですよ。

{% block content %} {% endblock %}

基本的に、`

`の間を、以下の様に書き換えただけですね:

{% block content %}
{% endblock %}

どうしてこんな風に書くのか、考えてみましょう。 base.htmlblock を記述しました。そうすると、別のテンプレートの内容を、この block の部分に挿入することが出来るようになります。これが、テンプレートの拡張です。それでは、この block に挿入する post_list.html も修正してみましょう。

base.html を保存して blog/templates/blog/post_list.html を開きましょう。まず、BODYタグの中身以外は全て削除してしまいます。 <div class="page-header"></div> も削除してしまって、最終的には以下の様にします。

{% for post in posts %}
<div class="post">
<div class="date">
{{ post.published_date }}
</div>
<h1><a href="">{{ post.title }}</a></h1>
<p>{{ post.text|linebreaks }}</p>
</div>
{% endfor %}

修正出来たら、次の行をファイルの先頭に書き加えましょう。

{% extends 'blog/base.html' %}

こんな風にすると base.htmlblock 部分に post_list.html を組み込んで使うことが出来るという訳です。実際に block 部分に組み込むには、以下の様に `

` で囲わなくてはなりません。

{% extends 'blog/base.html' %}
{% block content %}
{% for post in posts %}
<div class="post">
<div class="date">
{{ post.published_date }}
</div>
<h1><a href="">{{ post.title }}</a></h1>
<p>{{ post.text|linebreaks }}</p>
</div>
{% endfor %}
{% endblock content %}

うまくテンプレート機能が動作しているか、ウェブサイトにを開いて確認してみましょう。

確認するとき blog/base.html が見当たらないという、 TemplateDoesNotExists のエラーが出るかもしれません。その場合は、コンソールで動いている runserver を一旦止めてみましょう。停止させるのは Ctrl-C (コントロールキーを押しながら'C'キーを押す) で、もう一度起動させるには python manage.py runserver コマンドを使います。