Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Render Jinja2 macro without bothering what's in the rest of the template

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?

like image 478
Passiday Avatar asked Feb 03 '14 07:02

Passiday


1 Answers

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.

like image 160
wanderlust Avatar answered Nov 16 '22 01:11

wanderlust