渲染Jinja2宏而不打扰模板的其余部分 [英] Render Jinja2 macro without bothering what's in the rest of the template

查看:333
本文介绍了渲染Jinja2宏而不打扰模板的其余部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的第一个Flask项目上工作时,我试图从Jinja2模板呈现宏时偶然发现了jinja2.exceptions.UndefinedError异常。事实证明,当Jinja2试图解析模板的其余部分时,确实包含了对全局请求对象的引用,所以产生了这个异常。



这是模板测试。 html用于测试用例:

 <!doctype html> 
{%macro test_macro() - %}
从宏
{% - endmacro%}
{{request.authorization}}







-python prettyprint-override> @ app.route(/ test)
def test_view():
return render_template('test.html')

Flask code#2:呈现宏(失败):

  @ app.route(/ test)
def test_view():
test_macro = get_template_attribute('test.html', 'test_macro')
return test_macro()

如果将 {{request.authorization}} out from the template,the 2nd test will execute successfully。



Flask code#3:using the <解决方法我在Flask邮件中找到了一个解决方法(成功):

@ app.route(/ test )
def test_view():
t = app.jinja_env.get_template('test.html')
mod = t.make_module({'request':request})
return mod.test_macro()

尽管我现在有一个工作代码,但是我不觉得不知道为什么第二种方法失败。为什么Jinja2甚至在需要渲染宏的时候对模板的其余部分感到困扰呢?

解决方案

你是绝对正确的,它已经在金加方面造成了。来自Flask的方法 get_template_attribute()看起来像这样:

  return getattr (current_app.jinja_env.get_template(template_name).module,
attribute)

检索一个模板名称,然后调用属性 module 来计算这个模板,然后生成属性列表。在你的情况下,对Jinja的变量 request 的引用仍然是未知的。有关详情,请查看 Jinja的 environment.py 来源


Working on my first Flask project, I stumbled upon jinja2.exceptions.UndefinedError exception when trying to render a macro from Jinja2 template. It turned out that Jinja2 generates this exception when it is trying to parse the rest of the template that indeed contains reference to the global request object.

Here is the template test.html I use for test case:

<!doctype html>
{% macro test_macro() -%}
  Rendered from macro
{%- endmacro %}
{{ request.authorization }}

Flask code #1: rendering the template (success):

@app.route("/test")
def test_view():
    return render_template('test.html')

Flask code #2: rendering the macro (fail):

@app.route("/test")
def test_view():
    test_macro = get_template_attribute('test.html', 'test_macro')
    return test_macro()

If you take the {{ request.authorization }} out from the template, the 2nd test will execute successfully.

Flask code #3: using the workaround I found in the Flask mailing list archive (success):

@app.route("/test")
def test_view():
    t = app.jinja_env.get_template('test.html')
    mod = t.make_module({'request': request})
    return mod.test_macro()

Although I have a working code now, I find it uncomfortable to not know why the 2nd approach fails. Why Jinja2 even bothers about the rest of the template when it is required to render only the macro?

解决方案

You are absolutely right, it has been caused on the Jinja side. Method get_template_attribute() from the Flask looks like this:

return getattr(current_app.jinja_env.get_template(template_name).module,
               attribute)

So it tries to retrieve a template name, and afterward, call to the property module evaluates this template before the list of the properties will be generated. In your case, the reference to the variable request remained unknown for the Jinja. For more details check Jinja's environment.py sources.

这篇关于渲染Jinja2宏而不打扰模板的其余部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆