Capture template output as a variable

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from django import template

register = template.Library()

@register.tag(name='captureas')
def do_captureas(parser, token):
    try:
        tag_name, args = token.contents.split(None, 1)
    except ValueError:
        raise template.TemplateSyntaxError("'captureas' node requires a variable name.")
    nodelist = parser.parse(('endcaptureas',))
    parser.delete_first_token()
    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 ''

More like this

  1. WithTag Tag by versae 4 years, 10 months ago
  2. HTTPS redirections middleware with updated URL template tag by xlq 7 months ago
  3. Subdirectory and subcontext include template tag with examples by t_rybik 3 years, 2 months ago
  4. Querystring Builder - create urls with GET params by jibberia 2 years, 4 months ago
  5. Support for {% macro %} tags in templates, version 2 by mludvig 5 years, 9 months ago

Comments

cubes (on June 24, 2009):

Thanks, I found this incredibly useful. One suggestion for improvement is to call django.utils.safestring.mark_safe on output after it is rendered in line 21.

This is because the render call performs HTML escaping of any interpolated variables, which means the newly created capture variable will be doubly escaped if it is not passed through the safe filter.

Thoughts?

#

cubes (on June 24, 2009):

I found that the built in filter tag somewhat decreases my need for captureas, but it's still nifty. :)

#

tiliv (on July 12, 2010):

The point, cubes, is actually to capture BLOCK output. Filters can indeed be wrapped with the filter block, but blocks can't take other blocks as arguments.

Good code for getting out of a quick bind. Could use improvement, but this completely fills the need. Hopefully this will get into the default tags by Django 1.3

#

(Forgotten your password?)