日記

日々のことと、Python/Django/PHP/Laravel/nodejs などソフトウェア開発のことを書き綴ります

テンプレートの共通化

テンプレートの使い方も一歩進めてみます。

DRY

テンプレートと言えども、DRYに従って実装を進めたいものです。
DjangoのTemplateでは、カスタムタグに加えて、includeやテンプレートの継承をサポートしています。

include

includeは、カスタムタグとして実装がされています。使い方は、テンプレートファイルの中で

{% include "template_name.html" %}

これだけです。
includeされたテンプレートファイルの中からも Contextの値は参照できるので、本当にファイルを分割する用途で使用できます。

ちなみにContextは参照できますが、カスタムタグのloadはそれぞれのテンプレートファイルの中で、再度ロードしないと使用できなくなっています。

テンプレートを継承する (extends)

テンプレートファイルはインクルードではなく、ベーステンプレートを作っておいて、コンテンツ部に別の内容を当て込むような使い方もできます。これをテンプレートの継承と呼ぶそうです。

まずベースになるテンプレートを用意しますが、普通のテンプレートファイルとは少し異なります。マニュアルのサンプルから抜粋したテンプレートは下記のようになっています。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <link rel="stylesheet" href="style.css" />
    <title>{% block title %}My amazing site{% endblock %}</title>
</head>

<body>
    <div id="sidebar">
        {% block sidebar %}
        <ul>
            <li><a href="/">Home</a></li>
            <li><a href="/blog/">Blog</a></li>
        </ul>
        {% endblock %}
    </div>

    <div id="content">
        {% block content %}{% endblock %}
    </div>
</body>
</html>

これをみると {% block %}という箇所があると思います。このblockという部分に任意の値を嵌め込むことができるわけです。では、このベーステンプレートに対応した拡張テンプレートを見てみると

{% extends "base.html" %}

{% block title %}My amazing blog{% endblock %}

{% block content %}
{% for entry in blog_entries %}
    <h2>{{ entry.title }}</h2>
    <p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}

こんな感じになっています。まず、{% extends "base.html" %}として、継承することを定義します。
次に、{% block xxx %}のxxxが拡張ポイントなっているので、継承する側も{% block xxx %}から{% endblock %}までに定義した内容が、拡張元(base.html)の中に展開されます。
ちなみに継承元の blockタグの中は、継承先で定義が無かったときに使用されます。

ちなみに Contextの利用方法も includeの時と同じで、普通のテンプレートと同じように利用できます。また、カスタムタグについても include のときと同じです。

テンプレートの Tips

ちなみに各々のテンプレートファイルでカスタムタグやフィルタを load するのめんどいぜ!というときは以下のコードを settings.pyの最後にでも書いてしまいましょう。

  from django import template
  template.add_to_builtins('project.app.templatetags.custom_tag_module')

これで自動的に全てのテンプレートファイルでカスタムタグが利用できるようになります。

まとめ

  • テンプレートには継承とincludeの二つの共通化方式がある。
  • 継承は全体のレイアウト、includeはガジェット的な枠に使うとよさそう


次回はそろそろ Model に入っていきたいと思います。やっとだよ。