One thing I’m quite lazy about is wanting to update navigation. There are several approaches I’ve taken in
the past to handle this, the most labor intensive being maintaining several (possibly related) navigation
menus via YAML files or directly in Jekyll’s _config.yaml
. For individual files that aren’t posts
or part of a logic collection, this often means manually defining the permalink:
attribute, which can
also get tiring.
When I designed Docsy Jekyll (and note that by “design” I mean write the logic for the Jekyll site, the design itself is done by the authors
of the original Docsy) I did an intermediate approach -
I had a few upper levels of links “hard coded” in the sidebar (via YAML) and then for any content in _docs
, by
way of being a collection, they would general URLs that logically corresponded to their organization. For example:
_docs/
├── ci-cd
├── compilers
├── containers
│ ├── docker.md (- /docs/containers/docker
│ ├── docker
│ │ └── getting-started.md (- /docs/containers/docker/getting-started
│ ├── subpage (- /docs/containers/subpage
│ └── singularity (- /docs/containers/singularity
This was annoying, of course, because instead of doing this to define an “index.html” equivalent:
_docs/
├── ci-cd
├── compilers
├── containers
│ ├── docker
│ │ ├── index.md (?? /docs/containers/docker/
│ │ └── getting-started.md (- /docs/containers/docker/getting-started
I had to do what I showed above - a docker.md alongside the docker folder. But I could actually use a permalink
to get around that if I wanted.
But I digress! With the organization above, I had a fairly auto-generating site, and although I had a few “summary” or top level pages to loop through all links, I still largely had to link from page to page. That was tiring.
Automatic Generation of Direct Child Pages
It occurred to me that given the structure of the url, I could easily derive pages that were children of other pages, and then at the bottom of each page, automatically provide navigation to any page on the next level. For example, if I have these pages:
/docs/
/docs/containers
/docs/containers/singularity
/docs/containers/docker
/docs/containers/docker/tutorial
/docs/ci
When I’m at the root, docs
, I’d only want to see links to
/docs/containers
/docs/ci
When I navigate then to /docs/containers
I’d only want to see:
/docs/containers/singularity
/docs/containers/docker
You get it. This seems obvious in retrospect, but I don’t see if often on Jekyll sites! So the easy logic is that when we are looping through pages in docs, we do a comparison to a potential “next page” and the current page. We check:
- Is the contender page url included in the current url?
- Is the nesting of the contender page the current nesting + 1?
For the first point, you can easily just check if the contender page url contains the current page url. E.g., “/docs/containers/docker” contains “/docs/containers” and therefore should be included. And for the second, we basically do a bunch of splitting and counting of slashes. In case this is useful for anyone else wanting similar functionality, here is what I came up with.
<h3>Read Next</h3>
{% assign page_url = page.url | replace: "index", "" | split: "/" | join: "/" %}
<!-- We compare lengths - the next level should be current +1.-->
{% assign current_level = page_url | split: "/" | size %}
{% assign next_level = current_level | plus: 1 %}
<div class="section-index">
<hr class="panel-line"><div class="card-columns">{% for doc in site.docs %}
{% assign doc_url = doc.url | replace: "index", "" %}
{% unless doc.url == page.url %}
{% assign comparison_count = doc_url | split: "/" | size %}
{% if next_level == comparison_count %}{% if doc_url contains page_url %}
<div class="card next-card">
<h5><a href="{{ site.baseurl }}{{ doc.url }}">{{ doc.title }}</a></h5>
<p>{{ doc.description }}</p>
</div>
{% endif %}{% endif %}{% endunless %}{% endfor %}<br>
</div>
Mind you that how you render your pages is up to you - I have little cards that include titles and descriptions. The result looks something like this:
And the example we talked about:
Just a tiny thing - but if this is useful to you, I’d like to help! Happy Jekyll-ing!
Suggested Citation:
Sochat, Vanessa. "Automatic Jekyll Navigation." @vsoch (blog), 20 Oct 2021, https://vsoch.github.io/2021/jekyll-next-navigation/ (accessed 22 Dec 24).