tags:

views:

144

answers:

4

I'm curious as to the best-practise way to handle having something appear on every page, or on a number of pages without having to assign the data manually to every page like so:

# views.py

def page0(request):
    return render_to_response(
        "core/index.html",
        {
            "locality": getCityForm(request.user),
        },
        context_instance=RequestContext(request)
    )

def page1(request):
    return render_to_response(
        "core/index.html",
        {
            "locality": getCityForm(request.user),
        },
        context_instance=RequestContext(request)
    )
...
def page9(request):
    return render_to_response(
        "core/index.html",
        {
            "locality": getCityForm(request.user),
        },
        context_instance=RequestContext(request)
    )

Now I can think of a few ways to do this, including writing my own Context or maybe some middleware, and of course, copy/pasting this locality assignment on every page... I'm just not sure of the best way to do this. I'm pretty sure that it's not that last one though.

+2  A: 

use inheritance in the templating engine:

have a base.html that includes the common code:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<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>

then in each page that needs that common code, simply:

{% 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 %}

http://docs.djangoproject.com/en/dev/topics/templates/#id1

this combined with context processessing will eliminate a lot of duplicate code.

bigjust
You don't address the issue he shows in the question: view code duplicated in many views.
Ned Batchelder
thats exactly what view code inheritance addresses.
bigjust
Actually, it's both! It's a floor wax *and* a dessert topping! We use a combination of context processors and a multi-level template inheritance scheme. The context processors give us the data across all of our views and the template inheritance means that the data lands in the right place on the page.
Peter Rowell
+2  A: 

Middleware is one option or your could write a custom template tag.

Mark Lavin
+11  A: 

You want a context processor. The data they generate is included in every context created as a RequestContext. They are perfect for this.

Combined with base templates that show common things, you can get rid of lots of need for copying and pasting code.

Ned Batchelder
A: 

To do exactly what you request, I'd simply define a function:

def foobar(req):
    return render_to_response(
        "core/index.html",
        {
            "locality": getCityForm(req.user),
        },
        context_instance=RequestContext(req)
    )

put it in some module myfun, and return myfun.foobar(request) wherever needed. You're likely to want a few more arguments, but as long as it stays about this simple, it's simpler that defining middleware, using OOP, &c.

Alex Martelli