Generates list with template

Is there a way to dynamically generate a list in a yaml file using Jinja?

For example if I have a script like this:

test_script:
  fields:
    var1:
      default: false
    var2:
      default: false
    var3:
      default: false
  sequence:
    - service: notify.my_mail
      data:
        title: "Testing"
        data:
          images:
            - /config/www/pic1.jpg
            - /config/www/pic2.jpg
            - /config/www/pic3.jpg

As you can see the smtp notify service requires a list for the “images” field. I thought I could do something like this if I want to use the input parameters to control which of the 3 pictures should be included:

          images: >
            {% if var1 == true %}
            - /config/www/pic1.jpg
            {% endif %}
            {% if var2 == true %}
            - /config/www/pic2.jpg
            {% endif %}
            {% if var3 == true %}
            - /config/www/pic3.jpg
            {% endif %}

While the output looks exactly what I want, HA treats the entire output of the template as one single string, and therefore does not see the dashes as list items.

I also tried to template just the filename and leave the dash outside of the template:

          images:
            - {{ 'pic1.jpg' if var1 == true else '' }}
            - {{ 'pic2.jpg' if var2 == true else '' }}
            - {{ 'pic3.jpg' if var3 == true else '' }}

However the smtp service would abort as soon as it see an empty list item.

The best I could come up with is to substitute the real image with a blank one like this:

          images:
            - /config/www/{{ 'pic1' if var1 == true else 'blank' }}.jpg
            - /config/www/{{ 'pic2' if var2 == true else 'blank' }}.jpg
            - /config/www/{{ 'pic3' if var3 == true else 'blank' }}.jpg

Is there a better way?

You could try to see if a list works. If this does work, then templating it should be relatively easy:


test_script:
  fields:
    var1:
      default: false
    var2:
      default: false
    var3:
      default: false
  sequence:
    - service: notify.my_mail
      data:
        title: "Testing"
        data:
          images: ['/config/www/pic1.jpg', '/config/www/pic2.jpg', '/config/www/pic3.jpg']

1 Like

Try like this

images: >
  {% set my_list = [] %}
  {% if var1 %}
    {% set my_list = my_list + ['/config/www/pic1.jpg'] %}
  {% endif %}
  {% if var2 %}
    {% set my_list = my_list + ['/config/www/pic2.jpg'] %}
  {% endif %}
  {% if var3 %}
    {% set my_list = my_list + ['/config/www/pic3.jpg'] %}
  {% endif %}
  {{ my_list }}

Or:

images: >
  {% set mapping = {        
                     'pic1.jpg': var1,
                     'pic2.jpg': var2,
                     'pic3.jpg': var3
                    }
  %}
  {{ mapping.items()
      | selectattr('1')
      | map(attribute='0')
      | map('regex_replace', '^', '/config/www/')
      | list
  }}
1 Like

Thanks! Didn’t know that you can use the square bracket instead. :stuck_out_tongue:

I rewrote the script to look something like this and it works! The smtp service just ignore all the extra commas when some of the variables are false.

images: >
  [ {{ '/config/www/pic1.jpg' if var1 == true }},
    {{ '/config/www/pic2.jpg' if var2 == true }},
    {{ '/config/www/pic3.jpg' if var3 == true }} ]

Thank TheFes! Those are much nicer than the one I came up with. I ended up using the 2nd one you suggested.