diff --git a/pydata_sphinx_theme/__init__.py b/pydata_sphinx_theme/__init__.py index a210bc0eea..ba1cf1c30f 100644 --- a/pydata_sphinx_theme/__init__.py +++ b/pydata_sphinx_theme/__init__.py @@ -14,7 +14,7 @@ def add_toctree_functions(app, pagename, templatename, context, doctree): """Add functions so Jinja templates can add toctree objects.""" - def generate_nav_html(kind, **kwargs): + def generate_nav_html(kind, startdepth=None, **kwargs): """ Return the navigation link structure in HTML. Arguments are passed to Sphinx "toctree" function (context["toctree"] below). @@ -27,6 +27,10 @@ def generate_nav_html(kind, **kwargs): ---------- kind : ["navbar", "sidebar", "raw"] The kind of UI element this toctree is generated for. + startdepth : int + The level of the toctree at which to start. By default, for + the navbar uses the normal toctree (`startdepth=0`), and for + the sidebar starts from the second level (`startdepth=1`). kwargs: passed to the Sphinx `toctree` template function. Returns @@ -37,6 +41,22 @@ def generate_nav_html(kind, **kwargs): toc_sphinx = context["toctree"](**kwargs) soup = bs(toc_sphinx, "html.parser") + if startdepth is None: + startdepth = 1 if kind == "sidebar" else 0 + + # select the "active" subset of the navigation tree for the sidebar + if startdepth > 0: + selector = " ".join( + [ + "li.current.toctree-l{} ul".format(i) + for i in range(1, startdepth + 1) + ] + ) + subset = soup.select(selector) + if not subset: + return "" + soup = bs(str(subset[0]), "html.parser") + # pair "current" with "active" since that's what we use w/ bootstrap for li in soup("li", {"class": "current"}): li["class"].append("active") @@ -54,13 +74,15 @@ def generate_nav_html(kind, **kwargs): for li in soup("li"): li["class"].append("nav-item") li.find("a")["class"].append("nav-link") + # only select li items (not eg captions) out = "\n".join([ii.prettify() for ii in soup.find_all("li")]) elif kind == "sidebar": + # Add bootstrap classes for first `ul` items + for ul in soup("ul", recursive=False): + ul.attrs["class"] = ul.attrs.get("class", []) + ["nav", "bd-sidenav"] - # Join all the top-level `li`s together for display - current_lis = soup.select("li.current.toctree-l1 li.toctree-l2") - out = "\n".join([ii.prettify() for ii in current_lis]) + out = soup.prettify() elif kind == "raw": out = soup diff --git a/pydata_sphinx_theme/_templates/sidebar-nav-bs.html b/pydata_sphinx_theme/_templates/sidebar-nav-bs.html index 30a83aa1f7..c248dbab26 100644 --- a/pydata_sphinx_theme/_templates/sidebar-nav-bs.html +++ b/pydata_sphinx_theme/_templates/sidebar-nav-bs.html @@ -1,7 +1,5 @@ diff --git a/tests/sites/sidebars/_templates_sidebar_level2/sidebar-nav-bs.html b/tests/sites/sidebars/_templates_sidebar_level2/sidebar-nav-bs.html new file mode 100644 index 0000000000..ca66734360 --- /dev/null +++ b/tests/sites/sidebars/_templates_sidebar_level2/sidebar-nav-bs.html @@ -0,0 +1,10 @@ + diff --git a/tests/sites/sidebars/_templates_single_sidebar/layout.html b/tests/sites/sidebars/_templates_single_sidebar/layout.html new file mode 100644 index 0000000000..a9d0f30bcf --- /dev/null +++ b/tests/sites/sidebars/_templates_single_sidebar/layout.html @@ -0,0 +1,5 @@ +{% extends "pydata_sphinx_theme/layout.html" %} + +{# Silence the navbar #} +{% block docs_navbar %} +{% endblock %} diff --git a/tests/sites/sidebars/_templates_single_sidebar/sidebar-nav-bs.html b/tests/sites/sidebars/_templates_single_sidebar/sidebar-nav-bs.html new file mode 100644 index 0000000000..597d57772a --- /dev/null +++ b/tests/sites/sidebars/_templates_single_sidebar/sidebar-nav-bs.html @@ -0,0 +1,6 @@ + diff --git a/tests/sites/sidebars/conf.py b/tests/sites/sidebars/conf.py new file mode 100644 index 0000000000..64dbb56f23 --- /dev/null +++ b/tests/sites/sidebars/conf.py @@ -0,0 +1,11 @@ +# -- Project information ----------------------------------------------------- + +project = "PyData Tests" +copyright = "2020, Pydata community" +author = "Pydata community" + +master_doc = "index" + +# -- General configuration --------------------------------------------------- + +html_theme = "pydata_sphinx_theme" diff --git a/tests/sites/sidebars/index.rst b/tests/sites/sidebars/index.rst new file mode 100644 index 0000000000..eb942bdb2a --- /dev/null +++ b/tests/sites/sidebars/index.rst @@ -0,0 +1,14 @@ +Sidebar depth variations +======================== + +.. toctree:: + :caption: Caption 1 + + section1/index + + +.. toctree:: + :caption: Caption 2 + + section2/index + diff --git a/tests/sites/sidebars/section1/index.rst b/tests/sites/sidebars/section1/index.rst new file mode 100644 index 0000000000..9c9eeb89d7 --- /dev/null +++ b/tests/sites/sidebars/section1/index.rst @@ -0,0 +1,8 @@ +Section 1 index +=============== + +.. toctree:: + :caption: Section 1 + + subsection1/index + page2 diff --git a/tests/sites/sidebars/section1/page2.rst b/tests/sites/sidebars/section1/page2.rst new file mode 100644 index 0000000000..c6ae536225 --- /dev/null +++ b/tests/sites/sidebars/section1/page2.rst @@ -0,0 +1,2 @@ +Section 1 page 1 +================ diff --git a/tests/sites/sidebars/section1/subsection1/index.rst b/tests/sites/sidebars/section1/subsection1/index.rst new file mode 100644 index 0000000000..29dad001c4 --- /dev/null +++ b/tests/sites/sidebars/section1/subsection1/index.rst @@ -0,0 +1,8 @@ +Subsection 1.1 index +==================== + +.. toctree:: + :caption: Subsection 1.1 + + page1 + page2 diff --git a/tests/sites/sidebars/section1/subsection1/page1.rst b/tests/sites/sidebars/section1/subsection1/page1.rst new file mode 100644 index 0000000000..83421f23c2 --- /dev/null +++ b/tests/sites/sidebars/section1/subsection1/page1.rst @@ -0,0 +1,2 @@ +Section 1 sub 1 page 1 +====================== diff --git a/tests/sites/sidebars/section1/subsection1/page2.rst b/tests/sites/sidebars/section1/subsection1/page2.rst new file mode 100644 index 0000000000..c229b0796d --- /dev/null +++ b/tests/sites/sidebars/section1/subsection1/page2.rst @@ -0,0 +1,2 @@ +Section 1 sub 1 page 2 +====================== diff --git a/tests/sites/sidebars/section2/index.rst b/tests/sites/sidebars/section2/index.rst new file mode 100644 index 0000000000..81674a2619 --- /dev/null +++ b/tests/sites/sidebars/section2/index.rst @@ -0,0 +1,7 @@ +Section 2 index +=============== + +.. toctree:: + + page1 + https://google.com \ No newline at end of file diff --git a/tests/sites/sidebars/section2/page1.rst b/tests/sites/sidebars/section2/page1.rst new file mode 100644 index 0000000000..818ef8aa63 --- /dev/null +++ b/tests/sites/sidebars/section2/page1.rst @@ -0,0 +1,2 @@ +Section 1 Page 1 +================ diff --git a/tests/test_build.py b/tests/test_build.py index e6a4bea7dc..be461fa814 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -154,3 +154,40 @@ def test_navbar_no_in_page_headers(sphinx_build_factory, file_regression): index_html = sphinx_build.html_tree("index.html") navbar = index_html.select("ul#navbar-main-elements")[0] file_regression.check(navbar.prettify(), extension=".html") + + +def test_sidebars_captions(sphinx_build_factory, file_regression): + sphinx_build = sphinx_build_factory("sidebars").build() + + subindex_html = sphinx_build.html_tree("section1/index.html") + + # Sidebar structure + sidebar = subindex_html.select("nav#bd-docs-nav")[0] + # TODO this should include the captions + file_regression.check(sidebar.prettify(), extension=".html") + + +def test_sidebars_single(sphinx_build_factory, file_regression): + confoverrides = {"templates_path": ["_templates_single_sidebar"]} + sphinx_build = sphinx_build_factory("sidebars", confoverrides=confoverrides).build() + + index_html = sphinx_build.html_tree("index.html") + + # No navbar included + assert not index_html.select("nav#navbar-main") + assert not index_html.select(".navbar-nav") + + # Sidebar structure + sidebar = index_html.select("nav#bd-docs-nav")[0] + file_regression.check(sidebar.prettify(), extension=".html") + + +def test_sidebars_level2(sphinx_build_factory, file_regression): + confoverrides = {"templates_path": ["_templates_sidebar_level2"]} + sphinx_build = sphinx_build_factory("sidebars", confoverrides=confoverrides).build() + + subindex_html = sphinx_build.html_tree("section1/subsection1/index.html") + + # Sidebar structure + sidebar = subindex_html.select("nav#bd-docs-nav")[0] + file_regression.check(sidebar.prettify(), extension=".html") diff --git a/tests/test_build/sidebar_ix.html b/tests/test_build/sidebar_ix.html index 255f787f4b..f330b6000c 100644 --- a/tests/test_build/sidebar_ix.html +++ b/tests/test_build/sidebar_ix.html @@ -6,8 +6,6 @@ diff --git a/tests/test_build/test_sidebars_captions.html b/tests/test_build/test_sidebars_captions.html new file mode 100644 index 0000000000..62ac272299 --- /dev/null +++ b/tests/test_build/test_sidebars_captions.html @@ -0,0 +1,16 @@ + diff --git a/tests/test_build/test_sidebars_level2.html b/tests/test_build/test_sidebars_level2.html new file mode 100644 index 0000000000..d098d37922 --- /dev/null +++ b/tests/test_build/test_sidebars_level2.html @@ -0,0 +1,17 @@ + diff --git a/tests/test_build/test_sidebars_single.html b/tests/test_build/test_sidebars_single.html new file mode 100644 index 0000000000..ce63c3b328 --- /dev/null +++ b/tests/test_build/test_sidebars_single.html @@ -0,0 +1,29 @@ +