Add iif (immediate if) template function/filter (#61428)

This commit is contained in:
Franck Nijhof 2021-12-21 17:25:07 +01:00 committed by GitHub
parent 0e9282a404
commit 07e034c1c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 55 additions and 1 deletions

View File

@ -17,7 +17,7 @@ repos:
hooks:
- id: codespell
args:
- --ignore-words-list=hass,alot,datas,dof,dur,ether,farenheit,hist,iff,ines,ist,lightsensor,mut,nd,pres,referer,rime,ser,serie,te,technik,ue,uint,visability,wan,wanna,withing,iam,incomfort,ba,haa
- --ignore-words-list=hass,alot,datas,dof,dur,ether,farenheit,hist,iff,iif,ines,ist,lightsensor,mut,nd,pres,referer,rime,ser,serie,te,technik,ue,uint,visability,wan,wanna,withing,iam,incomfort,ba,haa
- --skip="./.*,*.csv,*.json"
- --quiet-level=2
exclude_types: [csv, json]

View File

@ -1763,6 +1763,25 @@ def slugify(value, separator="_"):
return slugify_util(value, separator=separator)
def iif(
value: Any, if_true: Any = True, if_false: Any = False, if_none: Any = _SENTINEL
) -> Any:
"""Immediate if function/filter that allow for common if/else constructs.
https://en.wikipedia.org/wiki/IIf
Examples:
{{ is_state("device_tracker.frenck", "home") | iif("yes", "no") }}
{{ iif(1==2, "yes", "no") }}
{{ (1 == 1) | iif("yes", "no") }}
"""
if value is None and if_none is not _SENTINEL:
return if_none
if bool(value):
return if_true
return if_false
@contextmanager
def set_template(template_str: str, action: str) -> Generator:
"""Store template being parsed or rendered in a Contextvar to aid error handling."""
@ -1877,6 +1896,7 @@ class TemplateEnvironment(ImmutableSandboxedEnvironment):
self.filters["int"] = forgiving_int_filter
self.filters["relative_time"] = relative_time
self.filters["slugify"] = slugify
self.filters["iif"] = iif
self.globals["log"] = logarithm
self.globals["sin"] = sine
self.globals["cos"] = cosine
@ -1906,6 +1926,7 @@ class TemplateEnvironment(ImmutableSandboxedEnvironment):
self.globals["pack"] = struct_pack
self.globals["unpack"] = struct_unpack
self.globals["slugify"] = slugify
self.globals["iif"] = iif
self.tests["match"] = regex_match
self.tests["search"] = regex_search

View File

@ -21,6 +21,7 @@ from homeassistant.const import (
TEMP_CELSIUS,
VOLUME_LITERS,
)
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import TemplateError
from homeassistant.helpers import device_registry as dr, entity, template
from homeassistant.helpers.entity_platform import EntityPlatform
@ -3101,6 +3102,38 @@ def test_urlencode(hass):
assert tpl.async_render() == "the%20quick%20brown%20fox%20%3D%20true"
def test_iif(hass: HomeAssistant) -> None:
"""Test the immediate if function/filter."""
tpl = template.Template("{{ (1 == 1) | iif }}", hass)
assert tpl.async_render() is True
tpl = template.Template("{{ (1 == 2) | iif }}", hass)
assert tpl.async_render() is False
tpl = template.Template("{{ (1 == 1) | iif('yes') }}", hass)
assert tpl.async_render() == "yes"
tpl = template.Template("{{ (1 == 2) | iif('yes') }}", hass)
assert tpl.async_render() is False
tpl = template.Template("{{ (1 == 2) | iif('yes', 'no') }}", hass)
assert tpl.async_render() == "no"
tpl = template.Template("{{ not_exists | default(None) | iif('yes', 'no') }}", hass)
assert tpl.async_render() == "no"
tpl = template.Template(
"{{ not_exists | default(None) | iif('yes', 'no', 'unknown') }}", hass
)
assert tpl.async_render() == "unknown"
tpl = template.Template("{{ iif(1 == 1) }}", hass)
assert tpl.async_render() is True
tpl = template.Template("{{ iif(1 == 2, 'yes', 'no') }}", hass)
assert tpl.async_render() == "no"
async def test_cache_garbage_collection():
"""Test caching a template."""
template_string = (