Navigation
Documentation about navigation.
Documentation about navigation.
The main navigation menu is not done using the 11ty Navigation Plugin This allows to display a navigation menu that directly reflects the organisation of pages without having to add a key
or any information in the Front Matter.
This navigation will instead look in collections.all
and list all pages. It will show all first level pages in the main menu and all nested pages under each sub menu and so on.
If you want to exclude a page from the navigation (typically the 404 page and similar), you can just exclude it from the collections.all
by adding the following line in the pageās Front Matter:
eleventyExcludeFromCollections: true
The navigation menu can be added to the nunjunk template of your choice by just including menu.njk
.
{% include "menu.njk" %}
menu.njk
will loop on collections.all
and parse the url of each entry.
The first level entries are the ones wih 3 chuncks (more if you has a long path). From this point we will use the macro renderNavItem(entry)
to display the entry in the menu.
If the entry contains nested pages, the macro will handle it by loading itself again (see bellow).
{% set allEntries = collections.all %}
<ul role="list" class="flex">
{%- for entry in allEntries %}
{% if entry.url.split("/").length === 3 %}
{{ renderNavItem(entry) }}
{% endif %}
{% endfor %}
</ul>
The link to the home page which has fewer chucks of url is hard coded at the beginning of the navigation. This allows you to shape the link to home the way you want, with the word home, another name or even directly by adding your websiteās logo.
<li class="relative group">
<a href="/" {% if entry.url == "/" %} aria-current="page" {% endif %}
class="block p-4 text-nowrap hover:text-blue-300"
>ą„ home</a>
</li>
For each entry renderNavItem(entry)
will first look if the entry contains nested pages. If it does, it will set them as children.
{% for menuEntry in Allentries %}
{% if menuEntry.url.split("/").length === level + 1 %}
{% if menuEntry.url.split("/")[level-2] === entry.url.split("/")[level-2] %}
{% set children = (children.push(menuEntry), children) %}
{% endif %}
{% endif %}
{% endfor %}
If the entry has children it will contain a sub list where all entries will be handled, including their possible subsets, by calling the macro again.
{% if children.length %}
<li>
<div>
<summary>
<a href="{{ entry.url }}">{{ entry.data.title }}</a>
</summary>
<ul role="list">
{%- for child in children %}{{ renderNavItem(child) }}{% endfor -%}
</ul>
</div>
</li>
Entries without children will be displayed normally.
{% else %}
<li class="relative group">
<a href="{{ entry.url }}">{{ entry.data.title }}</a>
</li>
{% endif %}
### Styling the navigation menu items as needed
Since the navigation menu is a list with possible sublists, it is rendered on the page the way it is styled. The styled are applied using tailwind according to their level. They are added to the list loop using smaller macros aClass
and ulClass
.
First level entries are styled with a different colour
{% if entry.url.split("/").length === 3 %}
block p-4 text-nowrap hover:text-blue-300
{% endif %}
and their sub-blocks display on hover
{% macro ulClass(entry) %}
{% if entry.url.split("/").length === 3 %}
absolute left-0 hidden bg-white text-black shadow-lg group-hover:block
{% endif %}
{% endmacro %}
Second level entries are displayed under their parent entry in a drop-down menu.
{% if entry.url.split("/").length === 4 %}
block p-4 text-nowrap hover:underline
{% endif %}
Following entries will display in the same drop-down block with only smaller font and added padding.
{% if entry.url.split("/").length >= 5 %}
block px-4 py-0 text-sm text-nowrap hover:underline
{% endif %}
You may want to update the styles directly in both menu.njk
and renderNavItem.njk
so that it fits your needs.
If you donāt need such menu in your website, just remove these two files and carry on.