Tuesday, July 2, 2013

Inclusion Tags

Inclusion Tags

Another common template tag is the type that displays some data by rendering another template. For example, Django’s admin interface uses custom template tags to display the buttons along the bottom of the “add/change” form pages. Those buttons always look the same, but the link targets change depending on the object being edited. They’re a perfect case for using a small template that is filled with details from the current object.
These sorts of tags are called inclusion tags. Writing inclusion tags is probably best demonstrated by example. Let’s write a tag that produces a list of books for a given Author object. We’ll use the tag like this:
{% books_for_author author %}
The result will be something like this:
<ul>
    <li>The Cat In The Hat</li>
    <li>Hop On Pop</li>
    <li>Green Eggs And Ham</li>
</ul>

_______________

Pre-conditions: 
custom tag creation and loading 
polls/
    models.py
    templatetags/
        __init__.py
        poll_extras.py
    views.py
And in your template you would use the following:
{% load poll_extras %}
_________________
First, we define the function that takes the argument and produces a dictionary of data for the result. Notice that we need to return only a dictionary, not anything more complex. This will be used as the context for the template fragment:
def books_for_author(author):
    books = Book.objects.filter(authors__id=author.id)
    return {'books': books}
Next, we create the template used to render the tag’s output. Following our example, the template is very simple:
book_snippet.html
<ul>
{% for book in books %}
    <li>{{ book.title }}</li>
{% endfor %}
</ul>
Finally, we create and register the inclusion tag by calling the inclusion_tag() method on a Library object.
Following our example, if the preceding template is in a file called book_snippet.html, we register the tag like this:
register.inclusion_tag('book_snippet.html')(books_for_author)
Python 2.4 decorator syntax works as well, so we could have written this, instead:
@register.inclusion_tag('book_snippet.html')
def books_for_author(author):
    # ...
takes_context
Sometimes, your inclusion tags need access to values from the parent template’s context. To solve this, Django provides a takes_context option for inclusion tags. If you specify takes_context in creating an inclusion tag, the tag will have no required arguments, and the underlying Python function will have one argument: the template context as of when the tag was called.
For example, say you’re writing an inclusion tag that will always be used in a context that containshome_link and home_title variables that point back to the main page. Here’s what the Python function would look like:
@register.inclusion_tag('link.html', takes_context=True)
def jump_link(context):
    return {
        'link': context['home_link'],
        'title': context['home_title'],
    }
(Note that the first parameter to the function must be called context.)
The template link.html might contain the following:
Jump directly to <a href="{{ link }}">{{ title }}</a>.
Then, anytime you want to use that custom tag, load its library and call it without any arguments, like so:
{% jump_link %}

good for pagination, buttons

No comments:

Post a Comment