jinja2 template - {% else %} not honored

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.

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

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