From a251382b7a68acb4eff37774b31750550809cf1f Mon Sep 17 00:00:00 2001
From: Kevin Lin <hello@kevinl.info>
Date: Mon, 22 Apr 2024 15:07:29 -0700
Subject: [PATCH] Add `nav_enabled` variables for more customizable and
 feature-complete minimal layouts (#1441)

* Add nav_enabled variables for site/layout/page-level control

* _sass: Add a space around `+` operator

* assets: Do not compile based on site.nav_enabled

* _config.yml: nav_enabled can be selectively enabled

* CHANGELOG.md: Add nav_enabled feature and docs

* docs: Prefer em dash in describing minimal layout

* docs: Add section on Selectively hiding or showing the sidebar

* _layouts: Display sidebar based on variable importance

* docs: Update documentation on the minimal layout

* docs: Document site.nav_enabled configuration variable

---------

Co-authored-by: Matt Wang <matt@matthewwang.me>
---
 CHANGELOG.md               |  4 +--
 _config.yml                |  6 +++-
 _layouts/default.html      |  8 ++++-
 _layouts/minimal.html      | 34 ++-------------------
 _sass/layout.scss          | 60 +++++++++++++++++++++++---------------
 assets/js/just-the-docs.js |  8 +++--
 docs/configuration.md      |  8 +++++
 docs/customization.md      | 42 +++-----------------------
 docs/layout/layout.md      | 15 +++++++++-
 9 files changed, 85 insertions(+), 100 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9d3e8aa..93cba94 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,11 +17,11 @@ This website is built from the `HEAD` of the `main` branch of the theme reposito
 
 Code changes to `main` that are *not* in the latest release:
 
-- N/A
+- Added: `nav_enabled` site, layout, and page-level variable to selectively show or hide the side/mobile menu by [@kevinlin1] in [#1441]. The minimal layout was reimplemented using this feature, and now has support for the site-wide search bar and auxiliary links.
 
 Docs changes made since the latest release:
 
-- N/A
+- Docs: Explained the `nav_enabled` variables as an alternative to using the minimal layout [@kevinlin1] in [#1441].
 
 ## Release v0.8.2
 
diff --git a/_config.yml b/_config.yml
index 074cafc..a63240a 100644
--- a/_config.yml
+++ b/_config.yml
@@ -109,6 +109,10 @@ aux_links:
 # Makes Aux links open in a new tab. Default is false
 aux_links_new_tab: false
 
+# Enable or disable the side/mobile menu globally
+# Nav menu can also be selectively enabled or disabled using page variables or the minimal layout
+nav_enabled: true
+
 # Sort order for navigation links
 # nav_sort: case_insensitive # default, equivalent to nil
 nav_sort: case_sensitive # Capital letters sorted before lowercase
@@ -121,7 +125,7 @@ nav_external_links:
 liquid:
    error_mode: strict
    strict_filters: true
-   
+
 # Footer content
 # appears at the bottom of every page's main content
 
diff --git a/_layouts/default.html b/_layouts/default.html
index 923c1c1..4eaae58 100644
--- a/_layouts/default.html
+++ b/_layouts/default.html
@@ -9,7 +9,13 @@ layout: table_wrappers
 <body>
   <a class="skip-to-main" href="#main-content">Skip to main content</a>
   {% include icons/icons.html %}
-  {% include components/sidebar.html %}
+  {% if page.nav_enabled == true %}
+    {% include components/sidebar.html %}
+  {% elsif layout.nav_enabled == true and page.nav_enabled == nil %}
+    {% include components/sidebar.html %}
+  {% elsif site.nav_enabled != false and layout.nav_enabled == nil and page.nav_enabled == nil %}
+    {% include components/sidebar.html %}
+  {% endif %}
   <div class="main" id="top">
     {% include components/header.html %}
     <div class="main-content-wrap">
diff --git a/_layouts/minimal.html b/_layouts/minimal.html
index b12c5db..5863017 100644
--- a/_layouts/minimal.html
+++ b/_layouts/minimal.html
@@ -1,34 +1,6 @@
 ---
-layout: table_wrappers
+layout: default
+nav_enabled: false
 ---
 
-<!DOCTYPE html>
-
-<html lang="{{ site.lang | default: 'en-US' }}">
-{% include head.html %}
-<body>
-  <a class="skip-to-main" href="#main-content">Skip to main content</a>
-  {% include icons/icons.html %}
-  <div class="main-content-wrap" id="top">
-    {% include components/breadcrumbs.html %}
-    <div id="main-content" class="main-content" role="main">
-      {% if site.heading_anchors != false %}
-        {% include vendor/anchor_headings.html html=content beforeHeading="true" anchorBody="<svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><use xlink:href=\"#svg-link\"></use></svg>" anchorClass="anchor-heading" anchorAttrs="aria-labelledby=\"%html_id%\"" %}
-      {% else %}
-        {{ content }}
-      {% endif %}
-
-      {% if page.has_children == true and page.has_toc != false %}
-        {% include components/children_nav.html %}
-      {% endif %}
-
-      {% include components/footer.html %}
-
-    </div>
-  </div>
-
-  {% if site.mermaid %}
-    {% include components/mermaid.html %}
-  {% endif %}
-</body>
-</html>
+{{ content }}
diff --git a/_sass/layout.scss b/_sass/layout.scss
index 027b388..43ec5a5 100644
--- a/_sass/layout.scss
+++ b/_sass/layout.scss
@@ -19,23 +19,48 @@
     width: calc((100% - #{$nav-width + $content-width}) / 2 + #{$nav-width});
     min-width: $nav-width;
   }
+
+  & + .main {
+    @include mq(md) {
+      margin-left: $nav-width-md;
+    }
+
+    @include mq(lg) {
+      // stylelint-disable function-name-case
+      // disable for Max(), we want to use the CSS max() function
+      margin-left: Max(
+        #{$nav-width},
+        calc((100% - #{$nav-width + $content-width}) / 2 + #{$nav-width})
+      );
+      // stylelint-enable function-name-case
+    }
+
+    .main-header {
+      display: none;
+      background-color: $sidebar-color;
+
+      @include mq(md) {
+        display: flex;
+        background-color: $body-background-color;
+      }
+
+      &.nav-open {
+        display: block;
+
+        @include mq(md) {
+          display: flex;
+        }
+      }
+    }
+  }
 }
 
 .main {
+  margin: auto;
+
   @include mq(md) {
     position: relative;
     max-width: $content-width;
-    margin-left: $nav-width-md;
-  }
-
-  @include mq(lg) {
-    // stylelint-disable function-name-case
-    // disable for Max(), we want to use the CSS max() function
-    margin-left: Max(
-      #{$nav-width},
-      calc((100% - #{$nav-width + $content-width}) / 2 + #{$nav-width})
-    );
-    // stylelint-enable function-name-case
   }
 }
 
@@ -53,23 +78,12 @@
 
 .main-header {
   z-index: 0;
-  display: none;
-  background-color: $sidebar-color;
+  border-bottom: $border $border-color;
 
   @include mq(md) {
     display: flex;
     justify-content: space-between;
     height: $header-height;
-    background-color: $body-background-color;
-    border-bottom: $border $border-color;
-  }
-
-  &.nav-open {
-    display: block;
-
-    @include mq(md) {
-      display: flex;
-    }
   }
 }
 
diff --git a/assets/js/just-the-docs.js b/assets/js/just-the-docs.js
index 74164ef..d249b6d 100644
--- a/assets/js/just-the-docs.js
+++ b/assets/js/just-the-docs.js
@@ -556,12 +556,14 @@ function activateNav() {
 // Document ready
 
 jtd.onReady(function(){
-  initNav();
+  if (document.getElementById('site-nav')) {
+    initNav();
+    activateNav();
+    scrollNav();
+  }
   {%- if site.search_enabled != false %}
   initSearch();
   {%- endif %}
-  activateNav();
-  scrollNav();
 });
 
 // Copy button on code
diff --git a/docs/configuration.md b/docs/configuration.md
index 12d2fbd..fb352a3 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -101,6 +101,14 @@ aux_links:
 aux_links_new_tab: false
 ```
 
+## Navigation sidebar
+
+```yaml
+# Enable or disable the side/mobile menu globally
+# Nav menu can also be selectively enabled or disabled using page variables or the minimal layout
+nav_enabled: true
+```
+
 ## Heading anchor links
 
 ```yaml
diff --git a/docs/customization.md b/docs/customization.md
index 7c57b77..4939e18 100644
--- a/docs/customization.md
+++ b/docs/customization.md
@@ -329,43 +329,9 @@ Future versions may subdivide components further; we guarantee that we will only
 
 ### Alternative layouts and example (`minimal`)
 
-Users can develop custom layouts that compose, omit, or add components differently. We provide one first-class example titled `minimal`, inspired by Kevin Lin's work in [just-the-class](https://github.com/kevinlin1/just-the-class). This `minimal` layout does not render the sidebar, header, or search. To see an example, visit the [minimal layout test]({{site.baseurl}}/docs/minimal-test/) page.
+Users can develop custom layouts that compose, omit, or add components differently. We provide one first-class example titled `minimal`, which disables the navigation sidebar. To see an example, visit the [minimal layout test]({{site.baseurl}}/docs/minimal-test/) page.
 
-Here is a simplified code example of what it looks like:
-
-{% raw %}
-
-```liquid
-<!-- a simplified version of _layouts/minimal.html -->
-<html>
-{% include head.html %}
-<body>
-  {% include icons/icons.html %}
-  {% comment %} Bandaid fix for breadcrumbs here! {% endcomment %}
-  {% include components/breadcrumbs.html %}
-
-  {% if site.heading_anchors != false %}
-    {% include vendor/anchor_headings.html html=content ... %}
-  {% else %}
-    {{ content }}
-  {% endif %}
-
-  {% if page.has_children == true and page.has_toc != false %}
-    {% include components/children_nav.html %}
-  {% endif %}
-
-  {% include components/footer.html %}
-
-  {% if site.mermaid %}
-    {% include components/mermaid.html %}
-  {% endif %}
-</body>
-</html>
-```
-
-{% endraw %}
-
-This layout is packaged in Just the Docs. Users can indicate this alternative layout in page front matter:
+Users can indicate this alternative layout in page front matter:
 
 {% raw %}
 
@@ -384,10 +350,10 @@ Similarly, users and developers can create other alternative layouts using Just
 
 Under the hood,
 
-- `default` and `minimal` inherit from the `table_wrappers` layout, which wraps all HTML `<table>` tags with a `div .table-wrapper`
+- `default` inherit from the `table_wrappers` layout, which wraps all HTML `<table>` tags with a `div .table-wrapper`
 - `table_wrappers` inherits from `vendor/compress`, which is a local copy of Anatol Broder's [jekyll-compress-html](https://github.com/penibelst/jekyll-compress-html) Jekyll plugin
 
-Note that as of now, `minimal` and `default` have no inheritance relationship.
+The `minimal` layout inherits from the `default` but assigns `nav_enabled: false` to disable the navigation sidebar.
 
 ### Overridden default Jekyll layouts
 
diff --git a/docs/layout/layout.md b/docs/layout/layout.md
index 6bf3de9..832cbb1 100644
--- a/docs/layout/layout.md
+++ b/docs/layout/layout.md
@@ -28,7 +28,20 @@ Each page that has child pages generally has a list of links to those pages (you
 
 ## The `minimal` layout
 
-A child and grandchild page of this page use the minimal layout. This differs from the default layout by omitting the sidebar -- and thereby also the navigation panel. To navigate between pages with the minimal layout, you can use the breadcrumbs and the tables of contents.
+A child and grandchild page of this page use the minimal layout. This differs from the default layout by omitting the sidebar---and thereby also the navigation panel. To navigate between pages with the minimal layout, you can use the breadcrumbs and the tables of contents.
+
+## Selectively hiding or showing the sidebar
+
+[Jekyll's front matter defaults] can be used to apply the `minimal` layout for many pages. But there are also other variables that can control the page layout. In `_config.yml`, you can set `nav_enabled: false` to disable the sidebar navigation panel across the entire site. This can then be selectively enabled on a page-by-page basis by assigning the `nav_enabled: true` page [front matter] variable. For instance, this could be used to enable sidebar navigation on a home page while all other pages have sidebar navigation disabled.
+
+```yaml
+---
+layout: default
+title: Home
+nav_enabled: true
+---
+
+```
 
 ## Other layouts