eleventy-navigation icon indicating copy to clipboard operation
eleventy-navigation copied to clipboard

active class on parent

Open fmeyer1980 opened this issue 6 years ago • 6 comments
trafficstars

Thanks for this wonderful plugin and love eleventy. But is there a way I can get active class on the parent selecter ?

fmeyer1980 avatar Nov 14 '19 22:11 fmeyer1980

You can do it by checking if entry.url == page.url

E.g.:

<nav id="menu">
  {% set pages = collections.all | eleventyNavigation %}
  <ul>
    {%- for entry in pages %}
    <li{% if entry.url == page.url %} class="current"{% endif %}>
      <a href="{{ entry.url | url }}">{{ entry.title }}</a>
    </li>
    {%- endfor %}
  </ul>
</nav>

p44v9n avatar May 26 '20 17:05 p44v9n

@p44v9n it just compares item.url to current page.url

I think OP asked for having a current/active class if navigation element page is parent of current page

it really difficult (or impossible?) to access a template's (aka page's) parent (and other user defined data) in a layout which isnt associated with the template like _base.njk oder _header.njk

After 2 hours of reading and trying

This https://www.11ty.dev/docs/data/

and This https://www.mikeaparicio.com/posts/2022-08-19-nested-navigation-in-eleventy/

I ended up with using plain path parsing (works only for first level)

// eleventy.config.js
const path = require("path");

module.exports = function (eleventyConfig) {
  eleventyConfig.addFilter("getbase", function (value) {
    const { dir } = path.parse(value);
    return dir + "/";
  });
}
{# layout #}
<nav class="main-navigation">
{% set navPages = collections.all | eleventyNavigation %}
  <ul>
  {%- for entry in navPages %}
	  <li{% if entry.url == page.url or entry.url == page.url | getbase %} class="current"{% endif %}>
		  <a href="{{ entry.url }}">{{ entry.title }}</a>
	  </li>
  {%- endfor %}
  </ul>
</nav>

scsskid avatar Mar 01 '23 16:03 scsskid

Building upon @scsskid's code, this is working right now for me with 3~4 sub dirs. I was only interessted if the top dir matched the menu item associated.

getbase: function (value) {
  if (value!==false) {
    const {dir}=path.parse(value);
    const firstPath=dir.split('/')[1];
    return "/"+firstPath+"/";
  } else {
    // Handle the case where value is a boolean false
    return "Invalid input: value is false";
  }
},

that ugly value!==false there is because i started having errors with navigation items that didn't have pages (they redirect to another url).

bronze avatar Sep 15 '23 04:09 bronze

It's ugly and only works for top level but this option doesn't require a filter:

{% set navPages = collections.all | eleventyNavigation %}
{% set navActiveClass = "is-active" %}

{%- for navItem in navPages %}

    {% if (navItem.url == "/") %}
        <li {% if navItem.url == page.url %}class="{{navActiveClass}}"{% endif %}>
            <a href="{{ navItem.url }}">{{ navItem.title }}</a>
        </li>
    {% elif navItem.url and page.url %}
        <li{% if navItem.url in page.url %} class="{{navActiveClass}}"{% endif %}>
            <a href="{{ navItem.url }}">{{ navItem.title }}</a>
        </li>
    {% endif %}

{%- endfor %}

The key is if navItem.url in page.url, check that the parent URL exists in the current URL. This should be unique for all top level URL. Unfortunately, the home link / exists in all URL so we have to check for that first.

Edit: replaced {% else %} with {% elif navItem.url and page.url %} as the build broke if a post was in draft.

patrickgrey avatar Nov 21 '23 11:11 patrickgrey

This is now possible with the CSS :has selector, which let you style elements based on their children, see https://developer.mozilla.org/en-US/docs/web/css/:has

li:has(.activeClass)

Thibaultfq avatar Jan 08 '24 21:01 Thibaultfq

in my own markup, i didn’t have parent child relationships, but i was able to use
{% if item.url in page.url %} to add a class to a page’s parent’s link. @patrickgrey gave me the idea.

<a class="nav-item has-children 
    {% if item.url == page.url %}active{% endif %} 
    {% if item.url in page.url %}active{% endif %}" 
    href="{{ item.url }}" {% if item.url == page.url %}aria-current="page"{% endif %}>
        {{ item.title }}
</a>

isralduke avatar Feb 07 '24 14:02 isralduke