From def7c7291d82a1e771c8dc526cb55074c91eacec Mon Sep 17 00:00:00 2001 From: Chris Holdgraf Date: Wed, 15 Feb 2023 22:39:45 +0100 Subject: [PATCH] Standardize template structure in more sections (#1184) * Standardize template structure in all sections * Fixing footer behavior * Update docs/user_guide/layout.rst Co-authored-by: Daniel McCloy * Remove use of id= as much as possible --------- Co-authored-by: Daniel McCloy --- docs/_templates/test.html | 2 + docs/conf.py | 2 +- docs/user_guide/layout.rst | 40 ++++++++++++++--- docs/user_guide/search.rst | 3 +- docs/user_guide/version-dropdown.rst | 4 +- src/pydata_sphinx_theme/__init__.py | 10 ++++- .../assets/scripts/pydata-sphinx-theme.js | 10 ++--- .../assets/styles/components/_icon-links.scss | 44 +++++++++---------- .../assets/styles/components/_page-toc.scss | 27 ++++++++++++ .../assets/styles/components/_searchbox.scss | 2 - .../assets/styles/pydata-sphinx-theme.scss | 1 + .../assets/styles/sections/_footer.scss | 23 +++++++++- .../styles/sections/_header-article.scss | 7 ++- .../assets/styles/sections/_header.scss | 22 +++++----- .../styles/sections/_sidebar-primary.scss | 12 ++--- .../styles/sections/_sidebar-secondary.scss | 33 ++------------ .../components/footer-article/prev-next.html | 2 - .../components/icon-links.html | 3 +- .../components/navbar-nav.html | 2 +- .../components/page-toc.html | 4 +- .../components/sidebar-nav-bs.html | 3 +- .../theme/pydata_sphinx_theme/layout.html | 5 ++- .../sections/announcement.html | 6 +-- .../pydata_sphinx_theme/sections/footer.html | 21 +++++++-- .../sections/header-article.html | 6 ++- .../pydata_sphinx_theme/sections/header.html | 22 +++++++--- .../sections/sidebar-primary.html | 14 +++--- .../sections/sidebar-secondary.html | 6 ++- .../theme/pydata_sphinx_theme/theme.conf | 21 ++++++--- .../sidebar-nav-bs.html | 2 +- .../components/sidebar-nav-bs.html | 2 +- tests/test_build.py | 27 +++++++----- tests/test_build/navbar_icon_links.html | 2 +- tests/test_build/navbar_ix.html | 6 +-- tests/test_build/sidebar_subpage.html | 18 ++++---- .../test_navbar_no_in_page_headers.html | 2 +- tests/test_build/test_sidebars_captions.html | 2 +- tests/test_build/test_sidebars_level2.html | 2 +- .../test_build/test_sidebars_nested_page.html | 2 +- 39 files changed, 258 insertions(+), 164 deletions(-) create mode 100644 docs/_templates/test.html create mode 100644 src/pydata_sphinx_theme/assets/styles/components/_page-toc.scss diff --git a/docs/_templates/test.html b/docs/_templates/test.html new file mode 100644 index 000000000..341b0d292 --- /dev/null +++ b/docs/_templates/test.html @@ -0,0 +1,2 @@ +{# This is just used for testing in our documentation #} + diff --git a/docs/conf.py b/docs/conf.py index 398fa920a..b24121fa4 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -138,7 +138,7 @@ # "navbar_end": ["theme-switcher", "navbar-icon-links"], # "navbar_persistent": ["search-button"], # "primary_sidebar_end": ["custom-template.html", "sidebar-ethical-ads.html"], - # "footer_items": ["copyright", "sphinx-version"], + # "footer_start": ["test.html", "test.html"], # "secondary_sidebar_items": ["page-toc.html"], # Remove the source buttons "switcher": { "json_url": json_url, diff --git a/docs/user_guide/layout.rst b/docs/user_guide/layout.rst index cde41b4b9..1b5d67e42 100644 --- a/docs/user_guide/layout.rst +++ b/docs/user_guide/layout.rst @@ -10,7 +10,8 @@ Overview of theme layout Below is a brief overview of the major layout of this theme. Take a look at the diagram to understand what the major sections are called. -You can click on section titles to learn more about them and some basic layout configuration. +Where you can insert component templates in ``html_theme_options``, we include the variable name ``in inline code``. +Click on section titles to learn more about them and some basic layout configuration. .. The directives below generate a grid-like layout that mimics the structure of this theme. .. It uses Sphinx Design grids: https://sphinx-design.readthedocs.io/en/latest/grids.html @@ -52,18 +53,24 @@ You can click on section titles to learn more about them and some basic layout c Logo + ``navbar_start`` + .. grid-item:: :padding: 2 :columns: 6 Section links + ``navbar_center`` + .. grid-item:: :padding: 2 :columns: 3 Components + ``navbar_end`` + .. grid-item:: :padding: 2 :outline: @@ -78,6 +85,10 @@ You can click on section titles to learn more about them and some basic layout c Links between pages in the active section. + ``sidebars`` + + ``primary_sidebar_end`` + .. grid-item:: :columns: 8 @@ -88,7 +99,7 @@ You can click on section titles to learn more about them and some basic layout c .. grid-item:: :class: content :padding: 2 - :columns: 8 + :columns: 6 :outline: .. button-ref:: layout-article-header @@ -97,6 +108,9 @@ You can click on section titles to learn more about them and some basic layout c Article Header + ``article_header_start`` + ``article_header_end`` + **Article Content** .. button-ref:: layout-article-footer @@ -107,7 +121,7 @@ You can click on section titles to learn more about them and some basic layout c .. grid-item:: :padding: 2 - :columns: 4 + :columns: 6 :outline: :class: sidebar-secondary @@ -119,6 +133,8 @@ You can click on section titles to learn more about them and some basic layout c Within-page header links + ``secondary_sidebar_items`` + .. grid:: :margin: 0 :gutter: 0 @@ -149,7 +165,8 @@ You can click on section titles to learn more about them and some basic layout c Footer - Site-wide links. + ``footer_start`` + ``footer_end`` Horizontal spacing ------------------ @@ -425,18 +442,27 @@ Footer Located in ``sections/footer.html``. The footer is just below a page’s main content, and is configured in ``conf.py`` -with ``html_theme_options['footer_items']``. +with ``html_theme_options['footer_start']`` and ``html_theme_options['footer_end']``. -By default, it has the following templates: +By default, ``footer_end`` is empty, and ``footer_start`` has the following templates: .. code-block:: python html_theme_options = { ... - "footer_items": ["copyright", "sphinx-version", "theme-version"], + "footer_start": ["copyright", "sphinx-version", "theme-version"], ... } +Within each subsection, components will stack **vertically**. +If you'd like them to stack **horizontally** use a custom CSS rule like the following: + +.. code-block:: css + + .footer-items__start, .footer-items__end { + flex-direction: row; + } + Change footer display --------------------- diff --git a/docs/user_guide/search.rst b/docs/user_guide/search.rst index d603340d9..9a0faf13c 100644 --- a/docs/user_guide/search.rst +++ b/docs/user_guide/search.rst @@ -14,7 +14,8 @@ You can also configure some aspects of the search button and search field, descr Configure the search field position ----------------------------------- -The position of the search *button* is controlled by ``search-button`` and by default is included in ``html_theme_options["navbar_persistent"]``; you may move it elsewhere as befits your site's layout, or remove it. You can also add an always-visible search field to some/all pages in your site by adding ``search-field.html`` to one of the configuration variables (e.g., ``html_sidebars``, ``html_theme_options["footer_items"]``, etc). +The position of the search *button* is controlled by ``search-button`` and by default is included in ``html_theme_options["navbar_persistent"]``; you may move it elsewhere as befits your site's layout, or remove it. +You can also add an always-visible search field to some/all pages in your site by adding ``search-field.html`` to one of the configuration variables (e.g., ``html_sidebars``, ``html_theme_options["footer_start"]``, etc). For example, if you'd like the search field to be in your side-bar, add it to the sidebar templates like so: diff --git a/docs/user_guide/version-dropdown.rst b/docs/user_guide/version-dropdown.rst index eb7227e5b..305949b7c 100644 --- a/docs/user_guide/version-dropdown.rst +++ b/docs/user_guide/version-dropdown.rst @@ -23,7 +23,7 @@ The switcher requires the following configuration steps: 3. Specify where to place the switcher in your page layout. For example, add the ``"version-switcher"`` template to one of the layout lists in - ``html_theme_options`` (e.g., ``navbar_end``, ``footer_items``, etc). + ``html_theme_options`` (e.g., ``navbar_end``, ``footer_start``, etc). Below is a more in-depth description of each of these configuration steps. @@ -156,7 +156,7 @@ Specify where to display the switcher Finally, tell the theme where on your site's pages you want the switcher to appear. There are many choices here: you can add ``"version-switcher"`` to one of the locations in ``html_theme_options`` (e.g., ``navbar_end``, -``footer_items``, etc). For example: +``footer_start``, etc). For example: .. code:: python diff --git a/src/pydata_sphinx_theme/__init__.py b/src/pydata_sphinx_theme/__init__.py index 48641d8be..073120a56 100644 --- a/src/pydata_sphinx_theme/__init__.py +++ b/src/pydata_sphinx_theme/__init__.py @@ -67,6 +67,13 @@ def update_config(app): "Use `secondary_sidebar_items`." ) + # DEPRECATE after 0.14 + if theme_options.get("footer_items"): + theme_options["footer_start"] = theme_options.get("footer_items") + logger.warning( + "`footer_items` is deprecated. Use `footer_start` or `footer_end` instead." + ) + # Validate icon links if not isinstance(theme_options.get("icon_links", []), list): raise ExtensionError( @@ -205,7 +212,8 @@ def update_and_remove_templates(app, pagename, templatename, context, doctree): "theme_navbar_end", "theme_article_header_start", "theme_article_header_end", - "theme_footer_items", + "theme_footer_start", + "theme_footer_end", "theme_secondary_sidebar_items", "theme_primary_sidebar_end", "sidebars", diff --git a/src/pydata_sphinx_theme/assets/scripts/pydata-sphinx-theme.js b/src/pydata_sphinx_theme/assets/scripts/pydata-sphinx-theme.js index 9ba3fe53a..d297ceb14 100644 --- a/src/pydata_sphinx_theme/assets/scripts/pydata-sphinx-theme.js +++ b/src/pydata_sphinx_theme/assets/scripts/pydata-sphinx-theme.js @@ -100,13 +100,13 @@ function addModeListener() { */ function addTOCInteractivity() { window.addEventListener("activate.bs.scrollspy", function () { - const navLinks = document.querySelectorAll("#bd-toc-nav a"); + const navLinks = document.querySelectorAll(".bd-toc-nav a"); navLinks.forEach((navLink) => { navLink.parentElement.classList.remove("active"); }); - const activeNavLinks = document.querySelectorAll("#bd-toc-nav a.active"); + const activeNavLinks = document.querySelectorAll(".bd-toc-nav a.active"); activeNavLinks.forEach((navLink) => { navLink.parentElement.classList.add("active"); }); @@ -122,7 +122,7 @@ function addTOCInteractivity() { */ function scrollToActive() { // If the docs nav doesn't exist, do nothing (e.g., on search page) - if (!document.getElementById("bd-docs-nav")) { + if (!document.querySelector(".bd-docs-nav")) { return; } @@ -141,7 +141,7 @@ function scrollToActive() { console.log("[PST]: Scrolled sidebar using stored browser position..."); } else { // Otherwise, calculate a position to scroll to based on the lowest `active` link - var sidebarNav = document.getElementById("bd-docs-nav"); + var sidebarNav = document.querySelector(".bd-docs-nav"); var active_pages = sidebarNav.querySelectorAll(".active"); if (active_pages.length > 0) { // Use the last active page as the offset since it's the page we're on @@ -305,7 +305,7 @@ function checkPageExistsAndRedirect(event) { } // Populate the version switcher from the JSON config file -var themeSwitchBtns = document.querySelectorAll("version-switcher__button"); +var themeSwitchBtns = document.querySelectorAll(".version-switcher__button"); if (themeSwitchBtns.length) { fetch(DOCUMENTATION_OPTIONS.theme_switcher_json_url) .then((res) => { diff --git a/src/pydata_sphinx_theme/assets/styles/components/_icon-links.scss b/src/pydata_sphinx_theme/assets/styles/components/_icon-links.scss index 16a102f9c..321bb8b0f 100644 --- a/src/pydata_sphinx_theme/assets/styles/components/_icon-links.scss +++ b/src/pydata_sphinx_theme/assets/styles/components/_icon-links.scss @@ -2,7 +2,25 @@ * Icon links in the navbar */ -#navbar-icon-links { +.navbar-icon-links { + display: flex; + flex-direction: row; + column-gap: 1rem; + flex-wrap: wrap; + + // Remove the padding so that we can define it with flexbox gap above + li.nav-item a.nav-link { + padding-left: 0; + padding-right: 0; + } + + // Spacing and centering + a span { + display: flex; + align-items: center; + } + + // Icons styling i { &.fa-brands, &.fa-regular, @@ -12,7 +30,7 @@ font-size: var(--pst-font-size-icon); } - /* Social media buttons */ + /* Social media buttons hard-code the brand color */ &.fa-square-twitter:before { color: #55acee; } @@ -26,29 +44,9 @@ } } + // Force images to be icon-sized img.icon-link-image { height: 1.5em; border-radius: 0.2rem; } - - li:first-child a { - padding-left: 0; - } - - a span { - display: flex; - align-items: center; - } - - // inline the element in the navbar as long as they fit and use display block when collapsing - // One breakpoint less than $breakpoint-sidebar-primary. - // See variables/_layout.scss for more info. - @include media-breakpoint-down(lg) { - flex-direction: row; - - // Use Bootstrap padding for these nav links to get the spacing right - a { - padding: 0rem 0.5rem; - } - } } diff --git a/src/pydata_sphinx_theme/assets/styles/components/_page-toc.scss b/src/pydata_sphinx_theme/assets/styles/components/_page-toc.scss new file mode 100644 index 000000000..4171cd012 --- /dev/null +++ b/src/pydata_sphinx_theme/assets/styles/components/_page-toc.scss @@ -0,0 +1,27 @@ +/** + * The list of in-page TOC links + */ +.page-toc { + .section-nav { + padding-left: 0; + border-bottom: none; + + ul { + padding-left: 1rem; + } + } + + // override bootstrap settings + .nav-link { + font-size: var(--pst-sidebar-font-size-mobile); + @include media-breakpoint-up($breakpoint-sidebar-secondary) { + font-size: var(--pst-sidebar-font-size); + } + } + + .onthispage { + color: var(--pst-color-text-base); + font-weight: var(--pst-sidebar-header-font-weight); + margin-bottom: 0.5rem; + } +} diff --git a/src/pydata_sphinx_theme/assets/styles/components/_searchbox.scss b/src/pydata_sphinx_theme/assets/styles/components/_searchbox.scss index fd8aa8223..f213bdbac 100644 --- a/src/pydata_sphinx_theme/assets/styles/components/_searchbox.scss +++ b/src/pydata_sphinx_theme/assets/styles/components/_searchbox.scss @@ -36,8 +36,6 @@ div#searchbox { text-decoration: none; } - // add icon via CSS because the link is created by javascript - // match padding to .toc-item > i above &:before { content: var(--pst-icon-search-minus); color: unset; diff --git a/src/pydata_sphinx_theme/assets/styles/pydata-sphinx-theme.scss b/src/pydata_sphinx_theme/assets/styles/pydata-sphinx-theme.scss index c8e8b94d4..1b196e390 100644 --- a/src/pydata_sphinx_theme/assets/styles/pydata-sphinx-theme.scss +++ b/src/pydata_sphinx_theme/assets/styles/pydata-sphinx-theme.scss @@ -36,6 +36,7 @@ @import "./components/icon-links"; @import "./components/header/header-logo"; @import "./components/navbar-links"; +@import "./components/page-toc"; @import "./components/prev-next"; @import "./components/search"; @import "./components/searchbox"; diff --git a/src/pydata_sphinx_theme/assets/styles/sections/_footer.scss b/src/pydata_sphinx_theme/assets/styles/sections/_footer.scss index 37b732fb7..34169f3a2 100644 --- a/src/pydata_sphinx_theme/assets/styles/sections/_footer.scss +++ b/src/pydata_sphinx_theme/assets/styles/sections/_footer.scss @@ -1,8 +1,27 @@ -footer.bd-footer { +.bd-footer { width: 100%; border-top: 1px solid var(--pst-color-border); - padding: 10px; + .bd-footer__inner { + display: flex; + flex-grow: 1; + padding: 1rem; + margin: auto; + } + + .footer-items__start, + .footer-items__end { + display: flex; + flex-direction: column; + gap: 0.5rem; + justify-content: center; + } + + .footer-items__end { + margin-left: auto; + } + + // So that paragraphs don't take up extra room .footer-item p { margin-bottom: 0; } diff --git a/src/pydata_sphinx_theme/assets/styles/sections/_header-article.scss b/src/pydata_sphinx_theme/assets/styles/sections/_header-article.scss index de9dd8e50..8c1855831 100644 --- a/src/pydata_sphinx_theme/assets/styles/sections/_header-article.scss +++ b/src/pydata_sphinx_theme/assets/styles/sections/_header-article.scss @@ -1,8 +1,13 @@ .header-article__inner { - min-height: var(--pst-header-article-height); display: flex; padding: 0 0.5rem; + // The items define the height so that it disappears if there are no items + .header-article-item { + min-height: var(--pst-header-article-height); + height: var(--pst-header-article-height); + } + .header-article-items__start, .header-article-items__end { display: flex; diff --git a/src/pydata_sphinx_theme/assets/styles/sections/_header.scss b/src/pydata_sphinx_theme/assets/styles/sections/_header.scss index 98b6f8b51..b53931c6c 100644 --- a/src/pydata_sphinx_theme/assets/styles/sections/_header.scss +++ b/src/pydata_sphinx_theme/assets/styles/sections/_header.scss @@ -36,9 +36,7 @@ } // These items will define the height of the header - .navbar-start-item, - .navbar-center-item, - .navbar-end-item { + .navbar-item { height: var(--pst-header-height); max-height: var(--pst-header-height); display: flex; @@ -46,9 +44,9 @@ } } - #navbar-end, - #navbar-center, - #navbar-start { + .navbar-header-items__end, + .navbar-header-items__center, + .navbar-header-items__start { display: flex; align-items: center; flex-flow: wrap; @@ -56,19 +54,19 @@ row-gap: 0; } - #navbar-end, - #navbar-center { + .navbar-header-items__end, + .navbar-header-items__center { column-gap: 1rem; } // A little smaller because this is displayed by default on mobile - #navbar-start { + .navbar-header-items__start { flex-shrink: 0; margin-right: auto; gap: 0.5rem; } - #navbar-end { + .navbar-header-items__end { // End navbar items should snap to the right justify-content: end; } @@ -126,7 +124,7 @@ // inline the element in the navbar as long as they fit and use display block when collapsing @include media-breakpoint-up($breakpoint-sidebar-primary) { - .navbar-center-item { + .navbar-center-items .navbar-item { display: inline-block; } } @@ -152,7 +150,7 @@ } } -#navbar-main-elements li.nav-item i { +.bd-navbar-elements li.nav-item i { font-size: 0.7rem; padding-left: 2px; vertical-align: middle; diff --git a/src/pydata_sphinx_theme/assets/styles/sections/_sidebar-primary.scss b/src/pydata_sphinx_theme/assets/styles/sections/_sidebar-primary.scss index e39e77492..cd7c10ca4 100644 --- a/src/pydata_sphinx_theme/assets/styles/sections/_sidebar-primary.scss +++ b/src/pydata_sphinx_theme/assets/styles/sections/_sidebar-primary.scss @@ -47,9 +47,11 @@ color: var(--pst-color-text-base); } - .sidebar-start-items__item, - .sidebar-end-items__item { - padding: 0.5rem 0; + .sidebar-primary-items__start, + .sidebar-primary-items__end { + .sidebar-primary-item { + padding: 0.5rem 0; + } } // Hide the sidebar header items on widescreen since they are visible in the header @@ -100,7 +102,7 @@ } } - .sidebar-start-items { + .sidebar-primary-items__start { // Add a border on mobile to separate it from the header sidebar area border-top: 1px solid var(--pst-color-border); @include media-breakpoint-up($breakpoint-sidebar-primary) { @@ -108,7 +110,7 @@ } } - .sidebar-end-items { + .sidebar-primary-items__end { margin-top: auto; margin-bottom: 1em; } diff --git a/src/pydata_sphinx_theme/assets/styles/sections/_sidebar-secondary.scss b/src/pydata_sphinx_theme/assets/styles/sections/_sidebar-secondary.scss index 5b1333dc5..2a867d28f 100644 --- a/src/pydata_sphinx_theme/assets/styles/sections/_sidebar-secondary.scss +++ b/src/pydata_sphinx_theme/assets/styles/sections/_sidebar-secondary.scss @@ -10,38 +10,21 @@ position: sticky; top: var(--pst-header-height); max-height: calc(100vh - var(--pst-header-height)); - + padding: 2rem 1rem 1rem 1rem; + width: var(--pst-sidebar-secondary); font-size: var(--pst-sidebar-font-size-mobile); @include media-breakpoint-up($breakpoint-sidebar-secondary) { font-size: var(--pst-sidebar-font-size); } - // override bootstrap settings - .nav-link { - font-size: var(--pst-sidebar-font-size-mobile); - @include media-breakpoint-up($breakpoint-sidebar-secondary) { - font-size: var(--pst-sidebar-font-size); - } - } - - padding: 2rem 1rem 1rem 1rem; - width: var(--pst-sidebar-secondary); - // Color and border background-color: var(--pst-color-background); overflow-y: auto; - .onthispage { - color: var(--pst-color-text-base); - font-weight: var(--pst-sidebar-header-font-weight); - margin-bottom: 0.5rem; - } - @include scrollbar-style(); } -// Each TOC item is wrapped in this -.toc-item { +.sidebar-secondary-item { padding: 0.5rem 0.5rem; @include media-breakpoint-up($breakpoint-sidebar-secondary) { border-left: 1px solid var(--pst-color-border); @@ -52,13 +35,3 @@ padding-right: 0.5rem; } } - -// The list of in-page TOC -.section-nav { - padding-left: 0; - border-bottom: none; - - ul { - padding-left: 1rem; - } -} diff --git a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/components/footer-article/prev-next.html b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/components/footer-article/prev-next.html index 0c7e55b0d..5befca1bd 100644 --- a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/components/footer-article/prev-next.html +++ b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/components/footer-article/prev-next.html @@ -2,7 +2,6 @@
{%- if prev %} @@ -14,7 +13,6 @@ {%- endif %} {%- if next %}
diff --git a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/components/icon-links.html b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/components/icon-links.html index d6eff326d..35ec1cc62 100644 --- a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/components/icon-links.html +++ b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/components/icon-links.html @@ -25,8 +25,7 @@ {%- endif -%} {%- endmacro -%} -