Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi-level navigation #462

Closed
wants to merge 15 commits into from
Closed
18 changes: 7 additions & 11 deletions _config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,13 @@
# you will see them accessed via {{ site.title }}, {{ site.github_repo }}, and so on.
# You can create any custom variable you would like, and they will be accessible
# in the templates via {{ site.myvariable }}.
title: Just the Docs
title: Just the Docs FORK rec-nav-2
description: A Jekyll theme for documentation
baseurl: "/just-the-docs" # the subpath of your site, e.g. /blog
url: "https://pmarsceill.github.io" # the base hostname & protocol for your site, e.g. http://example.com
url: "https://pdmosses.github.io" # the base hostname & protocol for your site, e.g. http://example.com

permalink: pretty
exclude: ["node_modules/", "*.gemspec", "*.gem", "Gemfile", "Gemfile.lock", "package.json", "package-lock.json", "script/", "LICENSE.txt", "lib/", "bin/", "README.md", "Rakefile"
, "docs/tests/"
]

# Regression tests
# By default, the pages in /docs/tests are excluded when the ste is built.
# To include them, comment-out the relevant line above.
# Uncommenting the following line doesn't work - see https://github.com/jekyll/jekyll/issues/4791
# include: ["docs/tests/"]
exclude: ["node_modules/", "*.gemspec", "*.gem", "Gemfile", "Gemfile.lock", "package.json", "package-lock.json", "script/", "LICENSE.txt", "lib/", "bin/", "README.md", "Rakefile"]

# Set a path/url to a logo that will be displayed instead of the title
#logo: "/assets/images/just-the-docs.png"
Expand Down Expand Up @@ -74,6 +66,9 @@ aux_links_new_tab: false
# nav_sort: case_insensitive # default, equivalent to nil
nav_sort: case_sensitive # Capital letters sorted before lowercase

# Caching navigation links
nav_cache: true # default, equivalent to nil

# Footer content
# appears at the bottom of every page's main content

Expand Down Expand Up @@ -107,6 +102,7 @@ ga_tracking_anonymize_ip: true # Use GDPR compliant Google Analytics settings (t

plugins:
- jekyll-seo-tag
- jekyll-include-cache

kramdown:
syntax_highlighter_opts:
Expand Down
5 changes: 5 additions & 0 deletions _config_dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# For local development and testing, use the option
# --config _config.yml,_config_dev.yml
# See https://stackoverflow.com/a/27400343

url: http://localhost:4000/
99 changes: 0 additions & 99 deletions _includes/nav.html

This file was deleted.

41 changes: 41 additions & 0 deletions _includes/nav/children.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{%- comment -%}
{%- include nav/children.html
node = node
path = string
in_section = value_or_nil -%}
assigns to `nav_children` an unsorted array containing children of `node`,
including `child` when all its specified disambiguation fields match:
- `child.grand_parent == node.parent`,
- `child.in_section == in_section`, and
- `path contains child.ancestor`.
{%- endcomment -%}

{%- assign nav_candidates = nav_parenthood
| where: "name", include.node.title | map: "items" | first -%}
{%- assign nav_children = "" | split: "X" -%}

{%- for child in nav_candidates -%}
{%- assign nav_child_ok = true -%}

{%- if child.grand_parent and child.grand_parent != include.node.parent -%}
{%- assign nav_child_ok = false -%}
{%- endif -%}

{%- if child.in_section and child.in_section != include.in_section -%}
{%- assign nav_child_ok = false -%}
{%- endif -%}

{%- capture nav_newline %}
{% endcapture -%}

{%- if child.ancestor -%}
{%- assign nav_child_ancestor_title = nav_newline | append: child.ancestor | append: nav_newline -%}
{%- unless include.path contains nav_child_ancestor_title -%}
{%- assign nav_child_ok = false -%}
{%- endunless -%}
{%- endif -%}

{%- if nav_child_ok -%}
{%- assign nav_children = nav_children | push: child -%}
{%- endif -%}
{%- endfor -%}
77 changes: 77 additions & 0 deletions _includes/nav/collection.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
{%- comment -%}
{%- include nav/collection.html
pages = array
key = name_or_nil -%}
outputs the main navigation links for `pages`. It also assigns arrays of pages
to variables inspected by `nav/crumbs` and `nav/toc`.

When `key` is `nil`, `pages` is `site.html_pages`; otherwise `key` is the name
of a collection, and `pages` are the pages of that collection. (Pages without
a `title` are automatically excluded in the former case, but Jekyll provides
default titles for pages in collections, so their untitled pages are not
automatically excluded.)

`collection` first groups `pages` by their `parent` fields, creating an
unsorted array of hashes, assigned to `nav_parenthood`.

When `pages` contains the current `page`, `collection` calls `nav/page` to
search for the navigation path to `page`, then:
- assigns to `nav_page_path` the string of page titles leading to `page`,
- assigns to `nav_page_ancestors` the array of ancestors of `page`, and
- assigns to `nav_page_children` the array of children of `page`.

When pages are stored in folders whose nesting corresponds to the parent
relation, only nodes whose folder path is a prefix of `page.path` need to be
searched. For larger sites, using folder paths to direct searching for `page`
can exponentially reduce the build time. To avoid dependence on assumptions
about the folders used to store pages, however, exhaustive search is needed
as a fall-back when directed search fails.

Finally, `collection` outputs the main navigation links for `pages`.

The presence of navigation expanders requires the navigation links for the
entire site to be output on every page. To reduce build time, the navigation
links for inactive top-level nodes are cached. (It would be possible to cache
also the navigation links for inactive lower-level nodes, but that does not
reduce the build time signficantly.)
{%- endcomment -%}

{%- assign nav_parenthood = include.pages
| where_exp: "item", "item.title != nil" | group_by: "parent" -%}

{%- assign nav_top_nodes = nav_parenthood
| where_exp: "item", "item.name == ''" | map: "items" | first -%}

{%- assign nav_page_path = nil -%}

{%- if include.key == nil or include.key == page.collection -%}

{%- assign nav_page_dir = page.path | split: "/" | pop | join: "/" -%}
{%- assign nav_ancestors = "" | split: "X" -%}

{%- capture nav_newline %}
{% endcapture -%}

{%- include nav/page.html
direct = true
nodes = nav_top_nodes
ancestors = nav_ancestors
path = nav_newline
in_section = nil -%}

{%- unless nav_page_path -%}
{%- include nav/page.html
direct = false
nodes = nav_top_nodes
ancestors = nav_ancestors
path = nav_newline
in_section = nil -%}
{%- endunless -%}

{%- endif -%}

{%- include nav/links.html
nodes = nav_top_nodes
path = nav_newline
in_section = nil
pages = include.pages -%}
19 changes: 19 additions & 0 deletions _includes/nav/crumbs.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{%- comment -%}
{%- include nav/crumbs.html
nodes = array -%}
outputs breadcrumb navigation links for the nodes, and the title of the
current page.
{%- endcomment -%}

<nav aria-label="Breadcrumb" class="breadcrumb-nav">
<ol class="breadcrumb-nav-list">
{%- for node in include.nodes -%}
<li class="breadcrumb-nav-list-item">
<a href="{{ node.url | absolute_url }}">{{ node.title }}</a>
</li>
{%- endfor -%}
<li class="breadcrumb-nav-list-item">
<span>{{ page.title }}</span>
</li>
</ol>
</nav>
47 changes: 47 additions & 0 deletions _includes/nav/links.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{%- comment -%}
{%- include nav/links.html
nodes = array
path = string
in_section = value_or_nil
pages = array -%}
outputs links for non-excluded nodes and their children. The links for an
inactive node are independent of the path to the current page, but only those
for top-level nodes are cached.
{%- endcomment -%}

{%- include nav/sorted.html
nodes = include.nodes -%}

<ul class="nav-list">
{%- for node in nav_sorted -%}
{%- unless node.nav_exclude == true -%}

{%- capture nav_newline %}
{% endcapture -%}

{%- assign nav_path = include.path | append: node.title | append: nav_newline -%}
{%- if nav_page_path contains nav_path -%}
{%- assign nav_active = true -%}
{%- else -%}
{%- assign nav_active = false -%}
{%- endif -%}

{%- if nav_active or site.nav_cache == false or node.parent -%}
{%- include nav/node.html
node = node
path = nav_path
in_section = include.in_section
pages = include.pages
active = nav_active -%}
{%- else -%}
{%- include_cached nav/node_inactive.html
node = node
path = nav_path
in_section = include.in_section
pages = include.pages
cached = true -%}
{%- endif -%}

{%- endunless -%}
{%- endfor -%}
</ul>
26 changes: 26 additions & 0 deletions _includes/nav/links_inactive.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{%- comment -%}
{%- include nav/links_inactive.html
nodes = array
path = string
in_section = value_or_nil
pages = array -%}
outputs links for inactive nodes and their children.
{%- endcomment -%}

{%- include nav/sorted.html
nodes = include.nodes -%}

<ul class="nav-list">
{%- for node in nav_sorted -%}
{%- unless node.nav_exclude == true -%}

{%- include nav/node_inactive.html
node = node
path = include.path
in_section = include.in_section
pages = include.pages
cached = false -%}

{%- endunless -%}
{%- endfor -%}
</ul>
Loading