Jinja nested rendering on variable content

Say I have the actual jinja template code in variable X. Let's say the contents of X is "{{some_other_variable}}".

How can I display X as well as display its contents?

for example, this does not work:

{{X}}

Because it just displays it to display "{{some_other_variable}}" and not the contents of some_other_variable.

The reason I do this is because I have a website where (trusted) users can create messages that themselves can contain jinja template code. The browse page displays these messages, but because of the above problem, it visualizes them directly, and does not replace the variables as we would like.

+5
source share
6

, :

, , "{{some_other_variable}}" , .

:

X.replace("{{some_other_variable}}", some_other_variable))

{{X}} . , ?

+2

:

  • DictLoader ( )
  • ChainLoader DictLoader
  • ,
  • include

, !

+2

:), :

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

:

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

, , .

+2

, , finalize :

def render (tpl, args):
    scope = {}
    scope['env'] = jinja2.Environment (finalize=lambda x: scope['env'].from_string (x).render (**args) if isinstance(x, str) and '{{' in x else x)
    scope['env'].filters['q'] = lambda value: re.sub (r'"', r'\\"', value)
    return scope['env'].from_string (tpl).render (**args)

, :)

, OP, , {{.

>>> import jinja2
>>> def render (tpl, args):
...         scope = {}
...         scope['env'] = jinja2.Environment (finalize=lambda x: scope['env'].from_string (x).render (**args) if isinstance(x, str) and '{{' in x else x)
...         scope['env'].filters['q'] = lambda value: re.sub (r'"', r'\\"', value)
...         return scope['env'].from_string (tpl).render (**args)
... 
>>> render("this {{ outer_var }} wokring!", {"outer_var":"{{ inner_var }}", "inner_var":"{{ final_step }}", "final_step":"is"})
u'this is wokring!'

EDIT:

, , , :

def render (tpl, args):
    @jinja2.environmentfunction
    def finalize (env, value):
        if isinstance(value, (str, unicode)) and '{{' in value:
            return env.from_string (value).render (args)
        return value
    env = jinja2.Environment (finalize=finalize)
    env.filters['q'] = lambda value: re.sub (r'"', r'\\"', value)
    return env.from_string (tpl).render (args)
0

.

def render(template, values):
     prev = template.render(**values)
     while True:
         curr = Template(prev).render(siteinfo=config, menus=menus, blended_header=header, authors=authors, buildinfo=buildinfo, **values)
         if curr != prev:
             prev = curr
         else:
             return curr

, .

: render(template, dict(content=post, tags=tags))

template = env.get_template('index.html')

0

:

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

:

{{ "Hello, {{name}}"|subrender }}
0
source

All Articles