2
votes

I'm building a static website on using . I'm properly generating a simple, two-level navigation from a data file. My problem is that I am stuck trying to do two things:

  1. Apply a "selected" class to the current page link item.
  2. Apply an "open" class to the parent list item when a sublink menu is present.

Here's the format I'm using in my _data/nav.yml file

- title: Top Level Nav Item
  url: level-1/
  sublinks:
    - title: Child Nav Item 1
    url: child-1/
    - title: Child Nav Item 2
    url: child-2/

Here's how I'm building my navigation:

{% assign current_page = page.url | remove: 'index.html' %}
<ul class="-nav">
{% for nav in include.nav %}
    {% assign current = null %}
    {% if nav.url == current_page %}
        {% assign current = ' _selected' %}
    {% endif %}
    {% if nav.url contains current_page %}
        {% assign open = ' _open' %}
    {% endif %}
    <li class="-item{{ current }}{{ open }}">
        <a href="{{ site.url }}{{ nav.url }}">{{ nav.title }}</a>
        {% if nav.sublinks and current_page contains nav.url %}
            {% include navigation.html nav=nav.sublinks%}
        {% endif %}
    </li>
{% endfor %}
</ul>

Again this builds my navigation correctly, but it doesn't apply either the selected or open class.

Here's what I'm would like it to look like in the end:

enter image description here

What am I doing wrong?

1
Not sure this matters for the output, but you have inconsistent quotations around values. Also, what happens when you remove the {% assign current = null %} statement?Joel Glovier
@JoelGlovier Nothing happens when I remove {% assign current = null %}.Hynes

1 Answers

2
votes

Finally got this working. I solved it by adding an item to the front matter of my page called permalink where I specified the desired page permalink.

---
layout: default
title: Example
permalink: url/example/
---

I use this permalink to check against the current page.url to add the desired _selected class on the <li> element.

I made one modification to my example data file, adding in the parent url_part into the child's url. I'm not sure why, but I had trouble printing the entire URL correctly otherwise.

- title: Top Level Nav Item
  url: level-1/
  sublinks:
    - title: Child Nav Item 1
    url: level-1/child-1/
    - title: Child Nav Item 2
    url: level-1/child-2/

Lastly for my navigation.html include, here's how I'm creating my main menu, rendering sub-menus if they exist and should be shown, and properly selecting the active link:

{% assign current_page = page.url | remove: 'index.html' %}
<ul class="-nav">
{% for nav in include.nav %}
    {% assign current = null %}
    {% if nav.url == page.permalink %}
        {% assign current = ' _selected' %}
    {% endif %}
    <li class="-item{{ current }}">
        <a href="/{{ nav.url }}">{{ nav.title }}</a>
        {% if nav.sublinks and current_page contains nav.url %}
            {% include navigation.html nav=nav.sublinks%}
        {% endif %}
    </li>
{% endfor %}
</ul>

The big difference between this and the snippet I originally posted is I dropped the {{ open }} stuff for now. One problem at a time. The other thing is that I'm checking to see if nav.url equals page.permalink. Before I was checking against page.url and this always failed for me.

It's probably not the prettiest, but I finally got a menu to generate (semi-)dynamically and properly select the active link.