Login

Capture template output as a variable

Author:
kcarnold
Posted:
January 14, 2008
Language:
Python
Version:
.96
Score:
19 (after 19 ratings)

Tags like url and trans provide no way to get the result as a context variable. But how would you get a computed URL into a blocktrans?

This snippet solves the general problem. Just put the template code whose output you want to capture within captureas tags. For example:

{% captureas login_url %}{% url login %}{% endcaptureas %}
{% blocktrans %}
<a href="{{login_url}}">login</a>
{%endblocktrans%}
 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. Template tag - list punctuation for a list of items by shapiromatron 10 months, 1 week ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 2 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 6 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

#

venya (on January 30, 2015):

There is no need for custom tags, you can use existing templating tools like this:

{% url login as login_url %}
{% blocktrans %}<a href="{{login_url}}">login</a>{%endblocktrans%}

#

vdboor (on April 20, 2016):

As I'm using this between many projects now, I've packaged this feature as django-capture-tag

The mean reason to use it, is to handle social media meta tags, where the description and page title needs to be repeated.

#

Please login first before commenting.