ShanaC
ShanaC

Reputation: 377

Does Jinja2 support nested if statements?

I read the docs and I am not clear on this is right at all. I know you can use nested for loops, but if statements seem to be different.

Can i do the following?

{% if thing=true %}
<div> something here</div>
  {% if diffthing=true %}
  <div> something else</div>
  {% else %}
  <div> third thing</div>
  {% endif %}
{% else %}
<div> nothing here </div>
{% endif %}

Or should the format be different somehow?

Upvotes: 26

Views: 42069

Answers (4)

user559633
user559633

Reputation:

Jinja2 supports nested blocks, including if statements and other control structures.

See the documentation on Block Nesting and Scope: "Blocks can be nested for more complex layouts."

A good use case for this is writing macros that conditionally output HTML:

{# A macro that generates a list of errors coming back from wtforms's validate function #}
{% macro form_error_summary(form, li_class='bg-danger') %}
    {# only do the following on error... #}
    {% if form.errors %}

        <ul class="errors">

        {# you can do layers of nesting as needed to render your content #}
        {% for _field in form %}
            {% if _field.errors %}
                {% for error in _field.errors %}                 
                    <li class={{li_class}}>{{_field.label}}: {{ error|e }}</li>
                {% endfor %}
            {% endif %}
        {% endfor %}
        </ul>

    {% endif %}
{% endmacro %}

Upvotes: 23

Leighton Griffith
Leighton Griffith

Reputation: 23

Just a quick add, if you're unpacking data to populate your fields, Jinja will only unpack it once. I had a similar problem with MongoDB and found if you change the item to a list item you iterate through it more than once without nesting

@app.route("/")
@app.route("/get_shrink")
def get_shrink():
    # find and sort shrink top 5
    shrink = list(mongo.db.shrinkDB.find().limit(5).sort(
        "amount_lost_value", -1,))
    return render_template(
        "shrink.html", shrinkDB=shrink)
               {% for shrink in shrinkDB %}
                    {% if shrink.resolved == true %}
                        <li>{{ shrink.product_name }} ||£ {{ shrink.amount_lost_value }} || {{ shrink.date }}</li> 
                    {% endif %}    
               {% endfor %}
        </span>
      </div>
    </div>
    <div class="col s12 m5 offset-m2">
        <h4>Top 5 Resolved Threats</h4>
      <div class="card-panel light-blue">
        <span class="white-text">
<!-- Shrink For loop top 5 resolves-->
            {% for shrink in shrinkDB %}
                {% if shrink.resolved != true %}
                        <li>{{ shrink.product_name }} ||£ {{shrink.amount_lost_value }} || {{ shrink.date }}</li> 
                {% endif %}
            {% endfor %}

Upvotes: 1

Alex P. Miller
Alex P. Miller

Reputation: 2246

The answer is yes.

I'm using logic very similar to yours in a live application and the nested if blocks work as expected. It can get a little confusing if you don't keep your code clean, but it works fine.

Upvotes: 2

stickyb1t
stickyb1t

Reputation: 17

It seem possible. Refer to the documentation here: http://jinja.pocoo.org/docs/templates/#if

Upvotes: 0

Related Questions