Hide attribute definition if the value is empty in Jinja? - jinja2

<vcpu placement='{{cpu.placement}}' cpuset='{{cpu.cpuset}}' current={{cpu.current}}>{{ cpu['maximum'] }}</vcpu>
Giving that we have 3 possible attributes and any of them can be empty.
Is there a neat way to hide the attribute definition if the value is empty? Let's say if cpu.placement is empty, the line placement='' shouldn't be there in the XML definition.

Just put the attribute definition inside an if-block:
<vcpu
{% if cpu.placement %}placement='{{cpu.placement}}'{% endif %}
{% if cpu.cpuset %}cpuset='{{cpu.cpuset}}'{% endif %}
{% if cpu.current %}current={{cpu.current}}>{{ cpu['maximum'] }}{% endif %}
</vcpu>
See the list of builtin tests in you need more complicated test for a variable.

Related

Condition based on the three first letters of a string?

In my Jinja template, model.DataType value can be user defined or built in. My requirenement is if model.DataType start with the three letters ARR, then do a specific operation.
Example of values:
ARRstruct124
ARR_int123
ARR123123
CCHAR
UUINT
etc.
{% set evenDataType = model.eventDataType %}
{%if evenDataType | regex_match('^ARR', ignorecase=False) %}
// do the operation
{%else%}
// do the operation
{% endif %}
With this template, I am getting the error
{%if evenDataType | regex_match('^ARR', ignorecase=False) %}
jinja2.exceptions.TemplateAssertionError: no filter named 'regex_match'
There is indeed no regex_match filter in the Jinja builtin filters. You might have found some examples using it, but this is an additional filter provided by Ansible, so it won't work outside of Ansible.
This said, your requirement does not need a regex to be fulfilled, you can use the startswith() method of a Python string.
So, you template should be:
{% set evenDataType = model.eventDataType %}
{% if evenDataType.startswith('ARR') %}
`evenDataType` starts with 'ARR'
{% else %}
`evenDataType` does not starts with 'ARR'
{% endif %}

How do I access a data value in a dictionary in the html template

I'm passing a dictionary in the context in my views.py to my html template. How do I know access a value in the template based on a particular key. For instance I'd wanna do something like {{ dictionary.keyname.value }} but I don't know the correct syntax and for some reason I can't seem to find the documentation.
I want to achieve the same effect as this without having to use a for loop:
<b>Calories</b>
{% for key, value in output.items %}
{% if key == "calories" %}
{{ value }}
{% endif %}
{% endfor %}
You just want {{ output.calories }}.

Compare two grain values inside state.sls using jinja expressions

I am creating a state which will trigger some module if both of the grains are not matching. I have tried several options, but no luck.
Based on comparison, False will trigger my module and that module will change GRAIN_B value to match with GRAIN_A. So during every highstate my module will not get triggered, unless there is a change in GRAIN_A.
Any suggestions please.
I have tried several jinja expressions.
{% if grains['GRAIN_A'] not in grains.get('GRAIN_B','None') %}
{% set GRAIN_B = grains.get('GRAIN_B','None') %}
{% if grains['GRAIN_A'] != {{ GRAIN_B }} %}```
```{% if grains['GRAIN_A'] not in grains.get('GRAIN_B','None') %}
MY_MODULE:
module.run:
- func: MYMODULE.FUNCTION_A
{% endif %}```
Issue fixed, there is a \n character in my GRAIN_A output, which makes the evaluation condition fails.
This condition works already.
{% if grains['GRAIN_A'] not in grains.get('GRAIN_B','None') %}
MY_MODULE:
module.run:
- func: MYMODULE.FUNCTION_A
{% endif %}

Jekyll/liquid list parameter?

I wanted to create a simply include which simplifies creating a carousel. So I was looking for the syntax to give a list of image urls as a parameter. However I couldn't find anything about this.
{% include carousel.html images=WHAT HERE? %}
You can create a list as a string then convert it into an array inside your snippet. This is the way I would do it.
{% assign urls = 'url1.jpg,url2.jpg,url3.jpg' %}
{% include carousel.html images=urls %}
Of course this is the same as:
{% include carousel.html images='url1.jpg,url2.jpg,url3.jpg' %}
carousel.html
{% assign images = include.images | split: ',' %}
{% for image in images %}
{{ image }}
{% endfor %}

Is there a way in Liquid to use the contains operator to check for an exact match?

When searching an array for a match in a Liquid template, how do you call contains exactly? For example, if tag of a page may contain separable or non-separable, how do you find the pages that contain only the separable and not the non-separable tag? In my experience, the {% if post.tags contains 'separable' %} statement considers both cases.
Refer to the documentation you can use this filter
{% assign tags = post.tags | where:"tag","separable" %}
Loop through the array and check the values with a match operator. If it matches change a variable from false to true:
{% assign found_seperable = false %}
{% for tag in post.tags %}
{% if tag == 'separable' %}
{% assign found_seperable = true %}
{% endif %}
{% endfor %}
Then check the variable:
{% if found_seperable %}
do what you want if true
{% else %}
do what you want if false
{% endif %}