Is there a Django template tag that lets me set a context variable?

The answer is buried inside the more complex current_time example in the documentation.

Problem

You want to add a variable to the context. But you don’t want to go back and add that variable to all the views which call all the templates which invoke the tag. You just want a tag which can add some data to the context wherever its wanted. I’m looking for this kind of thing when rendering those random distractions which get dropped into sidebars and aren’t specifically related to the work of the main view, for example.

Method

To inject a variable to the context you need access to the context. To do that your custom tag will inject a node which added the data to the template context.

Example

This example adds a “coming_events” queryset to the context then loops over each result. It does that by declaring a custom tag which renders a node which adds a queryset to the context.

from django import template
from apps.events.models import Event
register = template.Library()

@register.tag
def coming_events(parser, token):
    return EventNode()

class EventNode(template.Node):
    def render(self, context):
        context['coming_events'] = Event.objects.all()
        return ''

You’d use it like this:

{% load events %}
{% coming_events %}
{% for event in coming_events %}
<div class="eventItem">
   <p>{{event.title}} {{event.data}}</p>
</div>
{% endfor %}

Extra Credit

If you’re really keen to be able to name the variable arbitrarily eg {% coming_events as events %} then look closely at the example in the documentation and note how they split the token into what’s before the ‘ as ‘ and what’s after and use the latter part to name the context variable. You’d have to implement that.

Note that if I wound up putting the HTML for each event into its own dedicated template then I’d be better off just following the standard inclusion tag example in the documentation. This solution is suggested for when you want the data without any baggage.

As posted to http://stackoverflow.com/questions/2566265

This entry was posted in geek and tagged . Bookmark the permalink.

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>