sidebarMod: Add/Remove Sidebar Links and Sections

sidebarMod

here’s my script for modding the sidebar (first mentioned in the custom sidebar sections topic).

it uses promises and MutationObserver to watch the sidebar for changes (e.g. from expanding or collapsing) and add/remove stuff in a performant way.

i think i made it flexible enough for most use cases. you can add links (positioned by appending, prepending, or inserting before/after existing links), remove sections, remove links, and even remove ⋮More.

it’s even possible to change the behavior if the viewer is a guest or a registered user. for example, i’m using it to remove a custom section that is irrelevant to guests.

it’s a nice complement to the new custom sidebar sections feature (enabled via SiteSetting.enable_custom_sidebar_sections), so i didn’t bother adding a feature to create sections.

let me know if you find bugs or need extra features.

installation

create a new theme component and paste it into Head. remember to enable it for your theme.

configuration

you only need to edit injections and removals near the top.

i suggest just leaving it as-is at first so you see what it’s doing. i tried to make the example config illustrative.

i’m personally using it like this:

  /**
   * link positioners:
   *   (bool) prepend, append: prepend/append link to section
   *   (str)  addBeforeKebab, addAfterKebab: add link before/after existing link
   * link visibility:
   *   (str)  injectFor: inject link only for 'anon' users, only for 'registered' users, or for 'both' (default: 'both')
   */
  injections: [
    { sectionSelector: '.sidebar-section[data-section-name="community"]',
      links: [
        { text: 'Guidelines', kebab: 'guidelines', title: 'Guidelines for using this site', href: '/guidelines', icon: 'gavel', addBeforeKebab: 'faq', injectFor: 'registered' }
      ]
    },
    { sectionSelector: '.sidebar-section[data-section-name="categories"]',
      links: [
        { text: 'Site Map', kebab: 'site-map', title: 'Site Map', href: '/t/32', icon: 'map-marker-alt', prepend: true }
      ]
    }
  ],

  /**
   * section options:
   *   (str) removeFor: remove section only for 'anon' users, only for 'registered' users, or for 'both' (default: 'none')
   *   (str) removeMore: remove '⋮More' only for 'anon' users, only for 'registered' users, or for 'both' (default: 'none')
   *                       useful if you know it's empty due to link removals
   * link removal options:
   *   (str) removeFor: remove link only for 'anon' users, only for 'registered' users, or for 'both' (default: 'both')
   */
  removals: [
    { sectionSelector: '.sidebar-section[data-section-name="community"]',
      links: [{ kebab: 'badges', removeFor: 'anon' }]
    },
    { sectionSelector: '.sidebar-custom-sections .sidebar-section[data-section-name="my-topics"]',
      removeFor: 'anon'
    }
  ],

questions from me

i investigated doing this with the API, but i don’t think enough stuff is implemented.

if i wanted to do this “the right way” instead of hacking things into the DOM, how would i do that? would i need to make a plugin with ruby? any hints would be appreciated.

2 Likes

updated to work with data-link-name

Thanks, this was really helpful for me implementing a custom sidebar section that needs to be updated on page transitions (see Making custom changes to the sidebar programmatically). One problem I have is that when the custom links are clicked, a full page refresh is triggered. Did you somehow get around this?

FYI, found a solution here: Reload page body when clicking a link in a custom header