Custom-sidebar: manage Home Assistant's sidebar items per user or device basis

Folks,
[email protected] has been released. It comes with many changes and improvements:

  1. base_order option in exceptions has been renamed to extend_from_base. If it is true it will merge order from base with the order from the exception, for the rest of properties it will take the propery from the base if it is not available in the exception.
  2. Now it is possible to set more options in exceptions apart from order:
    • title
    • sidebar_editable
    • styles

    If extend_from_base is true and any of these options are not set, it will try to get them from the base config.

  3. order in exceptions is not mandatory anymore.
  4. sidebar_editable apart from a boolean now accepts a string with a JavaScript or a Jinja template. The template should return true or false, otherwise it will be ignored.
  5. When sidebar_editable is false it will also avoid showing the glow circle around the mouse when one press and hold over the title
  6. Now you can use some client side variables inside Jinja templates (they were available in JavaScript templates but not in Jinja ones):
    • user_name: String with the logged user’s name
    • user_is_admin: Bolean value than indicates if the logged user is admin or not
    • user_is_owner: Bolean value than indicates if the logged user is the owner or not
    • user_agent: User agent of the browser in which Home Assistant is being executed
1 Like

The latest major update of custom-sidebar has been released. This major update comes with a lot of new options that will allow you to personalise almost everything of your Home Assistant sidebar, and what is more important, in a very very easy way: through simple configuration options.

Almost all of the new options accept JavaScript or Jinja templates. So it will be possible to change any of these options when certain entity of Home Assistant changes its state. So imagine to change the color of a sidebar item when an alarm is activated or changing completely the colors of the sidebar when the Christmas tree is on. The possibilities are infinite and the limit is your imagination :wink:

Try it out and post the result back :blush:

2 Likes

Hi, I have a problem, because I install the plugin from HACS and add the line in my configuration but it still doesn’t work. Any help?

This is the configuration:

“- hacsfiles/custom-sidebar/custom-sidebar-yaml.js?v=6.1.1”

Muchas gracias!

Add a slash at the beginning of your hacsfiles alias:

/hacsfiles/custom-sidebar/custom-sidebar-yaml.js?v1.0.0

Yes i have this slash “/”, but is not working!

The version at the end: “?v=6.1.1” is correct right?

Yes, that doesn’t matter. Open an issue in the repo so I can ask you for some info to debug it.

I clear the cache of the App and now works!!!

Thanks for your hard work!!!

1 Like

A new custom-sidebar version has been released. This is a minor update of the library and brings support for templates in the icons as well as new features and options. This should not be a breaking change for current implementations even if the code has been refactored in some extent.

1. Add support for templates in icons

From now on, it is possible to add a template in the icon property of an order item, so it will be possible to change the icon if the state of some entity changes.

order:
  - new_item: true
    item: Automations
    href: "/config/automation"
    icon: |
        [[[ is_state('input_boolean.dark_mode', 'on') ? 'mdi:robot-outline' : 'mdi:robot' ]]]

2. JavaScript templates can return Promises

From now on, the result of a JavaScript template can be asynchronous, if a JavaScript template return a Promise, the template will not be evaluated until it resolves.

order:
  - new_item: true
    item: Router
    href: "http://192.168.1.1"
    icon: mdi:router-wireless
    info: |
      [[[
        return fetch('http://192.168.1.1/some-endpoint')
          .then((response) => response.json())
          .then((result) => {
            if (result.active) {
              return 'On'
            }
            return 'Off';
          });
      ]]]

3. There is a new variable to use in JavaScript templates (panel_url)

Now it is possible to use a new variable in JavaScript templates to return the current panel URL. For example, panel_url will return /config/dashboard if the config panel is rendered. This variable will be reevaluated every time that the URL changes, so if you go to another panel or you change views inside the same lovelace panel, the template in which it was used will be reevaluated and the new result will be rendered. This is useful to set different colors in the sidebar when changing dashboards:

sidebar_background: |
  [[[
    if (panel_url.startsWith('/lovelace')) {
       return 'center / cover no-repeat fixed url("/local/sidebar-background.png")';
    }
    return 'var(--sidebar-background-color)';
  ]]]

4. New options to set variables for JavaScript and Jinja templates

Now it is possible to set variables that will be used inside the JavaScript and Jinja templates. These variables cannot be templates and only strings, numbers or booleans values are supported.

JavaScript variables

js_variables:
  alarm: input_boolean.alarm_activated
order:
  - new_item: true
    item: Alarm
    href: "/lovelace/alarm"
    info: |
      [[[ is_state(alarm, 'on') ? 'On' : 'Off' ]]]

Jinja variables

jinja_variables:
  alarm: input_boolean.alarm_activated
order:
  - new_item: true
    item: Alarm
    href: "/lovelace/alarm"
    info: |
      {{ 'On' if (is_state(alarm, 'on')) else 'Off' }}

5. New option to set partials

Partials are fragments of code that can be included in your templates. They can be inserted in JavaScript or Jinja templates or inside another partial. Any entity used in them will make the template in which the partial is inserted to be reevaluated when the entity changes its state.

Note: Partials will automatically use the variables set in the js_variables or jinja_variables (depending on the kind of template in which they are inserted).

Partials example with a JavaScript template

in YAML format:
js_variables:
  supervisor_update: update.home_assistant_supervisor_update
  os_update: update.home_assistant_operating_system_update
partials:
  supervisor_version: |
    const supervisorVersion = state_attr(supervisor_update, "latest_version");
  updates: |
    @partial supervisor_version
    const osVersion = state_attr(os_update, "latest_version");
order:
  - new_item: true
    item: info
    name: |
      [[[
        @partial updates
        return `Info ${supervisorVersion}`;
      ]]]
    info: |
      [[[
        @partial updates
        return `OS ${ osVersion }`
      ]]]
    href: '/config/info'
    icon: mdi:information-outline
in JSON format:
{
  "js_variables": {
    "supervisor_update": "update.home_assistant_supervisor_update",
    "os_update": "update.home_assistant_operating_system_update"
  },
  "partials": {
    "supervisor_version": "const supervisorVersion = state_attr(supervisor_update, 'latest_version');",
    "updates": "@partial supervisor_version const osVersion = state_attr(os_update, 'latest_version');"
  },
  "order": [
    {
      "new_item": true,
      "item": "info",
      "name": "[[[ @partial updates return `Info ${supervisorVersion}`; ]]]",
      "info": "[[[ @partial updates return `OS ${ osVersion }`; ]]]",
      "href": "/config/info",
      "icon": "mdi:information-outline"
    }
  ]
}

Partials example with a Jinja template

in YAML format:
jinja_variables:
  supervisor_update: update.home_assistant_supervisor_update
  os_update: update.home_assistant_operating_system_update
partials:
  supervisor_version: |
    {% set supervisorVersion = state_attr(supervisor_update, "latest_version") %}
  updates: |
    @partial supervisor_version
    {% set osVersion = state_attr(os_update, "latest_version") %}
order:
  - new_item: true
    item: info
    name: |
        @partial updates
        Info {{ supervisorVersion }}
    info: |
        @partial updates
        OS {{ osVersion }}
    href: '/config/info'
    icon: mdi:information-outline
in JSON format:
{
  "jinja_variables": {
    "supervisor_update": "update.home_assistant_supervisor_update",
    "os_update": "update.home_assistant_operating_system_update"
  },
  "partials": {
    "supervisor_version": "{% set supervisorVersion = state_attr(supervisor_update, 'latest_version') %}",
    "updates": "@partial supervisor_version {% set osVersion = state_attr(os_update, 'latest_version') %}"
  },
  "order": [
    {
      "new_item": true,
      "item": "info",
      "name": "@partial updates Info {{ supervisorVersion }}",
      "info": "@partial updates OS {{ osVersion }}",
      "href": "/config/info",
      "icon": "mdi:information-outline"
    }
  ]
}

Could you share the code for the background color/theme please? I can’t figure it out myself.

Hi @sebastiaan,
Which background color/theme?

thank you for your response. the third one you posted in the major update.

That one is using a background from lovelace-ios-themes. As it is a remote background you could set it up with this code:

sidebar_background: center / cover no-repeat fixed url('https://cdn.jsdelivr.net/gh/basnijholt/lovelace-ios-themes@a37376d918fcfe4785be99910dc9a7200ac37da9/themes/homekit-bg-blue-red.jpg')
2 Likes

Thanks! It works :blush:

1 Like

Hello,

I’m trying to get this to work and have not been successful. I am running home assistant via docker.

I have installed the custom-sidebar through HACS and added the module to the front end.

frontend:
  extra_module_url:
    - /config/www/community/lovelace-card-mod/card-mod.js
    - /config/www/community/custom-sidebar/custom-sidebar-yaml.js?v6.6.0

and added the sidebar-config.yaml to the following directory

root@RockServer:/config/www# ls
alexa_tts  community  sidebar-config.yaml
root@RockServer:/config/www# 

and I used the small example from the github page, but after I restarted Home Assistant the side bar did not change

title: My Home
icon_color_selected: var(--accent-color)
order:
  - new_item: true
    item: Google
    href: https://mrdoob.com/projects/chromeexperiments/google-gravity/
    icon: mdi:earth
    target: _blank
    order: 1
  - item: overview
    order: 2
  - new_item: true
    item: Automations
    href: "/config/automation"
    icon: mdi:robot
    info: |
      {{ states.automation | selectattr('state', 'eq', 'on') | list | count }} active
    order: 3

is there something obvious I’m missing?

Hi @rocksolidsr,
Consult the 5th step in the documentation and also check my comment in this issue.

You should have errors in your dev console that the resource cannot be loaded from that path.

How do I find out what the “href” is for “Add-Ons”, “Node Red”, and others. I did an inspect on the page where you click on Add-Ons, but there was nothing in the page source that told me what the href would be. I’ve tried"/config/Add-Ons" and that didn’t work.
Perhaps we could publish the HREFs for most of the menu items so they could be listed in one place


I did follow those steps that is why I included the snippet from my configuration.yaml and showed the location of the module from within the docker. Did I somehow get that wrong?

I do not see any errors in my dev console either.

No need to, when you open the dashboard, just check the URL in your browser:

For example, if you go to Settings > Addons, the URL will be http://xxx.xxx.xxx.xxx/hassio/dashboard, so the href should be /hassio/dashboard

You didn’t follow the steps if you are using this path: /config/www/community/custom-sidebar/custom-sidebar-yaml.js. That path is not the one that is provided in 5th step (either HACS or manual installations). Just check the second link that I posted, it is the same case as yours.

Quick test, I added /config/www/community/custom-sidebar/custom-sidebar-yaml.js as an extra_module_url in the custom-sidebar Docker demo configuration

Opened the demo, and this is the result:

yes you are correct, I misread the instructions and was unclear about the path. I got it working with your help, thanks a lot I appreciate it!

1 Like