Skip to content

Commit

Permalink
Create DictMerge (#24)
Browse files Browse the repository at this point in the history
* Personal adjustment

* Create Dict Merge

* Add patch

* Test 2

* Final fix

* Update Readme, change function names for merge

* Fix example code

---------

Co-authored-by: Michael Carroll
  • Loading branch information
droans authored Jun 10, 2024
1 parent 6945511 commit 39748dd
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 3 deletions.
45 changes: 45 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ This integration adds possibility to use new functions in Home Assistant Jinja2
- `ct_all_translations` - returns all available translations (that can be used with `ct_translated`)
- `ct_eval` - evaluates text as a template
- `ct_is_available` - checks if given entity is available
- `ct_dict_merge` - Merges two or more dictionaries together.

## Usage

Expand Down Expand Up @@ -257,6 +258,50 @@ false
</tr>
</table>

### `ct_dict_merge`

This function will merge one or more dictionaries (mappings) together into a single dictionary.
If any key is shared between two or more dictionaries, the value of the key will be the last value passed.

<table>
<tr>
<th>
Input
</th>
<th>
Output
</th>
</tr>
<tr>
<td>

```yaml
{% set dict_1 = {'a':1,'b':2,'c':3} %}
{% set dict_2 = {'d':4,'e':5,'f':6} %}
{% set dict_3 = {'b':7,'d':8,'g':9} %}
{{ ct_dict_merge(dict_1, dict_1) }}
{{ ct_dict_merge(dict_1, dict_2) }}
{{ ct_dict_merge(dict_2, dict_3) }}
{{ ct_dict_merge(dict_1, dict_2, dict_3) }}
```

</td>
<td>

```django
{'a': 1, 'b': 2, 'c': 3}
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6}
{'d': 8, 'e': 5, 'f': 6, 'b': 7, 'g': 9}
{'a': 1, 'b': 7, 'c': 3, 'd': 8, 'e': 5, 'f': 6, 'g': 9}
```

</td>
</tr>
</table>

## Configuration

To use this integration you have to add following config in `configuration.yaml`:
Expand Down
20 changes: 18 additions & 2 deletions custom_components/custom_templates/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
from .const import (DOMAIN, CUSTOM_TEMPLATES_SCHEMA, CONF_PRELOAD_TRANSLATIONS, CONST_EVAL_FUNCTION_NAME,
CONST_STATE_TRANSLATED_FUNCTION_NAME, CONST_STATE_ATTR_TRANSLATED_FUNCTION_NAME,
CONST_TRANSLATED_FUNCTION_NAME, CONST_ALL_TRANSLATIONS_FUNCTION_NAME,
DEFAULT_UNAVAILABLE_STATES, CONST_IS_AVAILABLE_FUNCTION_NAME)
DEFAULT_UNAVAILABLE_STATES, CONST_IS_AVAILABLE_FUNCTION_NAME,
CONST_DICT_MERGE_FUNCTION_NAME)

_LOGGER = logging.getLogger(__name__)

Expand All @@ -33,6 +34,18 @@ def validate_language(self, language):
raise TemplateError(f"Language {language} is not loaded") # type: ignore[arg-type]


class DictMerge:

def __init__(self, hass: HomeAssistant):
self._hass = hass

def __call__(self, *args):
result = {k:v for d in args for k, v in d.items()}
return result

def __repr__(self):
return f"<template CT_DictMerge 0.01>"

class IsAvailable:

def __init__(self, hass: HomeAssistant):
Expand Down Expand Up @@ -311,13 +324,14 @@ async def load_translations(_event: Event):
all_translations_template = AllTranslations(hass, languages)
eval_template = EvalTemplate(hass)
is_available_template = IsAvailable(hass)
dict_merge_template = DictMerge(hass)

_TranslationCache.ct_patched_get_cached = get_cached

def is_safe_callable(self: TemplateEnvironment, obj):
# noinspection PyUnresolvedReferences
return (isinstance(obj, (
StateTranslated, StateAttrTranslated, EvalTemplate, Translated, AllTranslations, IsAvailable))
StateTranslated, StateAttrTranslated, EvalTemplate, Translated, AllTranslations, IsAvailable, DictMerge))
or self.ct_original_is_safe_callable(obj))

def patch_environment(env: TemplateEnvironment):
Expand All @@ -327,11 +341,13 @@ def patch_environment(env: TemplateEnvironment):
env.globals[CONST_ALL_TRANSLATIONS_FUNCTION_NAME] = all_translations_template
env.globals[CONST_EVAL_FUNCTION_NAME] = eval_template
env.globals[CONST_IS_AVAILABLE_FUNCTION_NAME] = is_available_template
env.globals[CONST_DICT_MERGE_FUNCTION_NAME] = dict_merge_template
env.filters[CONST_STATE_TRANSLATED_FUNCTION_NAME] = state_translated_template
env.filters[CONST_STATE_ATTR_TRANSLATED_FUNCTION_NAME] = state_attr_translated_template
env.filters[CONST_TRANSLATED_FUNCTION_NAME] = translated_template
env.filters[CONST_EVAL_FUNCTION_NAME] = eval_template
env.filters[CONST_IS_AVAILABLE_FUNCTION_NAME] = is_available_template
env.filters[CONST_DICT_MERGE_FUNCTION_NAME] = dict_merge_template

def patched_init(
self: TemplateEnvironment,
Expand Down
3 changes: 2 additions & 1 deletion custom_components/custom_templates/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@
CONST_STATE_ATTR_TRANSLATED_FUNCTION_NAME = "ct_state_attr_translated"
CONST_TRANSLATED_FUNCTION_NAME = "ct_translated"
CONST_ALL_TRANSLATIONS_FUNCTION_NAME = "ct_all_translations"
CONST_IS_AVAILABLE_FUNCTION_NAME = "ct_is_available"
CONST_IS_AVAILABLE_FUNCTION_NAME = "ct_is_available"
CONST_DICT_MERGE_FUNCTION_NAME = 'ct_dict_merge'

0 comments on commit 39748dd

Please sign in to comment.