sphinx_rtd_theme icon indicating copy to clipboard operation
sphinx_rtd_theme copied to clipboard

Prevent left menu items from being collapsed

Open layoaster opened this issue 8 years ago • 20 comments

According to this thread it seems that 'collapse_navigation': False doesn't behave as one would expect.

Is there any option to make items not collapsable on the navigation menu?

layoaster avatar Aug 23 '17 17:08 layoaster

So if I understand you correctly, you want to see the whole documentation structure open all the time?

Blendify avatar Aug 23 '17 17:08 Blendify

That's exactly what I meant @Blendify . All items expanded (by "all", I meant the ones allowed by navigation_depth)

layoaster avatar Aug 24 '17 08:08 layoaster

This one is really confusing to me too... I've read through a bunch of the docs, and until I landed on this stackoverflow answer I'd been rebuilding my docs over and over in an attempt to get some combination of 'collapse_navigation': False and 'navigation_depth': 4 or 'navigation_depth': -1 to do what I thought it/they would do: show the entire toctree in the sidebar all the time...

I think this is both unclear from the docs, and a feature that I'd really like to see. Yeah, I'd also like to see the whole documentation structure open all the time, especially when I have some docs that are structured with only a few top-level headings, i.e.:

  • Foo
    • Bar
    • Baz
    • Blam
  • Lorem
    • ipsum
    • sit
    • dolor

jantman avatar Apr 26 '18 11:04 jantman

Big +1 on this. Projects trend small. Power law and all that.

For smaller projects (e.g., hyperlink), an always-expanded TOC tree would be great. I'm trying some wild jQuery hacks to try and stop .toggleCurrent() from collapsing the other entries without forking the theme, but I'd really rather this were supported via html_theme_options :)

mahmoud avatar May 02 '18 02:05 mahmoud

+1 Also. This would be awesome indeed!

Any guidance on how to achieve this? html_theme_options would be the way to go.

vonpupp avatar Oct 25 '18 14:10 vonpupp

This should be possible by changing our javascript. I doubt I will have time but I can look into this.

Blendify avatar Oct 26 '18 18:10 Blendify

This is currently not possible because the JS and CSS that expand menu items assume that only the active/current menu item is expanded. Decoupling is tracked in #692. if that is approved and merged, this can be either JS or (even better) Python code that sets the .expanded class on all menu items.

jessetan avatar Oct 29 '18 10:10 jessetan

+1 would love to see this!

manjotpahwa avatar Feb 03 '20 09:02 manjotpahwa

+1

alexei-developer avatar Feb 15 '20 20:02 alexei-developer

+1

mherkazandjian avatar Feb 27 '20 18:02 mherkazandjian

Is there any update on this?

jantman avatar Apr 21 '20 11:04 jantman

I managed to do this with custom javascript

html_js_files = [
    'js/custom.js'
]

html_theme_options = {
    "collapse_navigation": False,
}

custom.js

window.addEventListener('load', (event) => {
    var menu = document.querySelector(".wy-menu ul li:first-child")
    if (!menu.classList.contains("current")) {
        menu.classList.add("current")
    }
});

dorinoltean avatar Dec 09 '20 12:12 dorinoltean

Unfortunately the custom js doesn't work for me locally, as soon as I switch to another tab, the first section collapses.

Big +1 on this functionality for me as well, I'd really like it in multiple projects.

jennirinker avatar May 07 '21 10:05 jennirinker

+1, would also like this feature.

I have expanded on the script from @dorinoltean, as his script was only expanding the toctree 1 level for me. My script will expand everything to its maximum depth.

It is important to state this is quite an ugly hack to something that should work by default (IMO). If tomorrow the theme changes the classes, the HTML structure or fixes the issue, it is likely the hack will either stop working or become obsolete.

Given however that this issue was created in 2017 and there are people still complaining today, it may take a while for that future to come though.

window.addEventListener('load', (_event) => {
    var menu = document.querySelector(".wy-menu ul li:first-child")
    recurse(menu)
});

/**
 * Given a Node, it recursively goes through every child and checks if the child is expandable, it
 * expands it unless it is already expanded.
 * 
 * @param {Node} node 
 */
function recurse(node) {
    if (is_expandable(node) && !is_expanded(node)) {
        node.classList.add("current")
    }

    // By default, children are not arrays, so we need to convert them
    children = Array.prototype.slice.call(node.children)

    children.forEach(recurse)
}

/**
 * Returns whether or not the given node is an expandable list.
 * 
 * @param {Node} node 
 * @returns {boolean} true if the node is a toctree that can be expanded, false otherwise.
 */
function is_expandable(node) {
    return node.className.includes("toctree-l")
}

/**
 * Returns whether or not the given expandable node is already expanded.
 * Nodes are considered expandaded if they are 'current'ly selected, so we take advantage of this.
 * 
 * @param {Node} node 
 * @returns {boolean} true if the node is already expanded, false otherwise.
 */
function is_expanded(node) {
    return node.classList.contains("current")
}

Fl4m3Ph03n1x avatar Sep 29 '21 13:09 Fl4m3Ph03n1x

Another +1 on this feature. Unfortunately neither of the two js solutions posted above worked for me.

scottshambaugh avatar Dec 19 '21 05:12 scottshambaugh

+1

JonasKlotz avatar Jan 14 '22 09:01 JonasKlotz

+1 also here.

Both solutions above were not working for me. I adapted @Fl4m3Ph03n1x code - maybe not be the smartest, but now it works. I now select the elements with class .toctree-l1, and then check if each of them has li children.

window.addEventListener('load', (_event) => {
    var menu = document.querySelectorAll(".toctree-l1")
    menu.forEach(recurse);
});

/**
 * Given a Node, it recursively goes through every child and checks if the child is expandable, it
 * expands it unless it is already expanded.
 * 
 * @param {Node} node 
 */
function recurse(node) {
    if (is_expandable(node) && !is_expanded(node)) {
        node.classList.add("current");
    }

    // By default, children are not arrays, so we need to convert them
    children = Array.prototype.slice.call(node.children)

    children.forEach(recurse)
}

/**
 * Returns whether or not the given node is an expandable list.
 * 
 * @param {Node} node 
 * @returns {boolean} true if the node is a toctree that can be expanded, false otherwise.
 */
function is_expandable(node) {
    return node.querySelectorAll("li").length > 0
}

/**
 * Returns whether or not the given expandable node is already expanded.
 * Nodes are considered expandaded if they are 'current'ly selected, so we take advantage of this.
 * 
 * @param {Node} node 
 * @returns {boolean} true if the node is already expanded, false otherwise.
 */
function is_expanded(node) {
    return node.classList.contains("current")
}

edit: Just to make it clear, it also depends on

html_theme_options = {
  'collapse_navigation': False,
  }

html_js_files = [
    'custom.js'
]

in the conf.py file.

edit 2: Argh, it works for the initial page, but not when I click on others. Sorry. Anyway, ++1 for the feature.

filipesmg avatar Apr 13 '22 14:04 filipesmg

Adding to this! I've recently started with Sphinx and this theme and I've quickly found out about this issue. Would love to have the feature available "by-design", since none of the js above worked properly for me.

slim71 avatar May 29 '22 09:05 slim71

+1 on this. I'd love to have this as out-of-the-box functionality.

DSSAtDatagen avatar Jan 25 '23 12:01 DSSAtDatagen

html_theme = 'sphinx_book_theme'

html_theme_options = {
    "show_navbar_depth": 2
}

FYI: this works for me.

turboFei avatar Mar 09 '23 14:03 turboFei