Skip to content

Instantly share code, notes, and snippets.

@isweluiz
Last active June 4, 2022 14:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save isweluiz/b44855585c081acc575f8910f4587e22 to your computer and use it in GitHub Desktop.
Save isweluiz/b44855585c081acc575f8910f4587e22 to your computer and use it in GitHub Desktop.
How to remove the line when the variable is not defined in jinja2 template

How to remove the line when the variable is not defined in jinja2 template

I have the JINJA2 template below, and so the issue is that when some variable is not defined the conditional will have just a blank line, this is not what I would expect. See the result below the code and let's try to solve it.

If you wanna to do some live test I really recommend try to use https://j2live.ttl255.com/ .

My template:

Structure:

{% if variable is defined and variable %}  variable is defined{% endif %}

Template:

{{ ansible_managed | comment }}

{% for path in item.path %}
{{ path }}  
{% endfor %}{
{% if item.missingok is defined and item.missingok %}    missingok{% endif %}

{% if item.keep is defined %}    rotate {{ item.keep }}{% endif %}

{% if item.frequency is defined %}    {{ item.frequency }}{% endif %}

{% if item.compress is defined and item.compress %}    compress{% endif %}

{% if item.create is defined and item.create %}    create{% if item.create_mode is defined %} {{ item.create_mode }}{% endif %}{% if item.create_user is defined %} {{ item.create_user }}{% endif %}{% if item.create_group is defined %} {{ item.create_group }}{% endif %}{% endif %}

{% if item.sharedscripts is defined and item.sharedscripts %}    sharedscripts{% endif %}

{% if item.notifempty is defined and item.notifempty %}    notifempty{% endif %}

{% if item.delaycompress is defined and item.delaycompress %}    delaycompress{% endif %}

{% if item.size is defined and item.size %}    size {{ item.size }}{% endif %}

{% if item.minsize is defined %}    minsize {{ item.minsize }}{% endif %}

{% if item.dateext is defined and item.dateext %}    dateext{% endif %}

{% if item.dateformat is defined and item.dateformat %}    dateformat {{ item.dateformat }}{% endif %}

{% if item.postrotate is defined %}    postrotate
        {{ item.postrotate }}
    endscript{% endif %}
    
}

Result:

                },
                "rc": 0,
                "start": "2022-06-03 13:25:30.758653",
                "stderr": "",
                "stderr_lines": [],
                "stdout": "#\n# Ansible managed\n#\n\n/var/log/app/full  \n/var/log/app/messages  \n{\n    missingok\n    rotate 15\n    daily\n    compress\n    create 0640 app app\n    sharedscripts\n    notifempty\n\n    size 325k\n\n\n\n    postrotate\n        /usr/sbin/app -rx 'logger reload' > /dev/null 2> /dev/null\n    endscript    \n}",
                "stdout_lines": [
                    "#",
                    "# Ansible managed",
                    "#",
                    "",
                    "/var/log/app/full  ",
                    "/var/log/app/messages  ",
                    "{",
                    "    missingok",
                    "    rotate 15",
                    "    daily",
                    "    compress",
                    "    create 0640 app app",
                    "    sharedscripts",
                    "    notifempty",
                    "",
                    "    size 325k",
                    "",
                    "",
                    "",
                    "    postrotate",
                    "        /usr/sbin/app -rx 'logger reload' > /dev/null 2> /dev/null",
                    "    endscript    ",
                    "}"
                ]
            }
        ]
    }
}

In the documentation we can found this:

You must not add whitespace between the tag and the minus sign.

{%- if foo -%}...{% endif %}

You can also strip whitespace in templates by hand. If you add a minus sign (-) to the start or end of a block (e.g. a For tag), a comment, or a variable expression, the whitespaces before or after that block will be removed:

{% for item in seq -%}
    {{ item }}
{%- endfor %}

This will yield all elements without whitespace between them. If seq was a list of numbers from 1 to 9, the output would be 123456789.

If Line Statements are enabled, they strip leading whitespace automatically up to the beginning of the line.

By default, Jinja also removes trailing newlines. To keep single trailing newlines, configure Jinja to keep_trailing_newline.

Going in the documentation we can see how we can cut some lines, but dosen't solve our issue, let's move to the structure, you can find this too in the documentation:

Structure:

{% if variable is defined and variable %}
    variable is defined
{% endif %}
{{ ansible_managed | comment }}

{% for path in item.path %}
{{ path }}  
{% endfor %} {
{% if item.missingok is defined and item.missingok %}
    missingok
{% endif %}
{% if item.keep is defined %}
    rotate {{ item.keep }}
{% endif %}
{% if item.frequency is defined %}
    {{ item.frequency }}
{% endif %}
{% if item.compress is defined and item.compress %}
    compress
{% endif %}
{% if item.create is defined and item.create %}
    create{# #}
{% if item.create_mode is defined %} {{ item.create_mode }}{% endif %}
{% if item.create_user is defined %} {{ item.create_user }}{% endif %}
{% if item.create_group is defined %} {{ item.create_group }}{% endif %}

{% endif %}
{% if item.sharedscripts is defined and item.sharedscripts %}
    sharedscripts
{% endif %}
{% if item.notifempty is defined and item.notifempty %}
    notifempty
{% endif %}
{% if item.size is defined and item.size %}
    size {{ item.size }}
{% endif %}
{% if item.delaycompress is defined and item.delaycompress %}
    delaycompress
{% endif %}
{% if item.minsize is defined %}
    minsize {{ item.minsize }}
{% endif %}
{% if item.nomissingok is defined and item.nomissingok %}
    nomissingok
{% endif %}
{% if item.dateext is defined and item.dateext %}
    dateext
{% endif %}
{% if item.dateformat is defined and item.dateformat %}
    dateformat {{ item.dateformat }}
{% endif %}
{% if item.postrotate is defined %}
    postrotate
        {{ item.postrotate }}
    endscript
{% endif %}
}

The result will be like the below:

                    "size": "325k"
                },
                "rc": 0,
                "start": "2022-06-03 15:30:46.328241",
                "stderr": "",
                "stderr_lines": [],
                "stdout": "#\n# Ansible managed\n#\n\n/var/log/app/full  \n/var/log/app/messages  \n {\n    missingok\n    rotate 15\n    daily\n    compress\n    create 0640 app app\n    sharedscripts\n    notifempty\n    size 325k\n    delaycompress\n    postrotate\n        /usr/sbin/app -rx 'logger reload' > /dev/null 2> /dev/null\n    endscript\n}",
                "stdout_lines": [
                    "#",
                    "# Ansible managed",
                    "#",
                    "",
                    "/var/log/app/full  ",
                    "/var/log/app/messages  ",
                    " {",
                    "    missingok",
                    "    rotate 15",
                    "    daily",
                    "    compress",
                    "    create 0640 app app",
                    "    sharedscripts",
                    "    notifempty",
                    "    size 325k",
                    "    delaycompress",
                    "    postrotate",
                    "        /usr/sbin/app -rx 'logger reload' > /dev/null 2> /dev/null",
                    "    endscript",
                    "}"
                ]
            }
        ]
    }
}

Some variables were not defined but they are in the template:

    #size: 100M
    #nomissingok: yes
    #dateext: yes
    #dateformat: "-%Y-%m-%d"  

To find more details about that, go into the documentation:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment