Đây là những gì tôi đã đưa ra, bằng cách sử dụng tùy chọn finalize cho môi trường:
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)
Đó là một chút xấu xí, vì vậy cải thiện chào đón :)
Nhưng nó rendering đệ quy như OP đã yêu cầu và không dừng lại cho đến khi không còn {{
ở đầu ra ..
phiên Ví dụ
>>> 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, refactored tôi làm chức năng một chút, chức năng như nhau, nhưng một chút ngăn nắp:
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)
Added lời giải thích trên – muckabout