-
-
Notifications
You must be signed in to change notification settings - Fork 0
Variables
Variables are the holes in a template. You write [[name]] in the template, and pass a
value for name when you use it.
decluttering_templates:
room_light:
card:
type: tile
entity: '[[light]]'
name: '[[room]]'type: custom:decluttering-card-plus
template: room_light
variables:
- light: light.kitchen
- room: KitchenA placeholder is a name in double square brackets: [[light]], [[room]], [[accent]].
When a placeholder is the whole value, quote it.
entity: '[[light]]' # ✅
entity: [[light]] # ❌ not valid YAML - "[" starts a listInside a longer string, quotes are optional but harmless.
name: [[room]] light'
title: Lights in [[room]]Placeholders work anywhere in the content — keys' values, nested mappings, list items,
even inside CSS in a style block. They are substituted throughout the whole
template body.
variables: on the instance is a list, one key per entry:
variables:
- light: light.kitchen
- room: Kitchendefault: on the template supplies fallbacks, so callers only pass what differs.
decluttering_templates:
area_sensor:
card:
type: tile
entity: '[[entity]]'
name: '[[label]]'
icon: '[[icon]]'
default:
- label: [[area]] temperature'
- area: Living Room
- entity: sensor.living_room_temperature
- icon: mdi:thermometerUsed with no variables at all, it renders entirely from the defaults. Override one, and only that one changes:
# 1. nothing passed - pure defaults
- type: custom:decluttering-card-plus
template: area_sensor
# 2. override the area, and the label follows
- type: custom:decluttering-card-plus
template: area_sensor
variables:
- area: Bedroom
- entity: sensor.bedroom_temperature
# 3. override the label outright
- type: custom:decluttering-card-plus
template: area_sensor
variables:
- label: Solar output right now
- entity: sensor.solar_power
- icon: mdi:solar-power
default: uses the same list-of-mappings shape as variables:.
The default values are also what the visual editor uses to draw its
preview, so giving every variable a sensible default makes templates much nicer to work on.
A default can contain placeholders of its own. Above, label defaults to
[[area]] temperature', so changing area changes the label without the caller ever
mentioning label.
Substitution repeats until nothing is left to replace, so the order you declare them in does not matter, and a value you pass always beats a default — including when the placeholder only appears because of an earlier substitution.
This also gives you "fall back to another variable":
default:
- title: '[[name]]' # if no title is given, use the name
- name: SensorA variable that refers to itself can never be resolved. Substitution gives up after 10 passes and logs a warning to the browser console rather than hanging:
decluttering-card-plus: gave up substituting variables after 10 passes.
Check whether a variable refers to itself.
Ten passes is far more than any sane template needs — chains that deep are fine, cycles are not.
How a value is substituted depends on where the placeholder sits.
The type is preserved. Numbers stay numbers, booleans stay booleans, and mappings and lists are inserted as structure.
decluttering_templates:
sized_tile:
card:
type: tile
entity: '[[entity]]'
name: '[[name]]'
grid_options:
columns: '[[cols]]' # whole value
rows: 1variables:
- cols: 12 # inserted as the number 12, not "12"
This matters: columns: "12" would be a string and Home Assistant would ignore it.
The same applies to structures:
card:
type: tile
entity: '[[entity]]'
features: '[[features]]'variables:
- features:
- type: toggle
- type: light-brightnessand to booleans and null:
variables:
- show_name: true
- icon: nullThe value is inserted as text.
name: [[room]] light'With room: Kitchen this becomes Kitchen light. A mapping or list used this way is
inserted as its JSON text, which is occasionally useful and usually not what you want.
Values containing quotes, backslashes, newlines or tabs are escaped correctly. So multi-line values and Jinja templates work:
variables:
- message: >-
Line one
Line two
- jinja: "{{ states('sensor.x') | float * 2 }}"Values containing $& or $1 are inserted literally rather than being interpreted as
replacement patterns, and variable names containing regex characters are matched
literally too.
If a placeholder has no matching variable and no default, it is left in place. You will
see the literal text [[light]] in the rendered card, or Home Assistant complaining about
an unknown entity called [[light]].
That is the number one symptom of a typo in a variable name. See Troubleshooting.
You will also see this in the visual editor while editing a template — the card editor there is looking at the raw template, so it reports
[[light]]as an unknown entity. That is expected and harmless.
| Where | Example | Result |
|---|---|---|
| Whole value, string |
entity: '[[e]]' with e: light.x
|
light.x |
| Whole value, number |
columns: '[[c]]' with c: 12
|
12 (number) |
| Whole value, boolean |
show: '[[s]]' with s: true
|
true (boolean) |
| Whole value, mapping/list | features: '[[f]]' |
inserted as structure |
Whole value, null
|
icon: '[[i]]' with i: null
|
null |
| Inside a string |
name: [[r]] light' with r: Hall
|
Hall light |
| No such variable | entity: '[[nope]]' |
left as [[nope]]
|
| Precedence | Winner |
|---|---|
variables on the instance vs default on the template |
variables |
| Same key twice in one list | the first one |
→ Cards · Badges · Rows · Elements → Recipes for finished examples
Getting started
Core concepts
Content types
Features
- Repeating a Template
- Sharing Between Dashboards
- Sharing a Template
- Visibility
- Styling
- Visual Editors
- Translations
Reference