Skip to content

Commit e916043

Browse files
✨ ENH: Make starting depth of sidebar configurable in generated html (#309)
1 parent 89d3885 commit e916043

File tree

19 files changed

+203
-9
lines changed

19 files changed

+203
-9
lines changed

pydata_sphinx_theme/__init__.py

+26-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
def add_toctree_functions(app, pagename, templatename, context, doctree):
1515
"""Add functions so Jinja templates can add toctree objects."""
1616

17-
def generate_nav_html(kind, **kwargs):
17+
def generate_nav_html(kind, startdepth=None, **kwargs):
1818
"""
1919
Return the navigation link structure in HTML. Arguments are passed
2020
to Sphinx "toctree" function (context["toctree"] below).
@@ -27,6 +27,10 @@ def generate_nav_html(kind, **kwargs):
2727
----------
2828
kind : ["navbar", "sidebar", "raw"]
2929
The kind of UI element this toctree is generated for.
30+
startdepth : int
31+
The level of the toctree at which to start. By default, for
32+
the navbar uses the normal toctree (`startdepth=0`), and for
33+
the sidebar starts from the second level (`startdepth=1`).
3034
kwargs: passed to the Sphinx `toctree` template function.
3135
3236
Returns
@@ -37,6 +41,22 @@ def generate_nav_html(kind, **kwargs):
3741
toc_sphinx = context["toctree"](**kwargs)
3842
soup = bs(toc_sphinx, "html.parser")
3943

44+
if startdepth is None:
45+
startdepth = 1 if kind == "sidebar" else 0
46+
47+
# select the "active" subset of the navigation tree for the sidebar
48+
if startdepth > 0:
49+
selector = " ".join(
50+
[
51+
"li.current.toctree-l{} ul".format(i)
52+
for i in range(1, startdepth + 1)
53+
]
54+
)
55+
subset = soup.select(selector)
56+
if not subset:
57+
return ""
58+
soup = bs(str(subset[0]), "html.parser")
59+
4060
# pair "current" with "active" since that's what we use w/ bootstrap
4161
for li in soup("li", {"class": "current"}):
4262
li["class"].append("active")
@@ -54,13 +74,15 @@ def generate_nav_html(kind, **kwargs):
5474
for li in soup("li"):
5575
li["class"].append("nav-item")
5676
li.find("a")["class"].append("nav-link")
77+
# only select li items (not eg captions)
5778
out = "\n".join([ii.prettify() for ii in soup.find_all("li")])
5879

5980
elif kind == "sidebar":
81+
# Add bootstrap classes for first `ul` items
82+
for ul in soup("ul", recursive=False):
83+
ul.attrs["class"] = ul.attrs.get("class", []) + ["nav", "bd-sidenav"]
6084

61-
# Join all the top-level `li`s together for display
62-
current_lis = soup.select("li.current.toctree-l1 li.toctree-l2")
63-
out = "\n".join([ii.prettify() for ii in current_lis])
85+
out = soup.prettify()
6486

6587
elif kind == "raw":
6688
out = soup
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
<nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation">
22
<div class="bd-toc-item active">
3-
<ul class="nav bd-sidenav">
4-
{{ generate_nav_html("sidebar", maxdepth=4, collapse=True, includehidden=True, titles_only=True) }}
5-
</ul>
3+
{{ generate_nav_html("sidebar", maxdepth=4, collapse=True, includehidden=True, titles_only=True) }}
64
</div>
75
</nav>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation">
2+
<div class="bd-toc-item active">
3+
<!-- Use deeper level for sidebar -->
4+
{% if pagename.startswith("section1/subsection1") %}
5+
{{ generate_nav_html("sidebar", startdepth=2, maxdepth=4, collapse=True, includehidden=True, titles_only=True) }}
6+
{% else %}
7+
{{ generate_nav_html("sidebar", maxdepth=4, collapse=True, includehidden=True, titles_only=True) }}
8+
{% endif %}
9+
</div>
10+
</nav>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{% extends "pydata_sphinx_theme/layout.html" %}
2+
3+
{# Silence the navbar #}
4+
{% block docs_navbar %}
5+
{% endblock %}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation">
2+
<div class="bd-toc-item active">
3+
<!-- Specify a startdepth of 0 instead of default of 1 -->
4+
{{ generate_nav_html("sidebar", startdepth=0, maxdepth=4, collapse=True, includehidden=True, titles_only=True) }}
5+
</div>
6+
</nav>

tests/sites/sidebars/conf.py

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# -- Project information -----------------------------------------------------
2+
3+
project = "PyData Tests"
4+
copyright = "2020, Pydata community"
5+
author = "Pydata community"
6+
7+
master_doc = "index"
8+
9+
# -- General configuration ---------------------------------------------------
10+
11+
html_theme = "pydata_sphinx_theme"

tests/sites/sidebars/index.rst

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Sidebar depth variations
2+
========================
3+
4+
.. toctree::
5+
:caption: Caption 1
6+
7+
section1/index
8+
9+
10+
.. toctree::
11+
:caption: Caption 2
12+
13+
section2/index
14+
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Section 1 index
2+
===============
3+
4+
.. toctree::
5+
:caption: Section 1
6+
7+
subsection1/index
8+
page2
+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Section 1 page 1
2+
================
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Subsection 1.1 index
2+
====================
3+
4+
.. toctree::
5+
:caption: Subsection 1.1
6+
7+
page1
8+
page2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Section 1 sub 1 page 1
2+
======================
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Section 1 sub 1 page 2
2+
======================
+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Section 2 index
2+
===============
3+
4+
.. toctree::
5+
6+
page1
7+
https://google.com
+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Section 1 Page 1
2+
================

tests/test_build.py

+37
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,40 @@ def test_navbar_no_in_page_headers(sphinx_build_factory, file_regression):
154154
index_html = sphinx_build.html_tree("index.html")
155155
navbar = index_html.select("ul#navbar-main-elements")[0]
156156
file_regression.check(navbar.prettify(), extension=".html")
157+
158+
159+
def test_sidebars_captions(sphinx_build_factory, file_regression):
160+
sphinx_build = sphinx_build_factory("sidebars").build()
161+
162+
subindex_html = sphinx_build.html_tree("section1/index.html")
163+
164+
# Sidebar structure
165+
sidebar = subindex_html.select("nav#bd-docs-nav")[0]
166+
# TODO this should include the captions
167+
file_regression.check(sidebar.prettify(), extension=".html")
168+
169+
170+
def test_sidebars_single(sphinx_build_factory, file_regression):
171+
confoverrides = {"templates_path": ["_templates_single_sidebar"]}
172+
sphinx_build = sphinx_build_factory("sidebars", confoverrides=confoverrides).build()
173+
174+
index_html = sphinx_build.html_tree("index.html")
175+
176+
# No navbar included
177+
assert not index_html.select("nav#navbar-main")
178+
assert not index_html.select(".navbar-nav")
179+
180+
# Sidebar structure
181+
sidebar = index_html.select("nav#bd-docs-nav")[0]
182+
file_regression.check(sidebar.prettify(), extension=".html")
183+
184+
185+
def test_sidebars_level2(sphinx_build_factory, file_regression):
186+
confoverrides = {"templates_path": ["_templates_sidebar_level2"]}
187+
sphinx_build = sphinx_build_factory("sidebars", confoverrides=confoverrides).build()
188+
189+
subindex_html = sphinx_build.html_tree("section1/subsection1/index.html")
190+
191+
# Sidebar structure
192+
sidebar = subindex_html.select("nav#bd-docs-nav")[0]
193+
file_regression.check(sidebar.prettify(), extension=".html")

tests/test_build/sidebar_ix.html

-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
</form>
77
<nav aria-label="Main navigation" class="bd-links" id="bd-docs-nav">
88
<div class="bd-toc-item active">
9-
<ul class="nav bd-sidenav">
10-
</ul>
119
</div>
1210
</nav>
1311
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<nav aria-label="Main navigation" class="bd-links" id="bd-docs-nav">
2+
<div class="bd-toc-item active">
3+
<ul class="nav bd-sidenav">
4+
<li class="toctree-l2">
5+
<a class="reference internal" href="subsection1/index.html">
6+
Subsection 1.1 index
7+
</a>
8+
</li>
9+
<li class="toctree-l2">
10+
<a class="reference internal" href="page2.html">
11+
Section 1 page 1
12+
</a>
13+
</li>
14+
</ul>
15+
</div>
16+
</nav>
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<nav aria-label="Main navigation" class="bd-links" id="bd-docs-nav">
2+
<div class="bd-toc-item active">
3+
<!-- Use deeper level for sidebar -->
4+
<ul class="nav bd-sidenav">
5+
<li class="toctree-l3">
6+
<a class="reference internal" href="page1.html">
7+
Section 1 sub 1 page 1
8+
</a>
9+
</li>
10+
<li class="toctree-l3">
11+
<a class="reference internal" href="page2.html">
12+
Section 1 sub 1 page 2
13+
</a>
14+
</li>
15+
</ul>
16+
</div>
17+
</nav>
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<nav aria-label="Main navigation" class="bd-links" id="bd-docs-nav">
2+
<div class="bd-toc-item active">
3+
<!-- Specify a startdepth of 0 instead of default of 1 -->
4+
<p class="caption">
5+
<span class="caption-text">
6+
Caption 1
7+
</span>
8+
</p>
9+
<ul class="nav bd-sidenav">
10+
<li class="toctree-l1">
11+
<a class="reference internal" href="section1/index.html">
12+
Section 1 index
13+
</a>
14+
</li>
15+
</ul>
16+
<p class="caption">
17+
<span class="caption-text">
18+
Caption 2
19+
</span>
20+
</p>
21+
<ul class="nav bd-sidenav">
22+
<li class="toctree-l1">
23+
<a class="reference internal" href="section2/index.html">
24+
Section 2 index
25+
</a>
26+
</li>
27+
</ul>
28+
</div>
29+
</nav>

0 commit comments

Comments
 (0)