Django template inheritance

Posted June 2009

This site is (EDIT 2016: was) built on django – a python-based web framework. Although it’s not technically my first django outing, it’s the first of any substance, and I continue to be impressed at every point. The learning curve is a bit steeper, especially coming from a mainly PHP background but I’m a big fan of Python anyway, and the templating is second to none.

Template inheritance

Got to love this really. Seems pointless at first - as does Object Orientated Programming perhaps - but in the same way once you start using it, you wonder why everyone isn’t and exactly what you were wasting your time with before. The conciseness of a template using inheritance is pretty impressive.

Example template

The first version of the blog index page is just this:

{% extends "layout.html" %}
{% load markup %}
  
{% block content %}
{% for post in latest %}
    <h3>{{ post }}</h3>
    <p>{{ post.body|textile }}</p>
    <small>
        {{ post.author }} wrote {{ post.body|wordcount }} words
        on {{ post.date_created|date }} at {{ post.date_created|time }}
    </small>
    {% endfor %}
{% endblock %}

I still find it hard to believe that can be the extent of the template, but therein lies the power of inheritance. By only overriding the content block (defined in the layout), we can leave the other sections - HTML structure, any Javascript, navigation, side panes / modules to the defaults set up in the layout. If, however, we do want to change it - say we want some relevant posts or comments in the side column, it’s as simple as another {%block side%}. Magic!

Even cooler is the use of the superclass (a bit like calling parent.method() in php or java) from the a view template. For example, to add a stylesheet into the layout for one page (view) only:

{% extends "layout.html" %}
{% block css %}
  {{ block.super }}
   <!-- include CSS just for this page -->
  <link rel="stylesheet" type="text/css" href="/style/extra-page-stylesheet.css"></link>
{% endblock %}
  
{% block content %} 
   My page content blah blah...
  <br />
{% endblock %}

Now that really is cool, n’est-ce pas?