Conditional Output of a Django Block

A common use case when developing Django templates is rendering a block only when the block has content. Take this for example:

<section id="message" class="messages alert">
<p>{% block message %}{% endblock %}</p>

view raw
hosted with ❤ by GitHub

If you use blocks as designed out of the box, you’ll end up with some extra markup that you may need to hide via other methods (such as CSS). That’s definitely not ideal.

After digging around for a bit I stumbled upon this very helpful snippet which accomplishes this using a custom template tag:

from django import template
register = template.Library()
def do_captureas(parser, token):
tag_name, args = token.contents.split(None, 1)
except ValueError:
raise template.TemplateSyntaxError("'captureas' node requires a variable name.")
nodelist = parser.parse(('endcaptureas',))
return CaptureasNode(nodelist, args)
class CaptureasNode(template.Node):
def __init__(self, nodelist, varname):
self.nodelist = nodelist
self.varname = varname
def render(self, context):
output = self.nodelist.render(context)
context[self.varname] = output
return ''

view raw
hosted with ❤ by GitHub

The tag captures the content of the block to a variable within the template which can then be tested for existence, allowing you to conditionally show the block depending on the contents.

Using the tag is as simple as this:

{% load captureas %}
{% captureas message %}{% spaceless %}{% block message %}{% endblock %}{% endspaceless %}{% endcaptureas %}
{% if message %}
<section id="message" class="messages alert">
<p>{{ message }}</p>
{% endif %}

view raw
hosted with ❤ by GitHub

Hopefully Django adds this in the future.