Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Nickersoft/73a04c8f44968daeeb1ca96a89434273 to your computer and use it in GitHub Desktop.
Save Nickersoft/73a04c8f44968daeeb1ca96a89434273 to your computer and use it in GitHub Desktop.
Jekyll navigation bar with automatic highlighting.

Jekyll NavBar

In building a site powered by Jekyll and hosted by GitHub, I wanted the ability to highlight the current page's tab in the bar. I also wanted the bar to support second-level items (i.e. a dropdown), which proved somewhat tricky. This is the solution I arrived at after a few hours of fiddling around.

Construction

The contents of the navigation bar are contained in a data file located at _data/navigation.yml. This makes it accessible via the site-wide Liquid element {{ site.data.navigation}}. You can see the file for the formatting I used.

How it Works

This data is used in the navigation file, located at _includes/navigation.html (which is therefore able to be included in your templates via {% include navigation.html}).

Finding the current page in the list

The first section of the file has a loop that accomplishes two things:

  1. Does the current element of the loop have the exact same URL as the current page?
  2. If not, does the current element of the loop fit inside the current page's URL? (This is for nested pages.)

In the event of (1), the loop sets the current_page value and breaks. In the event of (2), the loop sets the current_page value but continues to loop. This effectively means the loop is searching for a best-fit value for the current page's URL.

Building the bar

Then the navigation bar is built. It loops over each entry and immediately checks if the current element is the same as the current_page value we found previously. If they are a match, a current variable is created that contains the class identifier to highlight the tab. If they are not a match the current variable must be set to null. This is to ensure you don't accidentally end up with a cascading highlighting effect. (Trust me, it's unwanted.)

Caveats

  • Any page that does not have an entry in the navigation.yml file will highlight a page with url: /.
  • My method is only built for a single sub-level. You'd have to adjust it for further sub-levels.
<!-- Belongs at: /_includes/navigation.html -->
<!-- This finds the current page so it can be highlighted. -->
{% for entry in site.data.navigation %}
{% capture fullurl %}{{ site.baseurl }}{{ entry.url }}{% endcapture %}
{% if fullurl == page.url %}
{% assign current_page = fullurl %}
{% break %}
{% elsif page.url contains fullurl %}
{% assign current_page = fullurl %}
{% endif %}
{% endfor %}
<!-- Then we build the nav bar. -->
<nav>
<ul>
{% for entry in site.data.navigation %}
{% if entry.url == current_page %}
{% assign current = ' class="current"' %}
{% else %}
<!-- We have to declare it 'null' to ensure it doesn't propagate. -->
{% assign current = null %}
{% endif %}
{% assign sublinks = entry.sublinks %}
{% if sublinks %}
<li{{ current }}>
<a href="{{ site.baseurl }}{{ entry.url }}">{{ entry.title }}</a>
<ul>
{% for sublink in sublinks %}
<li><a href="{{ site.baseurl }}{{ sublink.url }}">{{ sublink.title }}</a></li>
{% endfor %}
</ul>
</li>
{% else %}
<li{{ current }}><a href="{{ site.baseurl }}{{ entry.url }}">{{ entry.title }}</a></li>
{% endif %}
{% endfor %}
</ul>
</nav>
# Belongs at: /_data/navigation.yml
- title: Home
url: /
- title: Group of Things
url: /group/
sublinks:
- title: Sub-item 1
url: /group/si1
- title: Sub-item 2
url: /group/si2
- title: Sub-item 3
url: /group/si3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment