Andy McKay

Nov 15, 2007

Django Tutorial for Page Templates (Part 1)


This tutorial is a re-writing of the Django Tutorial in the documentation on the Django website. In this I step through the same tutorial covering the templating sections, but focusing on how they would look using Page Templates instead of the Django templating language.

The demo code and so on is from that site and all credit to the authors of that tutorial. As ever all mistakes are mine.

To run the code in this demo, you'll need Simple TAL and Simple Template. Check out Simple Template from here and follow the readme contained within that directory:

svn co http://svn.clearwind.ca/public/django/simpletemplate

If you don't fancy typing everything in, then please checkout code used in these examples from:

svn co http://svn.clearwind.ca/public/django/polltutorial

Already to go. Then start following through the tutorial and through parts one and two. Neither of these touch on templating at all so nothing relevant to us there. Tutorial three is where the fun starts to happen, in the section Write views that actually do something.

Simple template provides key api calls for rendering templates, that you can use instead of the builtin ones. Instead of:

from django.template import Context, loader

Use:

from django.contrib.simpletemplate.public import get_template

Instead of the given example, use:

from django.contrib.simpletemplate.public import get_template
from django.template import Context
from mysite.polls.models import Poll
from django.http import HttpResponse

def index(request):
    latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5]
    t = get_template('polls/index.pt')
    c = Context({
        'latest_poll_list': latest_poll_list,
    })
    return HttpResponse(t.render(c))

The key changes here are line 1, with that different import. Also on line 8 we are no longer using index.html, we are using a Page Template which follows a convention established from Zope of .pt as extension so we'll call ours index.pt.

The index.pt looks like the following:

<tal:block tal:condition="latest_poll_list">
    <ul>
        <li tal:repeat="poll latest_poll_list"
               tal:content="poll/question">question</li>
    </ul>
</tal:block>
<tal:block tal:condition="not: latest_poll_list">
    <p>No polls are available.</p>
</tal:block>

If you are familiar with TAL then this will hopefully make sense. The next step covers using "A shortcut: get_object_or_404()", this is relatively straightforward, to use the render_to_response replace the current import with the following:

from django.contrib.simpletemplate.public import render_to_response

Just remember to point to a .pt template, not a .html one.

And finally in tutorial three there is one more example that covers the detail view. Here's how detail.pt looks in Page Templates:

<h1 tal:content="poll/question">Poll Question</h1>
<pre>
<p tal:condition="error_message|nothing">
    <strong tal:content="error_message">Error</strong>
</p>

<form action="" 
         tal:attributes="action string:/polls/${poll/id}/vote/" 
         method="post">
    <tal:block tal:repeat="choice poll/choice_set/all">
        <input type="radio" name="choice" 
                tal:attributes="for string:choice${choice/index};
                value choice/id" />
        <label tal:attributes="for string:choice${choice/index}"
                tal:content="choice/choice">The choice<label><br />
    </tal:block>
    <input type="submit" value="Vote" />
</form>

And that's it, on to tutorial four in another day.