Decluttering Card Plus — a maintained continuation of decluttering-card (badges, cross-dashboard templates, repeat)

Write a card once, use it everywhere.

The original decluttering-card hasn’t
had a release since April 2023, and a few long-standing requests in its thread were never
merged. I’ve picked it up as Decluttering Card Plus and have been maintaining it since.

:point_right: GitHub - tempus2016/decluttering-card-plus: 🧹 Maintained successor to decluttering-card. Reusable Lovelace card templates with variables, visual editors, and custom styling. · GitHub

It’s a drop-in replacement. It registers custom:decluttering-card and
custom:decluttering-template as well as its own -plus types, and decluttering_templates
is unchanged — so you install it, remove the old card, and change nothing else. (Don’t run
both; whichever loads first claims the old names.)

What’s new on top of the original

  • Badge templates — templates for the dashboard badge row, not just cards (HA 2024.8+).
  • Templates shared between dashboards — define once, use on every dashboard.
  • visibility: works inside templates.
  • Repeat — build one card per entity from a list, or from an area/device/label, and skip
    copies that have nothing to show.
  • Defaults for every template on a dashboard, so instances only pass what differs.
  • Editor niceties — see what a card actually builds, see what uses a template before you
    change it, rename a template and have the uses follow, and export/import a template to
    share it with someone else.
  • Plus the entity-row and picture-elements templating from
    PR #78, which never got merged
    upstream, and a pile of variable-substitution and layout fixes.

Install — HACS custom repository (type: Dashboard):
https://github.com/tempus2016/decluttering-card-plus
or one click: Add to HACS

DocsQuick Start
· Variables
· Recipes
· Troubleshooting
· Releases

Requires HA 2024.7+. MIT, same as the original — full credit to RomRider, j9brown and
simbaja, whose work this builds on.

Bug reports and feature requests welcome on the
issue tracker.

3 Likes

v1.2.0 is out. The headline is a card per room that knows what’s in it.

Repeating over areas used to give you the room’s name and nothing about what was inside it,
so “a tile per room, each listing that room’s lights” still meant writing a card per room by
hand. Now with: gathers the entities for each area and hands them to the copy:

type: custom:decluttering-card-plus
template: room_summary
for_each_from:
  areas: true
  with:
    domain: light
columns: 3

Each copy gets items, which goes straight into a nested repeat — so the template draws the
room heading and then repeats a second template over that room’s own lights. One card, the
whole house. Rooms with nothing in them are left out unless you ask to keep them.

The rest, briefly:

  • Repeats can say what to leave out. exclude: light.bedside — patterns mean entity ids,
    or a mapping to exclude by area or label. Also device_class and integration, since a
    domain on its own is too coarse when you want motion sensors but not door sensors. Plus
    sort, reverse, limit (with a total that reports what matched before the limit, so
    a card can say “showing 5 of 23”), and empty: for a card to draw when nothing matches.

  • Placeholders can say what to do when nothing sets them. [[name|default:Unnamed]] puts
    that text in; [[name|or:label]] tries another variable; they chain. That’s different from
    [[name?]], which takes the option out of the card entirely.

  • Three more things to ask Home Assistant forfloor, and area_id / device_id, the
    ids rather than the names, for when you’re building one entity id out of another:
    binary_sensor.[[entity|area_id]]_motion.

  • The editor shows what a repeat matches as you type it, so a typo in an area name reads
    as “nothing matched that” instead of “this card is broken”. You can also duplicate a
    template, reorder its variables, and start from a few built-in examples.

  • Fixed: a template whose card used that same template froze the browser tab. There was
    no guard at all — every level built the next one before any of them reached the page. It now
    refuses and names the loop. Also fixed: [[entity|friendly_name]] never worked inside a
    repeat.

  • debug: true renders what the card actually built instead of the card, which is what you
    want when something only misbehaves on a phone.

  • The editors now speak French, Spanish and Portuguese, following your Home Assistant
    language.

Docs have moved to a proper site with search: Decluttering Card Plus | Reusable Lovelace card templates for Home Assistant

There’s also a whole demo dashboard in the repo under examples/ — paste it into a new
dashboard’s raw editor and it renders, no edits needed.

Still a drop-in. Nothing in your existing configuration needs changing.

Full notes: Release v1.2.0 · tempus2016/decluttering-card-plus · GitHub

I didn’t even know I needed a updated version. Have used the original version with no problems.

I have a old iPad Pro as a dashboard. It was a little slow, however what to expect from a 9 year old device.

Found your new version of Decluttering and installed, just to get the new version. And some of the new features might come handy.

Then, out of the blue, my old iPad running the dashboard was significantly faster. Thanks.

1 Like

@khvej8
Hopefully that’s due to the updated code :wink:
If you need any help, let me know.

1 Like

Decluttering Card Plus v1.3.0

v1.3.0 is out. Short version: it speaks German and Dutch now, there are two new transforms for tidying up text people type, a repeat can be sorted by anything its copies carry, and the starter library in the editor is a dropdown instead of five rows of buttons.

On languages — everything the card says follows the language in your Home Assistant profile, including the editors and the warnings it writes to the console. That’s six now: Dutch, English, French, German, Portuguese and Spanish, and anything a translation misses falls back to English key by key rather than going blank. I wrote the German and Dutch against the English file, so if either reads oddly to a native speaker, say so in this thread and I’ll fix it — it’s one file per language, no code, and corrections are genuinely welcome.

Two new transforms, trim and capitalize, for values that come from an input_text or from someone typing a name in by hand:

# room: '  living room  '
name: '[[room|trim|capitalize]]'   # Living room
name: '[[room|trim|title]]'        # Living Room

capitalize only touches the first character. title capitalises every word, which is right for a label and wrong for a sentence.

A repeat can now be ordered by anything its copies carry. sort: used to take six fixed names and quietly ignore anything else; a name outside that list is now read as a key on the copies themselves, so a grouped repeat can order rooms by how much is in them:

for_each_from:
  areas: true
  with:
    domain: light
  sort: entity_count      # emptiest rooms first

Numbers compare as numbers, so 2 comes before 10 rather than after it, and ties fall back to name order.

One thing to watch if you already use sort:. A misspelt value used to do nothing at all and leave the registry’s own order alone; now it sorts by a key nothing has, which comes out as name order instead. sort: none is still how you ask for “however Home Assistant listed them”.

Last one: the starter library on the editor’s Share tab. It used to be five examples in a list with a button each, taking up most of the tab. Pick one from the dropdown now and it tells you what it is and what else it’ll bring with it before you commit to anything, and Install asks twice rather than leaving you wondering whether the first press did anything.

Release, with the full notes: Release v1.3.0 · tempus2016/decluttering-card-plus · GitHub
Docs: Home · tempus2016/decluttering-card-plus Wiki · GitHub

Update through HACS as usual.

v1.4.0 is out — five transforms that take an argument.

Until now a transform did one fixed thing: [[room|slug]], |upper, |trim. These five take a value after a colon, the way attr: always has.

# room: 'living_room_lamp'
name: '[[room|replace:_: ]]'      # living room lamp
name: '[[room|replace:_]]'        # livingroomlamp - deletes when no "to" is given
entity: '[[room|prefix:light.]]'  # light.living_room_lamp
name: '[[room|suffix: 2]]'        # living_room_lamp 2
name: '[[room|max:12]]'           # living_room…

map is the one I think most people will get something out of. It turns a value into something a card option will actually accept — a colour, a label, an icon name:

# level: 'high'
color: '[[level|map:low=green,high=red]]'   # red
color: '[[level|map:low=green,*=grey]]'     # grey, for anything not listed

A value that no pair names leaves the placeholder visible rather than passing through something color would choke on, and *= is the catch-all if you’d rather have a fallback.

The argument runs to the end of the step, so it can hold spaces and colons of its own — replace:_: reads as “underscores to spaces”, trailing space included. It can’t hold a bar or a closing bracket, since those are what end the placeholder. They chain like anything else: [[room|replace:_:-|upper]] gives LIVING-ROOM-LAMP.

One thing worth mentioning if you use the optional marker. prefix and suffix decorate a value rather than supply one, so an empty value stays empty: [[name|suffix: sensors?]] drops the key entirely instead of leaving a stray " sensors" behind. And a ? written against the closing brackets is always the marker, never the last character of the argument.

This release also carries a security fix that went into main after 1.3.0 but hadn’t been cut into a release yet. access_token and entity_picture are now refused by the attr: resolver, so a template you copied from somewhere else can’t pull a camera’s credentials into a config that then sends them somewhere. It also caps runaway variable expansion so a crafted template can’t hang the tab. If you’re on 1.3.0 it’s worth updating for that alone.

Nothing to do when you upgrade — every transform here is new syntax, so existing templates behave exactly as they did.

Release notes: Release v1.4.0 · tempus2016/decluttering-card-plus · GitHub
Docs: Variables · tempus2016/decluttering-card-plus Wiki · GitHub

v1.5.0 is out, and it is all about shaping the list a repeat produces rather than choosing what goes into it.

require: drops a copy whose key came out empty, an entity in no area or an area on no floor, and it runs before anything is counted, so total tells you what is actually on screen rather than what matched. offset: skips the first few copies so two cards can split one long list between them, and total deliberately ignores the window so both halves still say “of 23”. Sorting picked up a leading minus to turn one key around, and a list of keys that breaks ties with the next, so sort: [floor, -entity_count] goes floor by floor with the busiest room in each one first. sort: attr:temperature orders by a state attribute, as a snapshot taken when the card is built rather than a live order. And overrides: gives named copies their own variables without excluding anything.

Most of it in one card:

type: custom:decluttering-card-plus
template: room_tile
for_each_from:
  domain: light
  require: area
  sort: [area, -name]
  overrides:
    light.kitchen_ceiling:
      icon: mdi:ceiling-light
      name: The big one

Also fixed: a sort: named after an inherited property, like constructor, threw instead of falling through to a key the copies carry.

Nothing in here changes what an existing card builds. All five are opt-in, so a repeat that does not name them sorts and counts exactly as it did before.

Release notes: Release v1.5.0 · tempus2016/decluttering-card-plus · GitHub
Docs: Repeating a Template · tempus2016/decluttering-card-plus Wiki · GitHub

I’d love to use it, but I have a question:
I have a couple of custom room cards that I would like to declutter. These cards are showing entity states like sensors, lights, windows, fans, thermostats, covers, etc.
Let’s say, there is a room that does not have a cover or a fan, but everything else like the other rooms. How does the decluttering card treat parts of the template when a variable is not of use? Will there be an error? Is it possible to hide this?

1 Like

No error — a variable nothing sets is just left as written, so you’d get [[fan]] sitting there where an entity id should be, plus a warning in the console. But you can hide it: put a ? inside the brackets and the option is taken out of the card entirely when nothing sets it.

The trick is to make the whole row optional, not just the entity id, otherwise you’re left with an empty row:

decluttering_templates:
  room:
    card:
      type: entities
      title: '[[room]]'
      entities:
        - entity: '[[light]]'
        - entity: '[[temp]]'
        - '[[fan_row?]]'
        - '[[cover_row?]]'

Then rooms that have a fan pass one:

variables:
  room: Living room
  light: light.living
  temp: sensor.living_temp
  fan_row:
    entity: fan.living
    name: Ceiling fan

and the office just leaves fan_row out — no row, no gap. Works the same for whole cards in a vertical-stack or grid, so an optional Mushroom fan card is fine too.

There’s also [[name|default:Something]] if you’d rather show a fallback than drop the option, and debug: true on a card shows you exactly what it built if you want to check what survived.