Jinja macro doesn't see value passed to render_template

1.1k views Asked by At

On certain pages I want my form drop down to be in a specific order and in other pages in a default order. When passing in a specific order from my app, my macro in form.html doesn't seem to see it. dropdown is never used, the template always displays the global data instead. Why is this happening?

form.html:

    {% if dropdown %}
        <select name="status">
        {% for option in dropdown %}
              <option value="{{ option }}">{{ option }}</option>
        {% endfor %}
        </select>
    {% else %}
        <select name="status">
        {% for option in global_add_links_data()[0] %}
              <option value="{{ option }}">{{ option }}</option>
        {% endfor %}
        </select>
    {% endif %}

app.py:

dropdown = [
    'Placed',
    'Review Not Started',
    'Review Passed',
    'Review Failed',
    'Contacted Pending',
    'Contacted Failed',
    'No Contacts',
    'No Reply',
    'Not Interested'
]
dropdown.insert(0, dropdown.pop(dropdown.index(link_status)))
return render_template('view.html', dropdown=dropdown)
1

There are 1 answers

0
davidism On BEST ANSWER

You are not rendering form.html directly, you are rendering view.html and importing form.html. When importing other templates, the template context is not passed by default. dropdown is local to the view.html context, so it is always undefined in form.html.

To import a template with context, you use the with context keywords.

{% from "form.html" render_form with context %}

A better, more explicit way to handle this is to just pass dropdown as an argument to the macro. This is more efficient, because as the docs above mention, imports are normally cached for performance, but using with context disables that.

{% macro render_form(form, dropdown=None) -%}
    {% if dropdown %}
    {% else %}
    {% endif %}
{%- endmacro %}
{% from "form.html" import render_form %}
{{ render_form(form, dropdown) }}