Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jinja nested rendering on variable content

Tags:

python

jinja2

Say I have actual jinja template code in a variable X. Let us say the content of X is "{{ some_other_variable }}".

How can I display X while also rendering its content?

e.g., this does not work:

{{ X }}

As it simply renders this to screen "{{ some_other_variable }}" rather than the contents of some_other_variable.

The reason I'm doing it this way is that I have a site in which (trusted) users can create posts which themselves may contain jinja template code. The view page displays these posts, but due to the above problem, renders them directly, rather than substituting variables as I'd like.

like image 690
muckabout Avatar asked Jan 14 '12 14:01

muckabout


2 Answers

I know it's a bit late :) but here's one solution without impacting template code:

import jinja2
def recursive_render(tpl, values):
     prev = tpl
     while True:
         curr = jinja2.Template(prev).render(**values)
         if curr != prev:
             prev = curr
         else:
             return curr

Test run:

>>> recursive_render("Hello {{X}}!", dict(X="{{name}}", name="world"))
u'Hello world!'

Note that this is not very efficient, since the template must be reparsed from scratch on every iteration.

like image 69
Lluís Vilanova Avatar answered Sep 30 '22 15:09

Lluís Vilanova


Create new filter:

from jinja2 import contextfilter, Markup

@contextfilter
def subrender_filter(context, value):
    _template = context.eval_ctx.environment.from_string(value)
    result = _template.render(**context)
    if context.eval_ctx.autoescape:
        result = Markup(result)
    return result

env = Environment()
env.filters['subrender'] = subrender_filter

And then use it in template:

{{ "Hello, {{name}}"|subrender }}
like image 31
Nikolay Baluk Avatar answered Sep 30 '22 15:09

Nikolay Baluk