Questo è ciò che mi si avvicinò con, utilizzando l'opzione finalize per l'Ambiente:
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)
E 'un po' brutto, quindi i miglioramenti benvenuti :)
ma lo fa il rendering ricorsiva come l'OP stava chiedendo, e non si ferma fino a quando non c'è più {{
nell'output ..
sessione Esempio
>>> 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:
Ok, refactoring il mio render funzione un po ', funzionalmente lo stesso, ma un po' più ordinato:
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)
Aggiunto spiegazione sopra – muckabout