How do you make nested pages with Jekyll?

I have a website with the Jekyll Minima theme, and I’d like to have a nested structure on the navigation bar. Basically, I’d like to see, on the navigation bar,

  • Page 1
  • Page 2
  • Category 1
    • Page 3
    • Page 4
  • Category 2
    • Page 5
    • Page 6

such that if you hover the mouse over ‘category 1’, a submenu pops up showing ‘page 3’ and ‘page 4’, and so on. I don’t particularly care about whether pages are generated for the categories themselves.

I realize that there may be several different ways to do this. One thing I attempted, unsuccessfully, was add the following to my _config.yml

  Resouces:
    output: true
    permalink: /resources/:path/

and then I created a folder called _Resources containing a markdown file for a page. (Here, ‘Resources’ is a ‘category’ of pages and I’d like to add multiple markdown pages under Resources. However, this didn’t work.

You can see my github repository here; I am using Github Pages. Any help would be appreciated!

While there are HTML and SCSS tricks, you will probably find JavaScript to be the best answer to your solution. Since Jekyll supports open internet standards, HTML, CSS, and JavaScript are supported but I think you will have to code it yourself (or find something that will do it for you on a site like Fiverr.com.

There are a few things to keep in mind:

  1. Hovering is great for a computer, but not for mobile, so make sure you support both
  2. If someone is on mobile, then the mobile version of the manu may appear (the hamburger), so you will want to figure out how to populate that properly

I would suggest you find some ideas on CodePen and implement it something you like from there.

Here is an example of what I think you are looking for:

Menu with sub-menu

I think you might find better tech support for creating the submenus on a site like Stack Overflow (this is an opinion only). However, if you need help creating the categories in Jekyll, then that is something we can help you with here.

Can you share how you want to use the categories? For example, do you want to share categories from posts or pages using YAML front matter like from below?

---
title: my post
categories: [biking, boating]
---

Or something else? If you give some more examples of how you want to use these submenus? Looking at your website, there are a lot of chapters, so I worry the menu would be too big.

Hi @BillRaymond ! Thank you for your thoughtful reply.

  • Actually, I don’t particularly care for ‘hovering’ or any other ‘effects’. This is why I’m hoping that I can get away with not using JavaScript.
  • My website consists mostly of the ‘chapters’ which you can see. I don’t want a submenu for these.
  • The chapters will be accompanied by a few ‘Resources’. Each ‘resource’ is an HTML page with some supplementary information. If I make each Resource a page in the root directory of my Jekyll project, then a navigation bar entry is created for each of them (e.g., you can see currently on the site that there is a page called ‘Notes on Spinoza’ and a page called ‘Farabi’s emanation scheme’. I intend to add a few (say, less than 5) more such resources.
  • This crowds up the navigation bar pretty quickly. So I’d like the navigation bar to simply show ‘Resources’ and under that, will be ‘Notes on Spinoza’, ‘Farabi’, etc. I was hoping that there would be a simple way, using the Minima theme, to implement a nested structure for the navigation bar.

If there is no easy way to do this, I might just have to create a Resources ‘page’ and use Jekyll’s ‘for loop’ to loop through all the ‘resources’ and print a ‘table of contents’, with hyperlinks, for my Resources. This would be similar to how the table of contents for my ‘chapters’ is currently organized.

Okay, I think I understand the problem better now. Whenever you add a page, it adds it to the menu for you and you do not want that, correct?

The challenge here is that you are using the Minima theme and you will need to overwrite some of the code to accomplish this, which is super simple.

I see you have some YAML code in your site already that says nav:true, but I worry you used that all over the place and I’m not sure if you planned on using that for the menu or something else.

First, in the pages you want to appear in the menu, add another piece of YAML front matter and call it something like siteNav (it doesn’t really matter what you call it), then add that with the value of true. You do not need to go and edit all the other pages because by default, they will be false.

Farabi.md

---
layout: page
title: Farabi's emanation scheme
permalink: /Farabi
nav: true
siteNav: true
---
This is a test page.

Now, you will need to modify the /_includes/header.html for your site. Unfortunately, you are working with a GEM-based theme, so you will have to override the theme or that one file. Follow the instructions to get that file (or the whole theme) onto your site. Personally, I like to override the theme because then I have full control and honestly they rarely change (plus if they do, they might change to your dismay :slight_smile: )

Now that you [at least] have the _includes/header.html code in your site, you can add two extra lines of code that check for the siteNav YAML item. There are nicer ways to do this so you don’t end up with lots of if statements, but this will get you what I believe you are looking for.

/_includes/header.html

    {% comment %} Create a navigation pane {% endcomment %}
    {%- if page_paths -%}
      <nav>
        <ul>
          {%- for path in page_paths -%}
            {%- assign my_page = site.pages | where: "path", path | first -%}
            {%- if my_page.title -%}
              {%- if my_page.siteNav -%}
                <li><a class="page-link" href="{{ my_page.url | relative_url }}">{{- my_page.title | escape -}}</a></li>
              {%- endif -%}
            {%- endif -%}
          {%- endfor -%}
            </ul>
      </nav>
    {%- endif -%}
  </div>
</header>

Note that you are really only adding the following lines:

{%- if my_page.siteNav -%}
  ...
{%- endif -%}

Hope that helps

Thanks! Adding a new piece of YAML front matter, and then adding an if statement (for those pages which I don’t want to appear in the site menu) into the header html, would be a very good solution.

However, I can implement the same effect without needing to edit the theme. I can use ‘collections’ and handle my ‘Resources’ the same way I have handled my ‘chapters’.

Thank you for your advice, though!

Yes, collections is a great way to create unique content in Jekyll. I thought specifically you were looking for the menu code, so glad you found another solution.