Showing posts with label format list. Show all posts
Showing posts with label format list. Show all posts

Saturday, 2 May 2009

Custom Template Tags - Part 3: A Last Minute Inclusion

After finishing last week's tutorial on block style template tags I realised that there was one template tag creation tip that I had yet to mention and that's the inclusion tag. This is quite closely related to the simple template tags described previously in that it only requires you to write one function. This time however you must provide also provide a template name which will be rendered at the end of it all. Take a look at the following example (a reworking of the simple tag example)


#File: list_formatters.py
from django import template

register = template.Library()

@register.inclusion_tag('format_list_tag.html')
def format_list(input_list):
return { 'unformatted_list':input_list, }

This file is fairly straightforward, we decorate the format_list function to say that it's an inclusion style tag and that it should use the template format_list_tag.html we then return a dictionary which will be used as the context for the template when it is processed. All that's left to include is the following template file:


{# File: format_list_tag.html #}
<ul>
{% for item in unformatted_list %}
<li>{{ item }}</li>
{% endfor %}
<ul>

This file simply provides a snippet of html describing how to display the list. Pop list_formatters.py into your templatetags directory and format_list_tag.html into your templates directory and pointing a url towards the following example (repeated from the previous tutorial) you can see the tag in action.


from django.template import Template,Context
from django.http import HttpResponse
def tag_test(request):
test_list=['Item 1','Item 2','Third time lucky']
t = Template("""{% load list_formatters %}
<html>
<head><title>Tag Test</title></head>
<body>
{% format_list test_list %}
</body>
</html>""")
return HttpResponse(t.render(Context({'test_list':test_list})))

There is one other useful feature of the inclusion tag and that is the ability to access the context. This can be done as follows (changes from the original file have been highlighted):


#File: list_formatters.py
from django import template

register = template.Library()

@register.inclusion_tag('format_list_tag.html', takes_context=True)
def format_list(context):
return { 'unformatted_list':context.get(test_list,[]), }

Whilst this example isn't really the best way to do things it should illustrate the power of what can be done by the inclusion tag and should enable you to use it in your own django sites.


Next time things will be back on track with the promised tutorial on custom filters

Sunday, 19 April 2009

Custom Template Tags - Part 1: Keeping It Simple

If you've ever created a django template before then you'll have used a template tag in one form or another. This tutorial will show you how you can create a simple template tag to help automate a common task.


The simplest of the Simple template tags are used for those cases where you find that you have a chunk of HTML code which is used in multiple places within your code, but because the location isn't static it can't be included in a base template. These tags would take no parameters at all and would output the same chunk of HTML every time. An example of this in the default tags would be {% debug %} which will output a load of debug information at the point the tag is placed.


The next level of complexity for template tags comes by allowing parameters into the simple tags. This could be used for things where you require a consistent format or where you want to run a piece of python code over a variable before displaying it. An example of one if these in the default tags would be {% url url_name %} which we saw last week in the tutorial on naming urls.


Since both of these types of tags are created on a similar way this tutorial will demonstrate how to create one that takes parameters. The example to be used this week will be for a tag that takes a list as a parameter and formats it into a series of bullet points.


The first thing to do is to create a directory named templatetags within your application directory. This is a special directory that django will look in whenever you try to import a set of tags (it will look for this directory in every installed application). In the newly-created directory create a blank file named __init__.py (which is required by python) and a file name list_formatters.py which should contain the following code:


from django import template

register = template.Library()

@register.simple_tag
def format_list(input_list):
return "<ul>\n <li>%s</li>\n<ul>" % "</li>\n <li>".join(input_list)


This code basically registers the function with the template library and says that it's a simple tag. The function then takes its only input and joins it together with some HTML to produce a bullet point style list.


Now we have generated the code for the tag, we can import it into a template and try it out. Create a new view using the following code and point a url at it:


from django.template import Template,Context
from django.http import HttpResponse
def tag_test(request):
test_list=['Item 1','Item 2','Third time lucky']
t = Template("""{% load list_formatters %}
<html>
<head><title>Tag Test</title></head>
<body>
{% format_list test_list %}
</body>
</html>""")
return HttpResponse(t.render(Context({'test_list':test_list})))

View this newly-created page and you should see that the list passed into the context has been formatted as a series of bullet points.


The next tutorial will look at block template tags i.e. ones that take a block of text/code in the middle of them like {% block %}{% endblock %} or {% if condition %}{% else %}{% endif %}