Including variables as templates

To manage the website content in a flexible way it's practical to have some portions of some pages generated from variables created as FlatPages. For example, in a frontpage I have a "featured item" section which renders a flatpage variable.

def frontpage(request):
    fp = FlatPage.objects.get(url='featured')
    return render_to_response('frontpage.html', {'fp':fp })
then in the template
...<div id="featured">{{ fp.content }}</div> ...

But sometimes it would also be nice to put some template tags inside those flatpages. Django does not seem to provide a tag for such task (most probably because it can be a bad idea from the security point of view), but the ssi tag does exactly the same thing for files in the filesystem. Based on ssi, the code bellow defines a new tag that includes the content of a variable as a template.

def do_templatevar(parser, token):
    bits = token.contents.split()
    if len(bits) != 2:
        raise TemplateSyntaxError, "%s tag takes one argument" % bits[0]
    return TemplateVarNode(parser.compile_filter(bits[1]))

register.tag('templatevar', do_templatevar)

class TemplateVarNode(Node):
    def __init__(self, content):
        self.content = content

    def render(self, context):
        content = self.content.resolve(context)
            t = Template(content)
            return t.render(context)
        except TemplateSyntaxError, e:
            if settings.DEBUG:
                return "[Included template had syntax error: %s]" % e
                return '' # Fail silently

Now I can put the following code in my flat page

<p>This is my media_url: {{ MEDIA_URL }}</p>

And it will work if I define my template as

...<div id="featured">{% templatevar fp.content %}</div> ...

A last remark to mention databasetemplateloader that allows to load template data from the database. I never tried it, but seems to be a more generic solution (and also a way to have a Zope 1 experience in Django).

0 Responses to “Including variables as templates”

Comments closed for this old post