# jinja2 template - {% else %} not honored

**URL:** <https://forum.ansible.com/t/jinja2-template-else-not-honored/29645>\
**Category:** Ansible Project\
**Created:** [February 11, 2019, 6:02am UTC](https://forum.ansible.com/t/jinja2-template-else-not-honored/29645 "2019-02-11T06:02:30Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ashok1](https://avatars.discourse-cdn.com/v4/letter/a/f1d935/32.png) [@Ashok1](https://forum.ansible.com/u/Ashok1)\
**Post date:** [February 11, 2019, 6:02am UTC](https://forum.ansible.com/t/jinja2-template-else-not-honored/29645/1 "2019-02-11T06:02:30Z")

</div>

I have the following data structure:

client\_groups:  
apache:

- ‘10.5.10.111’
- ‘10.2.10.112’
- ‘10.5.10.11’

mail:

- ‘1.2.3.4’
- ‘5.6.7.8’

database:

- ‘10.9.8.7’

client\_destinations:  
apache:

- var: ‘$syslogtag’  
contains: ‘apache-access:’  
destination: ‘/logs/apache-servers/access.log’

- var: ‘$syslogtag’  
contains: ‘apache-error:’  
destination: ‘/logs/apache-servers/error.log’

mail:

- var: ‘local5’  
contains: ‘dovecot’  
destination: ‘/logs/mail/mail.log’

database:

- var:  
contains:  
destination: ‘/logs/db/activity.log’

In my jinja2 template-file, I have the below:

{% for k in client\_groups %}  
{% if client\_destinations[k][0].var is defined %}  
{% for i in range(0,client\_destinations[k]|length) %}  
if $fromhost-ip == {{ client\_groups[k] | to\_json }} and {{ client\_destinations[k][i].var }} == ‘{{ client\_destinations[k][i].contains }}’ then {{ client\_destinations[k][i].destination }}  
{% endfor %}  
{% endif %}  
{% else %}  
if $fromhost-ip == {{ client\_groups[k] | to\_json }} then {{ client\_destinations[k].destination }}  
{% endfor %}

The desired output is:

_if $fromhost-ip == [“10.5.10.111”, “10.2.10.112”, “10.5.10.11”] and $syslogtag == ‘apache-access:’ then /logs/apache-servers/access.log_  
_if $fromhost-ip == [“10.5.10.111”, “10.2.10.112”, “10.5.10.11”] and $syslogtag == ‘apache-error:’ then /logs/apache-servers/error.log_  
_if $fromhost-ip == [“1.2.3.4”, “5.6.7.8”] and local5 == ‘dovecot’ then /logs/mail/mail.log_  
_if $fromhost-ip == [“10.9.8.7”] == then /logs/db/activity.log_

But, I get the below output:

_if $fromhost-ip == [“10.5.10.111”, “10.2.10.112”, “10.5.10.11”] and $syslogtag == ‘apache-access:’ then /logs/apache-servers/access.log_  
_if $fromhost-ip == [“10.5.10.111”, “10.2.10.112”, “10.5.10.11”] and $syslogtag == ‘apache-error:’ then /logs/apache-servers/error.log_  
_if $fromhost-ip == [“1.2.3.4”, “5.6.7.8”] and local5 == ‘dovecot’ then /logs/mail/mail.log_  
_if $fromhost-ip == [“10.9.8.7”] and == ‘’ then /logs/db/activity.log_

This means, the statement after {% else %} - if $fromhost-ip == {{ client\_groups[k] | to\_json }} then {{ client\_destinations[k].destination }} - is getting included in the `for` loop ({% for i in range(0,client\_destinations[k]|length) %}); {% else %} is not being honored.

What should be changed?

Thanks in advance.

---

<div class="post-metadata">

**Author:** ![felixfontein](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/felixfontein/32/7530_2.png) [@felixfontein](https://forum.ansible.com/u/felixfontein)\
**Post date:** [February 11, 2019, 7:20am UTC](https://forum.ansible.com/t/jinja2-template-else-not-honored/29645/2 "2019-02-11T07:20:26Z")

</div>

Hi,

> In my jinja2 template-file, I have the below:
> 
> {% for k in client\_groups %}  
> {% if client\_destinations[k][0].var is defined %}  
> {% for i in range(0,client\_destinations[k]|length) %}  
> if $fromhost-ip == {{ client\_groups[k] | to\_json }} and {{  
> client\_destinations[k][i].var }} ==  
> '{{ client\_destinations[k][i].contains }}' then  
> {{ client\_destinations[k][i].destination }} {% endfor %}  
> {% endif %}  
> {% else %}  
> if $fromhost-ip == {{ client\_groups[k] | to\_json }} then {{  
> client\_destinations[k].destination }}  
> {% endfor %}

First: you should \*\*really\*\* indent stuff for better readability:

{% for k in client\_groups %}  
{% if client\_destinations[k][0].var is defined %}  
{% for i in range(0,client\_destinations[k]|length) %}  
if $fromhost-ip == {{ client\_groups[k] | to\_json }} and {{  
client\_destinations[k][i].var }} == '{{ client\_destinations[k][i].contains  
}}' then {{ client\_destinations[k][i].destination }}  
{% endfor %}  
{% endif %}  
{% else %}  
if $fromhost-ip == {{ client\_groups[k] | to\_json }} then {{  
client\_destinations[k].destination }}  
{% endfor %}

> The desired output is:  
> [...]
> 
> This means, the statement after {% else %} - if $fromhost-ip == {{  
> client\_groups[k] | to\_json }} then  
> {{ client\_destinations[k].destination }}  
> - is getting included in the `for` loop ({% for i in  
> range(0,client\_destinations[k]|length) %}); {% else %} is not being  
> honored.

It is being honored. Please check the documentation:  
[http://jinja.pocoo.org/docs/2.10/templates/#for](http://jinja.pocoo.org/docs/2.10/templates/#for)

The else branch of a for loop is executed only if the loop is over zero  
elements. Since your loop is over a non-zero amount of elements, the  
else branch of the for loop is ignored.

You probably don't want an else branch for the for loop, but for the if  
construct. You can see from the indented version that you don't have  
that right now.

Cheers,  
Felix
