Add as_function to allow macros to return values
Breaking change
Proposed change
This PR implements the following architectural choices: https://github.com/home-assistant/architecture/discussions/1218
I frequently built utility macros for myself (and am excited for the folks supplying them through HACS), but one of my biggest frustrations has been the inability to return non-string values. This change makes it possible for people building such macros to make richer macros that return any kind of value by adding the as_function filter.
For example:
{%- macro macro_double(num, returns) -%}
{%- do returns(num * 2) -%}
{%- endmacro -%}
{%- set double = macro_double | as_function -%}
{{ double(5) + 5 }}
Which would give the integer value 15. The function double is importable from other templates and can be used in other contexts, both as filters and as inline calls. This is instead of writing a macro and then parsing the resulting string back into whatever type it needs to be (a dict, a number, a list, etc.), which is how many are working around this right now, and which can cause confusion.
Type of change
- [ ] Dependency upgrade
- [ ] Bugfix (non-breaking change which fixes an issue)
- [ ] New integration (thank you!)
- [x] New feature (which adds functionality to an existing integration)
- [ ] Deprecation (breaking change to happen in the future)
- [ ] Breaking change (fix/feature causing existing functionality to break)
- [ ] Code quality improvements to existing code or addition of tests
Additional information
- This PR fixes or closes issue: fixes #
- This PR is related to issue:
- Link to documentation pull request: https://github.com/home-assistant/home-assistant.io/pull/38730
- Link to developer documentation pull request:
- Link to frontend pull request:
Checklist
- [x] The code change is tested and works locally.
- [x] Local tests pass. Your PR cannot be merged unless tests pass
- [x] There is no commented out code in this PR.
- [x] I have followed the development checklist
- [x] I have followed the perfect PR recommendations
- [x] The code has been formatted using Ruff (
ruff format homeassistant tests) - [x] Tests have been added to verify that the new code works.
If user exposed functionality or configuration variables are added/changed:
- [x] Documentation added/updated for www.home-assistant.io
If the code communicates with devices, web services, or third-party tools:
- [ ] The manifest file has all fields filled out correctly.
Updated and included derived files by running:python3 -m script.hassfest. - [ ] New or updated dependencies have been added to
requirements_all.txt.
Updated by runningpython3 -m script.gen_requirements_all. - [ ] For the updated dependencies - a link to the changelog, or at minimum a diff between library versions is added to the PR description.
To help with the load of incoming pull requests:
- [ ] I have reviewed two other open pull requests in this repository.
I wasn't sure how this particular change would be received but figured it's easier to talk about something concrete so I made the quick pull request. If it seems reasonable, I'll add the docs as well.
This is quite a major feature change to our template engine. I think we should have an architectural proposal & discussion first, before making this pull request.
../Frenck
This is quite a major feature change to our template engine. I think we should have an architectural proposal & discussion first, before making this pull request.
../Frenck
Sure -- I'll mark this as a draft and try to open a discussion on it. The change itself is quite small -- not really changing the engine at all (just adding 2 higher-order filters to it), but it does meaningfully change the model that folks can use to build with it.
@frenck started a discussion here: https://github.com/home-assistant/architecture/discussions/1218
@frenck or others: any interest in continuing to discuss on https://github.com/home-assistant/architecture/discussions/1221 and https://github.com/home-assistant/architecture/discussions/1218 (split into 2 discussions for each part)?
With the architectural questions accepted, I'm reopening this. In the architecture discussions, I broke these two things out. It's possible to do that in the PR as well if needed -- let me know. I'd probably have to sequence them because there's some overlap in the testing, but it's doable.
Splitting this out -- marking as draft for now.
@Petro31 Split into this PR and https://github.com/home-assistant/core/pull/144227
@frenck Resolved merge conflicts.