Create navigation menu from markdown headers

Grav Community,

I have a long reference page on my site. I’d like to add a menu (left, right, or drop-down) that is automatically generated from the markdown headers and allows the user to quickly jump to the section of interest. I’ve searched on the Grav documentation site and this Discourse channel, but haven’t found what I was looking for. My questions:

*. Is there a resource or working example people can point me to?
*. Can I restrict the menu to desktops (non-mobile) to prevent hogging up smaller screens?
*. Can I specify header depth? (e.g. exclude H4, H5, …)

Thank you,

Sean

1 Like

Hi @jerobapatrol, might this Plugin be something suitable? https://github.com/trilbymedia/grav-plugin-page-toc

Thanks @paulhibbitts. That looks useful. I’ve installed the theme, but I’m unsure of which template file to modify, as per the Usage directions.

I’m an amateur developer and I’m still learning how Twig and templates work.

Welcome to Grav @jerobapatrol🙂I myself am an educator/interaction designer with some tech background, and though of course it takes time to learn the basics of Grav esp. Twig once you get going I have found it much easier to work with than other CMSs/LMSs I have tried.

Which Theme are you using? Based on that I might be able to help where you need to put that bit of Twig.

Thanks @paulhibbitts. I’m using the Quark theme. I’m not sure if I’m trying to extend or customize it.

I would start out by setting up an inherited theme https://learn.getgrav.org/16/themes/customization#theme-inheritance. This is a great way to make minor changes to a theme and benefit from all parent theme updates etc.

What is the filename of the page you want to a a TOC to? With Grav, a Markdown filename is used to then select which Twig Template is used to render the page https://learn.getgrav.org/16/content/content-pages#page-file

@paulhibbitts. I’d like to add a TOC to a default.md file.

I’m working through the process of creating an inherited theme.

Sounds good, once an inherited theme is setup choose it to be your “Active Theme”, and hopefully it all works the first time🙂Then make a copy of default.html.twig in the Quark templates folder to the same location in your inherited theme. At that point you could give it a go to add that Twig from the Plugin example or loop back and let me know how things are going.

ps - you can see a working (though more complex) inherited theme with my Open Publishing Space skeleton https://getgrav.org/downloads/skeletons

@paulhibbitts. I created the new inherited theme. Everything looks OK except for whitespace. Side padding seems to have disappeared.

Should my new default.html.twig file look as follows?

{% extends 'partials/base.html.twig' %}

{% block content %}
    {{ page.content|raw }}

    {% if config.get('plugins.page-toc.active') or attribute(page.header, 'page-toc').active %}
    <div class="page-toc">
        {% set table_of_contents = toc(page.content) %}
        {% if table_of_contents is not empty %}
        <h4>Table of Contents</h4>
        {{ table_of_contents }}
        {% endif %}
    </div>

    {% endif %}

{% endblock %}

I tried placing the TOC content after the endblock but it broke the site.

Yes @jerobapatrol that should be fine, and if you want to place the TOC before any page content it would look like this:

{% extends 'partials/base.html.twig' %}

{% block content %}

  {% if config.get('plugins.page-toc.active') or attribute(page.header, 'page-toc').active %}
  <div class="page-toc">
      {% set table_of_contents = toc(page.content) %}
      {% if table_of_contents is not empty %}
      <h4>Table of Contents</h4>
      {{ table_of_contents }}
      {% endif %}
  </div>
  {% endif %}

    {{ page.content|raw }}
{% endblock %}

I am not sure re: side padding issue though…

Got it, you might need to save the config for your new theme with “Grid Size” set to “Large” rather than default to empty.

For example, here is the setting for my “my-theme” config (in user/config/themes/my-theme.yaml):

streams:
  schemes:
    theme:
      type: ReadOnlyStream
      prefixes:
        '': [user/themes/my-quark, user/themes/quark]
production-mode: true
header-fixed: true
header-animated: true
header-dark: false
header-transparent: false
sticky-footer: true
blog-page: /blog
spectre:
  exp: false
  icons: false
grid-size: grid-lg

I appreciate your feedback. I now have an automatically generated table of contents before the page content and the your suggestion about setting the “Grid Size” to “Large” fixed the padding issue. Thanks!

My only remaining issue is that I’d like the TOC content to be separate and not in-line with the main page content. I was expecting that behavior given the image shown in https://github.com/trilbymedia/grav-plugin-page-toc/blob/develop/README.md. From looking at different pages, I think what I’m looking for is an off-canvas side bar.

Do I need to create new page type? Or can I modify default.html.twig to accommodate the different page structure? I need to do some more reading about Twig.

(I also lost my custom page icon, but I’ll dig around and try and find a way to re-add it. )

Thanks,

Sean

I’m taking a look at: https://picturepan2.github.io/spectre/experimentals/off-canvas.html

To be honest I am not sure what the next step would be re: TOC on the sidebar with Quark (that is not a Blog type page). Perhaps search these forums to see if you can find anything.

I would tend to leave default.html.twig alone though, as it is used by other pages within Quark etc. I would suggest you make a copy of it, perhaps called “toc-page.html.twig” and rename your MD file to “toc-page.md” and then do whatever you wish with that new Template - I hope that makes sense🙂

BTW, when I was first learning about Grav etc I found picking apart some of the core skeletons a great learning exercise - for example the One Page Site or Blog Site skeletons.

It makes sense to create a new page type so that I don’t affect every other page on my site.

The skeletons are a good resource. I’ll see if I can find one that has the setup I like and go from there.

It will take me some time to do the reading, so I probably can’t provide an update before this post sinks to the bottom and out of sight, but thanks for help and for pointing me in the right direction.

1 Like

2 posts were split to a new topic: How to create ‘Quick Menu’ as on Learn site?