The templating system in django is extremely powerful, we will only be using a small handful of its functionality in this example.

Firstly, lets create our base template. This is just a very basic example, which is not valid XHTML. This template alone doesn't do a great deal.

base.html

<html>
    <head>
        <title>{% block head_title %}Welcome to my blog{% endblock %}</title>
    </head>
    <body>
        <h1>{% block title %}Welcome to my block{% endblock %}</h1>
        {% block content %}

        {% endblock %}
    </body>
</html>

index.html

{% extends 'base.html' %}
{% block title %}Welcome to my blog{% endblock %}

{% block content %}
    <h2>Categories</h2>
    {% if categories %}
        <ul>
        {% for category in categories %}
            <li><a href="{{ category.get_absolute_url }}">{{ category.title }}</a></li>
        {% endfor %}
        </ul>
    {% else %}
        <p>There are no posts.</p>
    {% endif %}

    <h2>Posts</h2>
    {% if posts %}
        <ul>
        {% for post in posts %}
            <li><a href="{{ post.get_absolute_url }}">{{ post.title }}</a></li>
        {% endfor %}
        </ul>
    {% else %}
        <p>There are no posts.</p>
    {% endif %}

{% endblock %}

view_post.html

{% extends 'base.html' %} 
{% block head_title %}{{ post.title }}{% endblock %}
{% block title %}{{ post.title }}{% endblock %}

{% block content %}
    {{ post.body }}
{% endblock %}

view_category.html

{% extends 'base.html' %} 
{% block head_title %}Viewing category {{ category.title }}{% endblock %}
{% block title %}{{ category.title }}{% endblock %}

{% block content %}
    {% if posts %}
        <ul>
        {% for post in posts %}
            <li><a href="{{ post.get_absolute_url }}">{{ post.title }}</a></li>
        {% endfor %}
        </ul>
    {% else %}
        <p>There are no posts.</p>
    {% endif %}
{% endblock %}

So, what does all this do?

In the base.html we are defining the base content, <html>, <body> etc, as well as the blocks we would like to display. The content for these is output based on the content that extends the base template.

On the first line of all three of the other files you will notice

{% extends 'base.html' %}

This line calls the base.html template file. Inside this we define the blocks very much the same way as in the base.html file, however this time we add the content we want to display. Using the example from index.html

We define the block for content,

{% block content %}
    ...
{% endblock %}

Inside here we are checking if there are an categories. The variables we use here were defined in the views.py file in the render_to_response function.

{% if categories %}
    ....
{% else %}
    <p>There are no posts.</p>
{% endif %}

If there are categories, the following is run

<ul>
    {% for category in categories %}
        <li><a href="{{ category.get_absolute_url }}">{{ category.title }}</a></li>
    {% endfor %}
</ul>

This will loop the response from the Category model as defined in views.py, and print out the results that are entered into the database.

Now that you have a rather basic blog working, or at least I hope so, you might want to check out one of our more advanced tutorials, or have a browse of the Hints & Tips section.