渲染 Jinja2 宏而不影响模板其余部分的内容

Posted

技术标签:

【中文标题】渲染 Jinja2 宏而不影响模板其余部分的内容【英文标题】:Render Jinja2 macro without bothering what's in the rest of the template 【发布时间】:2014-02-26 14:19:54 【问题描述】:

在我的第一个 Flask 项目中工作时,我在尝试从 Jinja2 模板渲染宏时偶然发现了 jinja2.exceptions.UndefinedError 异常。事实证明,Jinja2 在尝试解析模板的其余部分确实包含对全局请求对象的引用时会生成此异常。

这是我用于测试用例的模板 test.html

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

Flask 代码#1:渲染模板(成功):

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

Flask 代码 #2:渲染宏(失败):

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

如果您从模板中取出 request.authorization ,则第二次测试将成功执行。

烧瓶代码#3:使用workaround I found in the Flask mailing list archive(成功):

@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 只需要渲染宏时还要关心模板的其余部分?

【问题讨论】:

【参考方案1】:

你说的完全正确,这是在 Jinja 方面造成的。 Flask 中的方法get_template_attribute() 如下所示:

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

因此它尝试检索模板名称,然后调用属性module 在生成属性列表之前评估此模板。在您的情况下,Jinja 对变量 request 的引用仍然未知。更多详情请查看Jinja's environment.py sources。

【讨论】:

以上是关于渲染 Jinja2 宏而不影响模板其余部分的内容的主要内容,如果未能解决你的问题,请参考以下文章

在macro_rules中使用另一个宏而不需要生锈的“extern crate”

模板渲染

Jinja2模板引擎简介

flask基础之jinja2模板-语法定义

使用 Django 的模板引擎而不使用 Django 的其余部分

使用 Django 模板和标签而不使用 Django 的其余部分