My tutorial template require a sidebar menu with tree capability. There are many types of sidebar menus with tree capability
-
Show all tree node opened.
-
Show all tree node collapsed, except current url opened. Using javascript.
-
Show all tree node collapsed, except current url opened. Using serverside, or static page.
Using Liquid template we will have all tree node opened. We will discuss a more complex example in next post.
Stylesheet
There’s nothing special, and you can see required css for sidemenu navigation here.
Navigation Data
It has been said a thousand times that Jekyll doesn’t support database connection. But we have YAML data as a workaround. And actually I find that reading yaml is easier when it comes to tree, compared with tweaking RDBMS.
We need three fields for each branch [title, url, and submenu tree node] Let’s see our sample _data/navigation_wm.yml to hold my Window Manager (WM) menu.
# Site navigation links
- title: Preface
url: /pages/desktop/index
submenu:
- title: Difference WM/DE
url: /desktop/2016/06/13/de-wm-shell-difference.html
- title: Dotfiles
url: https://gitlab.com/epsi-rns/dotfiles/
- title: Tiling WM
url: /pages/desktop/twm
submenu:
- title: Awesome
url: /pages/desktop/awesome
submenu:
- title: Modular
url: /desktop/2016/07/13/modularized-awesome-preparing.html
- title: Directory Structure
url: /desktop/2016/07/06/modularized-awesome-structure.html
- title: XMonad
url: /pages/desktop/xmonad
- title: i3
url: /pages/desktop/i3
See a complete tree in github
To make the page flexible, let’s decouple the data source name from the processing file.
In the layout file _layouts/page-sidemenu.html we will pass the variable name:
{% include layout/sidemenu.html
menusource = site.data.navigation_wm
%}
In the include file _includes/layout/sidemenu.html we will use the variable as below:
<ul class="nav" id="menu">
{% for link in include.menusource %}
...
{% endfor %}
</ul>
A Very Simple Loop
We will use the data field wisely to create a very simple menu. This _sidemenu.html will produce side bar menu with no tree.
Don’t worry if it is looks complex, it is just html formatting.
<ul class="nav" id="menu">
{% for link in include.menusource %}
{% if link.url contains 'http' %}
{% assign domain = '' %}
{% else %}
{% assign domain = site.url %}
{% endif %}
{% if link.url == page.url%}
<li class="active">{% else %}<li>
{% endif %}
<span class="fa fa-list"></span>
<a class="page-link" href="{{ domain }}{{ link.url }}"
{% if link.url contains 'http' %}target="_blank"{% endif %}>
<span class="collapse in">{{ link.title }}</span>
{% if link.url == page.url%}
<span class="sr-only">(current)</span>
{% endif %}
</a>
</li>
{% endfor %}
</ul>
Adding Tree Level
Since we have three levels, we need to add two more loops. Each inside another.
<ul class="nav" id="menu">
{% for link in include.menusource %}
...
{% if link.submenu %}
<ul>
{% for sublink in link.submenu %}
...
{% if sublink.submenu %}
<ul>
{% for subsublink in sublink.submenu %}
...
{% endfor %}
</ul>
{% endif %}
...
{% endfor %}
</ul>
{% endif %}
...
{% endfor %}
</ul>
This will produce a simple tree menu with all node opened.
Complete Code
This original code is going to be long.
<!--ul class="nav nav-sidebar"-->
<ul class="nav" id="menu">
{% for link in include.menusource %}
{% if link.url contains 'http' %}
{% assign domain = '' %}
{% else %}
{% assign domain = site.url %}
{% endif %}
{% if link.url == page.url%}
<li class="active">{% else %}<li>
{% endif %}
<span class="fa fa-list"></span>
<a class="page-link" href="{{ domain }}{{ link.url }}"
{% if link.url contains 'http' %}target="_blank"{% endif %}>
<span class="collapse in">{{ link.title }}</span>
{% if link.url == page.url%}
<span class="sr-only">(current)</span>
{% endif %}
</a>
{% if link.submenu %}
<ul>
{% for sublink in link.submenu %}
{% if sublink.url contains 'http' %}
{% assign domain = '' %}
{% else %}
{% assign domain = site.url %}
{% endif %}
{% if sublink.url == page.url%}
<li class="active">{% else %}<li>
{% endif %}
<span class="fa fa-chevron-right"></span>
<a class="page-link" href="{{ domain }}{{ sublink.url }}"
{% if sublink.url contains 'http' %}target="_blank"{% endif %}>
<span class="collapse in">{{ sublink.title }}</span>
{% if sublink.url == page.url%}
<span class="sr-only">(current)</span>
{% endif %}
</a>
{% if sublink.submenu %}
<ul>
{% for subsublink in sublink.submenu %}
{% if subsublink.url contains 'http' %}
{% assign domain = '' %}
{% else %}
{% assign domain = site.url %}
{% endif %}
{% if subsublink.url == page.url%}
<li class="active">{% else %}<li>
{% endif %}
<span class="fa fa-asterisk"></span>
<a class="page-link" href="{{ domain }}{{ subsublink.url }}"
{% if subsublink.url contains 'http' %}target="_blank"{% endif %}>
<span class="collapse in">{{ subsublink.title }}</span>
{% if subsublink.url == page.url%}
<span class="sr-only">(current)</span>
{% endif %}
</a>
</li>
{% endfor %}
</ul>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
</li>
{% endfor %}
</ul>
You can see the complexity. It gets complicated when you mixed logical code (liquid) and presentation code (html formatting). We will solve this issue in the next post.