Hi, I want to use the „do“ statement in jinja templating, particularly in a markdown card for lovelace. It seems like the jinja2.ext.do extension has to be used. How can I add this extension?
Updated, more appropriate question: How to extend a dict without do statement?
Hi, thanks for your answer! I want to add new key/value pairs to dictionaries. Precise use case is sorting dates and corresponding events. Sure, it should somehow be possible without dicts, but this seemed to me most elegant. I figured out how to sort given dicts by key or by value. But I can’t define a static dict, I want to add entries based on conditions. I tried some things for adding key/value pairs, but all failed. Here is what I tried from this site so far and what errors I got:
{% set data = {} %}
{%- set _ = data.update({'new_key': new_value}) -%}
Gives: SecurityError: access to attribute 'update' of 'dict' object is unsafe.
{% set _ = data.__setitem__('new_key', new_value) %}
Gives: SecurityError: access to attribute '__setitem__' of 'dict' object is unsafe.
Similarly, I could start with a full dict and delete items using data.pop(), but this gives me the same SecurityError.
Then I found a python-like option using ‘do’:
{%- do data['new_key'] = new_value -%}
Or in the same flavour as the first attempt, without getting a returned value:
{%- do data.update({'new_key': new_value}) -%}
The 'do' statements give me: "TemplateSyntaxError: Encountered unknown tag 'do'." So my idea was to add this extension, but unfortunately, this is not possible.
How is it possible to add key/value pairs to dicts? Or why isn’t it? Why is a SecurityError thrown? It seems that manipulating dictionaries is blocked. Can I unblock those commands manually?
then create your dictionary. You will not be able to update an existing dictionary with .update({})
{% set data = dict.from_keys(kvps) %}
Your best option to ‘update’ an existing dictionary (current) with another dictionaries values (update)…
{# make current a list of tuples #}
{% set current = current.items() | list %}
{# make update a list of tuples #}
{% set update = update.items() | list %}
{# remove keys from current that are in update #}
{% set current = current | rejectattr('0', 'eq', update | map(attribute='0') | list) | list %}
{{ dict.from_keys(current + update) }}
EDIT: This method restricts you from using dictionary keys that start with a number and have whitespace. Keep that in mind.
Thank you so much, that worked! I do not necessarily need to change the dict once it is created (but I learned a lot from your example). Instead, I can iteratively build the list and then create a dict from it, like this:
{% set kvps = [('x', 4), ('y',2)] %}
{% set kvps = kvps + [('z', 1)] %}
{% set data = dict.from_keys(kvps) %}
thanks! after a long search for a solution, this finally helped me solve my problem.
for anyone coming across the same problem: any of these two can be used to filter the attributes of an entity in a template, to only return the ones required.