[Answered ]-Nested template tags from context

1👍

I am not aware of any way to do exactly that, wouldn’t be surprised if it’s not implemented by default, as Django would no longer be able to render everything in one go…

Here are some things that come a bit close though, maybe it helps.

Easiest: just use Python %s to do it in your view

page['title'] = 'This is a test title for page %s' % page['foo']

If you want to use the Django rendering:

page['title'] = Template(page['title']).render(Context({'page': page, }))

In your view, that renders the This is a test title for page {{ page.foo }} with page as context.

If you were only using things from the default context, you could write a filter that renders the current string with that context like {{ page.title|render }}. But I’m not aware of a way to get the entire context from within a template, so this would only work for defeault context values.

EDIT: Found another way, will make a new answer.

👤Mark

1👍

You can make a template tag that renders a variable in the current context. Refer to https://docs.djangoproject.com/en/dev/howto/custom-template-tags/ for general information about custom template tags.

The result:

{% load renderme %}
{% renderme page.title %}

Becomes (for the context you provided):

This is a test title for page Test 

The template tag code (you will have to improve the imput checking, most notably it doesn’t yet accept passing a string directly):

from django import template
from django.template.context import Context
from django.template.base import Template

class RenderNode(template.Node):

    def __init__(self, template_string_name = ''):
        self.template_string_name = template_string_name

    def render(self, context):
        ''' If a variable is passed, it is found as string, so first we use render to convert that
            variable to a string, and then we render that string. '''
        self.template_string = Template('{{ %s }}' % self.template_string_name).render(context)
        return Template(self.template_string).render(context)

def render_me(parser, token):
    try:
        tag_name, template_string_name = token.split_contents()
    except Exception:
        raise template.TemplateSyntaxError('Syntax for renderme tag is wrong.')
    return RenderNode(template_string_name)

register = template.Library()
register.tag('renderme', render_me)

There you go! You will need to use a tag instead of a plain variable or filter, but it does what you described.

👤Mark

Leave a comment