Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
47985bb
restructuring html for parts
AakashGfude Feb 22, 2022
cbcc5c3
added styling and restructured bs html
AakashGfude Feb 22, 2022
c33f15e
adding list-caption class
AakashGfude Feb 22, 2022
c267479
not adding collapse parts for now
AakashGfude Feb 22, 2022
fc53df7
modified tests
AakashGfude Feb 22, 2022
c54dfb4
pre-commit
AakashGfude Feb 22, 2022
dcf9c2c
Update src/pydata_sphinx_theme/__init__.py
AakashGfude Feb 23, 2022
6698203
opening captions explicitly
AakashGfude Feb 23, 2022
f9a127b
Merge branch 'parts-collapse' of https://github.com/AakashGfude/pydat…
AakashGfude Feb 23, 2022
3761169
making parts text clickable
AakashGfude Feb 23, 2022
ef87163
style for part label
AakashGfude Feb 23, 2022
67c4c2f
pre-commit
AakashGfude Feb 23, 2022
3785a47
corrections in __init__ and tests
AakashGfude Feb 23, 2022
cce1bf9
adding docs for show_nav_levek: 0
AakashGfude Feb 24, 2022
63acd91
parts collapse only when show_nav_level: 0
AakashGfude Feb 24, 2022
cd7ecb3
tests update
AakashGfude Feb 25, 2022
d67480e
added test for sidebar nav_level0
AakashGfude Feb 25, 2022
270fe93
docs edit
AakashGfude Feb 25, 2022
4650f39
parts chevron style
AakashGfude Feb 28, 2022
99b2340
Update docs/user_guide/configuring.rst
AakashGfude Feb 28, 2022
dca2f5d
Update src/pydata_sphinx_theme/__init__.py
AakashGfude Feb 28, 2022
c5ef7d1
Update src/pydata_sphinx_theme/__init__.py
AakashGfude Feb 28, 2022
8e94faf
Update src/pydata_sphinx_theme/__init__.py
AakashGfude Feb 28, 2022
a60b2a7
Update src/pydata_sphinx_theme/__init__.py
AakashGfude Feb 28, 2022
819caed
Update src/pydata_sphinx_theme/__init__.py
AakashGfude Feb 28, 2022
2b43a8c
tests and some code refactoring
AakashGfude Feb 28, 2022
df2ca97
Clarify this in the docs
choldgraf Mar 10, 2022
7da634d
Update docs/user_guide/configuring.rst
choldgraf Mar 10, 2022
a3d4caf
Cleaning up docs
choldgraf Mar 10, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 30 additions & 2 deletions docs/user_guide/configuring.rst
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,8 @@ override this behavior and control the sidebar on a per-page basis, use the

.. _navigation-depth:

Navigation depth and collapsing of the sidebar
==============================================
Navigation depth and collapsing the sidebar
===========================================

By default, this theme enables to expand/collapse subsections in the left
sidebar navigation (without actually navigating to the page itself), and this extends
Expand All @@ -272,6 +272,34 @@ default, you can use the following configuration in ``conf.py``:
This will make the first two navigations show up by default (AKA, top-level
pages and their immediate children).

Collapse entire toctree captions / parts
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If your ``toctree`` elements have captions assigned to them (with ``:caption:``), you may
collapse navigation items so that only the caption is visible. Clicking on the
caption will display the items below.

To enable this behavior, set the ``show_nav_level`` value to 0, like below:

.. code:: python

html_theme_options = {
"show_nav_level": 0
}




You can only collapse your ``toctree`` items underneath their caption if a caption is defined for them!
If your ``toctree`` does not have a caption defined, then all of the pages underneath it will be displayed
(the same as the default theme behavior). See `the toctree documentation <https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-toctree>`_
for more details.

.. note::

In some Sphinx sites, the top-level ``toctree`` groupings make up "parts" in the documentation, with
each page beneath making up a "chapter".

.. _remove_toctrees:

Selectively remove pages from your sidebar
Expand Down
30 changes: 30 additions & 0 deletions src/pydata_sphinx_theme/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,25 @@ def generate_nav_html(kind, startdepth=None, show_nav_level=1, **kwargs):
for ul in soup("ul", recursive=False):
ul.attrs["class"] = ul.attrs.get("class", []) + ["nav", "bd-sidenav"]

# Add collapse boxes for parts/captions.
# Wraps the TOC part in an extra <ul> to behave like chapters with toggles
# show_nav_level: 0 means make parts collapsible.
Comment thread
AakashGfude marked this conversation as resolved.
if show_nav_level == 0:
partcaptions = soup.find_all("p", attrs={"class": "caption"})
if len(partcaptions):
new_soup = bs("<ul class='list-caption'></ul>", "html.parser")
for caption in partcaptions:
# Assume that the next <ul> element is the TOC list
# for this part
for sibling in caption.next_siblings:
if sibling.name == "ul":
toclist = sibling
break
Comment thread
AakashGfude marked this conversation as resolved.
li = soup.new_tag("li", attrs={"class": "toctree-l0"})
li.extend([caption, toclist])
new_soup.ul.append(li)
Comment thread
AakashGfude marked this conversation as resolved.
soup = new_soup

# Add icons and labels for collapsible nested sections
_add_collapse_checkboxes(soup)

Expand Down Expand Up @@ -264,6 +283,12 @@ def _add_collapse_checkboxes(soup):
# We check all "li" elements, to add a "current-page" to the correct li.
classes = element.get("class", [])

# expanding the parent part explicitly, if present
if "current" in classes:
parentli = element.find_parent("li", class_="toctree-l0")
if parentli:
parentli.select("p.caption ~ input")[0].attrs["checked"] = ""

# Nothing more to do, unless this has "children"
if not element.find("ul"):
continue
Expand All @@ -278,8 +303,12 @@ def _add_collapse_checkboxes(soup):
# Add the "label" for the checkbox which will get filled.
if soup.new_tag is None:
continue

label = soup.new_tag("label", attrs={"for": checkbox_name})
label.append(soup.new_tag("i", attrs={"class": "fas fa-chevron-down"}))
if "toctree-l0" in classes:
# making label cover the whole caption text with css
label["class"] = "label-parts"
element.insert(1, label)

# Add the checkbox that's used to store expanded/collapsed state.
Expand All @@ -292,6 +321,7 @@ def _add_collapse_checkboxes(soup):
"name": checkbox_name,
},
)

# if this has a "current" class, be expanded by default
# (by checking the checkbox)
if "current" in classes:
Expand Down
84 changes: 49 additions & 35 deletions src/pydata_sphinx_theme/assets/styles/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -165,34 +165,6 @@ footer {
}
}

.bd-sidebar {
padding-top: 1em;
overflow-y: auto;
display: flex;
flex-direction: column;

@include media-breakpoint-up(md) {
border-right: 1px solid rgba(0, 0, 0, 0.1);

@supports (position: -webkit-sticky) or (position: sticky) {
position: -webkit-sticky;
position: sticky;
top: var(--pst-header-height);
z-index: 1000;
height: calc(100vh - var(--pst-header-height));
}
}

&.no-sidebar {
border-right: 0;
}

.sidebar-end-items {
margin-top: auto;
margin-bottom: 1em;
}
}

.bd-links {
padding-top: 1rem;
padding-bottom: 1rem;
Expand Down Expand Up @@ -346,7 +318,8 @@ nav.bd-links {

/* Nav: hide second level (shown on .active) */

.bd-toc .nav {
.bd-toc .nav,
.list-caption {
.nav {
display: none;

Expand Down Expand Up @@ -522,8 +495,44 @@ nav.bd-links {
}

.bd-sidebar {
padding-top: 1em;
Comment thread
AakashGfude marked this conversation as resolved.
overflow-y: auto;
display: flex;
flex-direction: column;

@include media-breakpoint-up(md) {
border-right: 1px solid rgba(0, 0, 0, 0.1);

@supports (position: -webkit-sticky) or (position: sticky) {
position: -webkit-sticky;
position: sticky;
top: var(--pst-header-height);
z-index: 1000;
height: calc(100vh - var(--pst-header-height));
}
}

&.no-sidebar {
border-right: 0;
}

.sidebar-end-items {
margin-top: auto;
margin-bottom: 1em;
}
.list-caption {
list-style: none;
padding-left: 0px;
}
li {
position: relative;
// If it has children, add a bit more padding to wrap the content to avoid
// overlapping with the <label>
&.has-children {
> .reference {
padding-right: 30px;
}
}
}
label {
position: absolute;
Expand Down Expand Up @@ -553,12 +562,17 @@ nav.bd-links {
}
}
}

// If it has children, add a bit more padding to wrap the content to avoid
// overlapping with the <label>
li.has-children {
> .reference {
padding-right: 30px;
.label-parts {
width: 100%;
height: 100%;
&:hover {
background: none;
}
i {
width: 30px;
position: absolute;
top: 0.3em; // aligning chevron with text
right: 0em; // aligning chevron to the right
}
}
}
Expand Down
40 changes: 40 additions & 0 deletions tests/test_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,46 @@ def test_sidebars_level2(sphinx_build_factory, file_regression):
file_regression.check(sidebar.prettify(), extension=".html")


def test_sidebars_show_nav_level0(sphinx_build_factory, file_regression):
"""
Regression test for show_nav_level:0 when the toc is divided into parts.
Testing both home page and a subsection page for correct elements.
"""
confoverrides = {"html_theme_options.show_nav_level": 0}
sphinx_build = sphinx_build_factory("sidebars", confoverrides=confoverrides).build()

# 1. Home Page
index_html = sphinx_build.html_tree("section1/index.html")
sidebar = index_html.select("nav#bd-docs-nav")[0]

# check if top-level ul is present
ul = sidebar.find("ul")
assert "list-caption" in ul.attrs["class"]

# get all li elements
li = ul.select("li")

# part li
assert "toctree-l0 has-children" in " ".join(li[0].attrs["class"])
assert "caption-text" in li[0].select("p span")[0].attrs["class"]
assert "label-parts" in li[0].find("label").attrs["class"]

# basic checks on other levels
assert "toctree-l1 has-children" in " ".join(li[1].attrs["class"])
assert "toctree-l2" in li[2].attrs["class"]

# 2. Subsection Page
subsection_html = sphinx_build.html_tree("section1/subsection1/index.html")
sidebar = subsection_html.select("nav#bd-docs-nav")[0]

# get all input elements
input_elem = sidebar.select("input")

# all input elements should be collapsed in this page
for ii in input_elem:
assert "checked" in ii.attrs


def test_included_toc(sphinx_build_factory):
"""Test that Sphinx project containing TOC (.. toctree::) included
via .. include:: can be successfully built.
Expand Down