7.7 KiB
title, audience, tags, keywords, last_updated, summary
title | audience | tags | keywords | last_updated | summary | |
---|---|---|---|---|---|---|
Sidebar navigation | writer, designer |
|
The sidebar and top navigation bar read their values from yml files. The navigation components are one of the most unique parts of this theme, since the navigation components are only included if they meet all of the product, audience, version, etc., values as specified in the project settings. |
{% include linkrefs.html %}
Sidebar overview
To configure the sidebar, edit the values in the _data/sidebar_doc.yml file. Follow the example here in this theme. Note that YML spacing is picky. Each new level is two spaces indented. I usually just keep a template that shows all three levels and then copy and paste from it as needed.
Sidebar levels
You can add two levels of nesting in the sidebar nav. For example:
Introduction
-> Getting started
-> Features
-> Configuration
-> Options
-> Automation
You can't add more than two levels. In general, it's a best practice not to create more than two levels of navigation anyway. If you need deeper sublevels, I recommend creating different sidebars for different pages, which is logic that I haven't coded into the theme but which could probably be added fairly easily.
External links
If you want the URL to point to an external site, use external_url
instead of url
in the data file. Then just enter the full HTTP URL. The sidebar.html will apply this logic:
{% raw %}
{% if item.external_url %}
<li><a href="{{item.external_url}}" target="_blank">{{subcategory.title}}</a></li>
{% endraw %}
How it works
The values in the sidebar_doc.yml file are coded to match the logic in includes/sidebar.html.
Each of the items in the sidebar needs to have the attributes shown here:
- title: Getting started
url: /doc_getting_started.html
audience: writers, designers
platform: all
product: all
version: all
The audience, platform, product, and version are specified in the includes/custom/conditions.html file:
{% raw %}
{% if site.project == "doc" %}
{% assign audience = "designers" %}
{% assign sidebar = site.data.sidebar_doc.entries %}
{% assign topnav = site.data.topnav_doc.topnav %}
{% assign topnav_dropdowns = site.data.topnav_doc.topnav_dropdowns %}
{% assign version = "all" %}
{% assign product = "all" %}
{% assign platform = "all" %}
{% assign link = "custom/doc/links_doc.html" %}
{% assign projectTags = site.data.tags_doc.allowed-tags %}
{% assign searchGroup = "doc" %}
{% endif %}
{% endraw %}
Additionally, note how some assignments are set here as well. The conditions.html file set things like sidebar = site.data.sidebar_doc.entries
.
When the sidebar.html file runs the logic, it includes these statements:
{% raw %}
{% include custom/conditions.html %}
{% for entry in sidebar %}
{% endraw %}
The assignment of the sidebar
value means this is really what's happening:
{% raw %}
{% include custom/conditions.html %}
{% for entry in site.data.sidebar_doc.entries %}
{% endraw %}
Since different projects will use different data files, I had to make the logic run using the standard sidebar
variable, but change the meaning of that variable based on the project.
Sidebar accordion
The configuration file (configs/config_writers.yml) file includes a value (sidebar_accordion
) that lets you choose whether to use the accordion feature in the sidebar or not. The accordion feature collapses other sections when a section is opened, which conserves space on the screen. Put true
or false
for the value.
Sidebar fixed or moving
If you scroll up, the sidebar usually remains fixed in place. This is so that users can keep the context of the table of contents in place while they move down the page.
However, if the user's viewport is really small, you don't want the TOC to remain fixed in place because expanding one section may extend past what is visible. In the js/customscripts.js file, I inserted some logic to check the viewport size.
$( document ).ready(function() {
//
var h = $(window).height();
console.log (h);
if (h > 800) {
$( "#mysidebar" ).attr("class", "nav affix");
}
// activate tooltips. although this is a bootstrap js function, it must be activated this way in your theme.
$('[data-toggle="tooltip"]').tooltip({
placement : 'top'
});
});
The script says, if the height of the viewport is greater than 800px, then insert affix
class, which makes the nav bar fixed as your scroll. If you have a lot of nav items, this fixed position may not work for you. For example, if your sidebar has a lot of items and the fixed position makes it so the user can't see all the items when expanded, you may want to adjust the height. If viewing the sidebar is ap roblem, increase the height value from 800
to 1000
or more.
Navgoco foundation
The sidebar uses the Navgoco jQuery plugin as its basis. Why not use Bootstrap? Navgoco provides a few features that I couldn't find in Bootstrap:
- Navgoco sets a cookie to remember the user's position in the sidebar. If you refresh the page, the cookie allows the plugin to remember the state.
- Navgoco also inserts an
active
class based on the navigation option that's open. This is essential for keeping the accordion open. - Navgoco also includes the expand and collapse features of a sidebar.
In short, the sidebar has some complex logic here. I've integrated Navgoco's features with the sidebar.html and sidebar_doc.yml to build the sidebar. It's probably the most impressive part of this theme. (Other themes usually aren't focused on creating hierarchies of pages, but this kind of hierarchy is important in a documentation site.)
Highlighting the active item
Here's how the highlighting of the currently viewed page works. In the sidebar.html file, you'll see this:
{% raw %}
{% elsif page.url == item.url %}
<li class="active"><a href="{{item.url | replace: "/",""}}">{{item.title}}</a></li>
{% endraw %}
The page.url
is a universal Jekyll tag that returns the end path of the page, prepended with /
. For example, /sample.html
. If this page URL matches the item.url specified in the sidebar_doc.yml file, then an active class gets applied.
Note that I've added a filter to the item.url in the sidebar.html file:
{{item.url | replace: "/",""}}
Ideally, in the sidebar_doc.yml file, you could just write the URL you want to go to: sample.html
instead of /sample.html
. However, page.url always returns the forward slash before the URL. In order to match the page.url with the item.url, you have to use the forward slash before item.url in the doc_sidebar.yml file.
However, if you set up your relative link as /sample.html
instead of sample.html
, then the browser will go to the directory root instead of any baseurl. For example, if your site is deployed at http://mydomain.com/doc/, then going to /sample.html
in the link will take you to http://mydomain.com/sample.html instead of http://mydomain.com/doc/sample.html. In contrast, going to sample.html
in the link will take you to http://mydomain.com/doc/sample.html. Hence the filter to remove the forward slash in the link.
That logic handles the highlighting of the active item, but in order for the sidebar to remain open, the parent level needs to also have the active class. To accomplish this, I inserted this script below the sidebar code in the sidebar.html file:
<script>$("li.active").parents('li').toggleClass("active");</script>
This script has to come after the sidebar code; otherwise, if placed inside customscripts.js, the script runs before the sidebar code runs and the class never gets inserted.