Flask / Jinja - 使用父级的范围/上下文在父模板中呈现用户输入jinja模板

时间:2016-06-04 21:44:40

标签: python flask jinja2

标题很乱,所以让我尽可能清楚。我该如何实施do_magic

在此template.html中

{% set x = 1 %}
{{ do_magic(subtemplate) }}, {{ x }}, {{ y }}

从此方法调用

@app.route('/')
def home():
  return render_template(
    'template.html',
    subtemplate='{{ x }}, {{ y }}',
    y=2,
    do_magic=do_magic
  )

def do_magic(some_text):
    ... # what goes here?

哪个应该输出

1, 2, 1, 2

而不是

{{ x }}, {{ y }}, 1, 2

1 个答案:

答案 0 :(得分:0)

我想我明白了!

from jinja2 import contextfunction, Markup

@contextfunction
def do_magic(context, subtemplate):
  ''' Renders string subtemplate with variables from the active context. '''
  template_object = app.jinja_env.from_string(subtemplate)
  html = template_object.render(**context)
  return Markup(html)

我当然希望这不会有一些我不知道的致命缺陷。

(顺便说一句,你们看到Jinja的源代码吗?它从模板构建一个python脚本然后运行python脚本!)

修改

原来所见即所得的编辑器不能很好地处理复杂的jinja模板,并且回想起来,我认为我不需要一个带有if-else的CMS的无处不在的CMS。

我想我真正想要的只是替换变量的基本模板能力。所以我提出了一种方法来替换使用正则表达式的变量。

import re
from jinja2 import contextfunction, Markup

@contextfunction
def do_magic(context, subtemplate):
  fallback_value = '???'
  def get_replacement(matchobj):
    key = matchobj.group(1)
    return context.get(key, fallback_value)

  pattern = r'{{\s*([a-zA-Z0-9_]+)\s*}}'
  html = re.sub(pattern, get_replacement, subtemplate)
  return Markup(html)