Here's how to dodge some of the more obvious template pitfalls: == Debugging == Not a pitfall, but a tip: Use {% debug %} in a template block if you want to know what is defined and can be used in a template. The debug output is pretty ugly unless you look at it through View Source, or you can do it this way: {{{ {% filter linebreaks %} {% debug %} {% endfilter %} }}} or more simply: {{{
{% debug %}
}}}
== Anonymity ==
{{{user.is_anonymous}}} is a method, not an attribute, which makes it hard to test against in a template. Set your own context variable {{{is_anonymous}}}, instead.
== Context variables and template inheritance ==
To solve ''Anonymity'' above, it's handy to define a method each view can call to fill in its {{{Context}}} with the right variables. If you're inheriting templates, you should also do the same with the method. I've ended up with an {{{app_vars}}} method in each app's views module which calls {{{site_vars}}} in the site.
{{{site_vars}}} goes in {{{sitename/views/sitename.py}}} if you're trying to match the default shape of the application namespace, or in {{{sitename/views.py}}} if you're flattening it:
{{{
def site_vars(request, **kwargs):
"""Determine context variables for the site's base template."""
user = request.user
is_anonymous = user.is_anonymous()
if is_anonymous:
username = name = '(anonymous)'
else:
username = user.username
name = user.get_full_name()
if not name:
name = username
vars = {
'is_anonymous': is_anonymous,
'name': name,
'username': username,
}
vars.update(kwargs)
return vars
}}}
A custom version of {{{app_vars}}} goes in each {{{sitename/apps/appname/views/appname.py}}} (or, if you're flattening the namespace, {{{sitename/apps/appname/views.py}}}):
{{{
def app_vars(request, **kwargs):
"""Determine context variables for the application and site base templates."""
vars = {} # set your app variables here
vars.update(site_vars(request, **kwargs))
return vars
}}}
The keyword arguments let you define additional useful variables for your page without having to further manipulate the dictionary: just keep piling on the arguments to {{{app_vars}}}. Let's say your base template likes to have a {{{title}}} variable available to it:
{{{
def index(request):
"""View the appname index."""
# Customise the app variables the hard way
vars = app_vars(request)
vars['title'] = "Index"
# Or, the easy way
vars = app_vars(request, title="Index")
# Load the template, construct the context, and render one against the other:
t = template_loader.get_template('appname_index')
c = Context(request, vars)
return HttpResponse(t.render(c))
}}}