elchininet / custom-sidebar

Custom HACS plugin that allows you to manage Home Assistant's sidebar items per user or device basis
Apache License 2.0
22 stars 3 forks source link
custom-plugin custom-plugins custom-sidebar custom-sidebars hacs hacs-plugin home-assistant homeassistant javascript lovelace lovelace-ui plugin

Custom Sidebar

hacs_badge HACS Action Tests Coverage Status downloads

Home Assistant Nightly Beta Tests

Custom HACS plugin that allows you to manage Home Assistant's sidebar items per user or device basis.

Default sidebar Hide some items Add new items Reorder items
default sidebar hide items new items reorder items

This is a refactor of custom-sidebar-v2 by @galloween, which unfortunatelly is now unmaintained and archived. In its beginning, @galloween's code was a refactor of the original Custom Sidebar plugin by @Villhellm (R.I.P.). This version refactored completely @galloween's code allowing to use a configuration in YAML (as @Villhellm's one) or in JSON (as @galloween's version), fixing several bugs, improving performance, and using home-assistant-query-selector to make it less likely to break with future Home Assistant front-end updates.

Installation

You can install the plugin manually or through HACS, not both. If you install the plugin using the two installations methods you could have issues or errors.

Through HACS (v2 or greather)

Note: if your version of HACS is lower than v2 consult the section Through old HACS versions (< v2)

  1. Go to HACS dashboard
  2. Click on the three-dots icon in the top-right corner
  3. Select Custom repositories
  4. In the Repository field insert https://github.com/elchininet/custom-sidebar and in the Type select Dashboard
  5. Click on Add
  6. Search for custom-sidebar and click on it
  7. On the plugin page, click on the Download yellow button in the bottom-right corner
  8. Click on Download in the more-info dialog
  9. When the plugin is already downloaded, add the url of the plugin as an extra_module_url in your configuration.yaml:

If you want to use a YAML configuration

frontend:
  extra_module_url:
    - /hacsfiles/custom-sidebar/custom-sidebar-yaml.js?v1.0.0

If you want to use a JSON configuration

frontend:
  extra_module_url:
    - /hacsfiles/custom-sidebar/custom-sidebar-json.js?v1.0.0
  1. Make sure you add the correct version at the end of the URL (e.g. ?v=1.0.0) because in this way you make Home Assistant to load the new version instead of a version stored in cache
  2. Restart Home Assistant

Through old HACS versions (< v2)

  1. Go to HACS dashboard
  2. Go to Frontend
  3. Click on the three-dots icon in the top-right corner
  4. Select Custom repositories
  5. In the repository field insert https://github.com/elchininet/custom-sidebar and in the category select Lovelace
  6. Click on Add
  7. Click on Explore and download repositories button in the bottom-right of the screen
  8. Search for custom-sidebar and install it
  9. Add the url of the plugin as an extra_module_url in your configuration.yaml:

If you want to use a YAML configuration

frontend:
  extra_module_url:
    - /hacsfiles/custom-sidebar/custom-sidebar-yaml.js?v1.0.0

If you want to use a JSON configuration

frontend:
  extra_module_url:
    - /hacsfiles/custom-sidebar/custom-sidebar-json.js?v1.0.0
  1. Make sure you add the correct version at the end of the URL (e.g. ?v=1.0.0) because in this way you make Home Assistant to load the new version instead of a version stored in cache
  2. Restart Home Assistant

Manual installation

  1. Download the latest custom-sidebar release
  2. Copy custom-sidebar-yaml.js or custom-sidebar-json.js into <config directory>/www/ (depending on the configuration format that you are going to use, YAML or JSON)
  3. Add the url of the plugin as an extra_module_url in your configuration.yaml:

If you want to use a YAML configuration

frontend:
  extra_module_url:
    - /local/custom-sidebar-yaml.js?v1.0.0

If you want to use a JSON configuration

frontend:
  extra_module_url:
    - /local/custom-sidebar-json.js?v1.0.0
  1. Make sure you add the correct version at the end of the URL (e.g. ?v=1.0.0) because in this way you make Home Assistant to load the new version instead of a version stored in cache
  2. Restart Home Assistant

Configuration

Depending on the file that you have added to extra_module_url, you will need to add your configuration in YAML or JSON format. If you used custom-sidebar-yaml.js you need to provide the configuration in YAML format. If you have used custom-sidebar-json.js you need to provide the configuration in JSON format.

Add a file named sidebar-config.yaml or sidebar-config.json into your <config directory>/www/ directory. It could be easier if you copy the example sidebar-config.yaml or the example sidebar-config.json file, delete the id parameter, and edit it to match your needs.

Configuration options

Property Type Required Description
order Array of item yes List of items to process
title* String no Custom title to replace the Home Assistant title
sidebar_editable* Boolean or String no If it is set to false, long press on the sidebar title will be ignored and the button to edit the sidebar in the profile panel will be disabled. As a string it should be a JavaScript or a Jinja template that returns true or false
styles String no Custom styles that will be added to the styles block of the plugin

Order item properties

Property Type Required Description
item String yes This is a string that will be used to match each sidebar item by its text, its data-panel attribute or its href. If the exact property is not set, it is case insensitive and it can be a substring such as developer instead of Developer Tools or KITCHEN instead of kitchen-lights.
match String no This property will define which string will be used to match the item property. It has three possible values "text" (default) to match the text content of the element, "data-panel" to match the data-panel attribute of the element, or "href", to match the href attribute of the element
exact Boolean no Specifies whether the item string match should be an exact match (true) or not (false).
name* String no Changes the name of the sidebar item
notification* String no Add a notification badge to the sidebar item
order Number no Sets the order number of the sidebar item
bottom Boolean no Setting this property to true will group the item with the bottom items (Configuration, Developer Tools, etc)
hide Boolean no Setting this property to true will hide the sidebar item
href String no Specifies the href of the sidebar item
target String no Specifies the target property of the sidebar item
icon String no Specifies the icon of the sidebar item
new_item Boolean no Set this property to true to create a new item in the sidebar. Using this option makes href and icon required properties

* These options and item properties allow JavaScript or Jinja templates.

Short example in YAML format:

title: My Home
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: Integrations
    href: "/config/integrations"
    icon: mdi:puzzle
    order: 3
styles: |
  paper-listbox {
      --icon-primary-color: var(--accent-color);
  }

Short example in JSON format:

{
  "title": "My Home",
  "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": "Integrations",
      "href": "/config/integrations",
      "icon": "mdi:puzzle",
      "order": 3
    }
  ],
  "styles": "paper-listbox { --icon-primary-color: var(--accent-color); }"
 }

Notes

Exceptions

You can define user-specific options using exceptions feature. Exceptions can be used if you would like to define different options for a specific user/device.

Property Type Required Description
order Array of item no Defines the sidebar items order
title* String no Custom title to replace the Home Assistant title
sidebar_editable* Boolean or String no If it is set to false, long press on the sidebar title will be ignored and the button to edit the sidebar in the profile panel will be disabled. As a string it should be a JavaScript or a Jinja template that returns true or false
styles String no Custom styles that will be added to the styles block of the plugin
extend_from_base Boolean no If true, the options will be extended with the root options. The property order will be merged with the base one, the rest of properties will use the base counterpart if they are not specified. If it is false, it will take into account only the options in the exception
user String or String[] no Home Assistant user name(s) you would like to display this order for
not_user String or String[] no Home Assistant user name(s) you wouldn't like to display this order for
device String or String[] no Device(s) you would like to display this order for. E.g. ipad, iphone, macintosh, windows, android (it uses the device's user-agent)
not_device String or String[] no Device(s) you wouldn't like to display this order for. E.g. ipad, iphone, macintosh, windows, android (it uses the device's user-agent)

* These options and item properties allow JavaScript or Jinja templates.

Short example in YAML format:

...
exceptions:
  - user:
    - Jim Hawkins
    - Long John Silver
    title: My Home
    order:
      ...

Short example in JSON format:

{
  ...
  "exceptions": [
    {
      "user": ["Jim Hawkins", "Long John Silver"],
      "title": "My Home",
      "order": [
          ...
      ]
    }
  ]  
}

Notes

Templates

Some config options and item properties, as title, sidebar_editable, name and notification, admit templates. custom-sidebar admits two templating systems, JavaScript templates or Jinja templates. JavaScript templates are processed faster because the rendering is done in client side, Jinja templates need to perform a websocket call to receive the template result, but in general you should not notice many differences between the two in terms of performance. The main difference between the two templating systems (apart from the syntax) is that JavaScript can access client side data like DOM APIs meanwhile Jinja templates are agnostic to the device in which Home Assistant is being executed.

JavaScript templates

This templating system IS NOT the same that Home Assistant implements. It is basically a JavaScript code block in which you can use certain client-side objects, variables and methods. To set a property as a JavaScript template block, include the code between three square brackets [[[ JavaScript code ]]]. If you don‘t use the square brackets, the property will be interpreted as a regular string.

The JavaScript code will be taken as something that you want to return, but if you have a more complex logic, you can create your own variables and return the desired result at the end.

The entities and domains used in the templates will be stored so if the state of these entities change, it will update the templates used in the configuration.

JavaScript templates example

The next example will set the title of the sidebar as "My Home" followed by the current time. It will also add the number of HACS updates as a notification in the HACS item in the sidebar. In case that there are no updates, an empty string is returned and in these cases the notification will not be displayed. And it also creates a new item that redirects to the Home Assistant info page with a dynamic text with the word "Info" followed by the installed Supervisor version between parentheses.

in YAML format:
title: '[[[ "My Home " + new Date(states("sensor.date_time_iso")).toLocaleTimeString().slice(0, 5) ]]]'
order:
  - item: hacs
    notification: |
      [[[
        const outdatedHacsEntities = Object.values(entities.update).filter(
          (entity) => entity.platform === 'hacs' && is_state(entity.entity_id, 'on')
        );
        return outdatedHacsEntities.length || '';
      ]]]
  - new_item: true
    item: info
    name: '[[[ "Info (" + state_attr("update.home_assistant_supervisor_update", "latest_version") + ")" ]]]'
    href: '/config/info'
    icon: mdi:information-outline
in JSON format:
{
  "title": "[[[ 'My Home ' + new Date(states('sensor.date_time_iso')).toLocaleTimeString().slice(0, 5) ]]]",
  "order": [
    {
      "item": "hacs",
      "notification": "[[[ return Object.values(entities.update).filter((entity) => entity.platform === 'hacs' && is_state(entity.entity_id, 'on')).length || '' ]]]"
    },
    {
      "new_item": true,
      "item": "info",
      "name": "[[[ 'Info (' + state_attr('update.home_assistant_supervisor_update', 'latest_version') + ')' ]]]",
      "href": "/config/info",
      "icon": "mdi:information-outline"
    }
  ]
}

Note: Custom Sidebar uses Home Assistant Javascript Templates for the JavaScript templating system. To know all the objects, variables and methods available in the JavaScript templates, consult the proper section in the repository.

Jinja templates

This templating system is the same that Home Assistant implements. You can use the majority of the template methods and objects. The entire template will be processed, rendered and the result will be used as the inner html of the element. If you don‘t want to display anything in certain scenarios, you should return an empty string in those cases. The next client side varianles will be available in Jinja templates:

When the entities and domains used in a templates change, it will trigger an update and the updated result of the template will be rendered.

Jinja templates example

The next example will set the title of the sidebar as "My Home" followed by the current time. It will also add the number of HACS updates as a notification in the HACS item in the sidebar. In case that there are no updates, an empty string is returned and in these cases the notification will not be displayed. And it also creates a new item that redirects to the Home Assistant info page with a dynamic text with the word "Info" followed by the installed Supervisor version between parentheses.

in YAML format:
title: 'My Home {{ as_timestamp(states("sensor.date_time_iso")) | timestamp_custom("%H:%M") }}'
order:
  - item: hacs
    notification: |
      {{
        expand(states.update)
        | selectattr('state', 'eq', 'on')
        | map(attribute='entity_id')
        | map('device_attr', 'identifiers')
        | map('contains', 'hacs')
        | list
        | length or ""
      }}
  - new_item: true
    item: info
    name: 'Info ({{ state_attr("update.home_assistant_supervisor_update", "latest_version") }})'
    href: '/config/info'
    icon: mdi:information-outline
in JSON format:
{
  "title": "My Home {{ as_timestamp(states('sensor.date_time_iso')) | timestamp_custom('%H:%M') }}",
  "order": [
    {
      "item": "hacs",
      "notification": "{{ expand(states.update) | selectattr('state', 'eq', 'on') | map(attribute='entity_id') | map('device_attr', 'identifiers') | map('contains', 'hacs') | list | length or '' }}"
    },
    {
      "new_item": true,
      "item": "info",
      "name": "Info ({{ state_attr('update.home_assistant_supervisor_update', 'latest_version') }})",
      "href": "/config/info",
      "icon": "mdi:information-outline"
    }
  ]
}

Home Assistant built-in sidebar configuration options

Check out Home Assistant's native sidebar tools, maybe it will be enough for your needs.


Credits and huge thanks to: