I have to admit, @DownPW gets the credit for this, as I saw something he was working on for his release of v3 and liked it so much I asked him if I could “steal” it for my own site.
I took his original design concept and extended it using the NodeBB API. In Harmony, it looks like this (see resultant menu on the left underneath the categories button).
Now I have you salivating I expect you’d like the code to test for yourself? Sure…
Firstly, you’ll need to go to /admin/settings/navigation
Locate the Categories icon as shown below, and enable the “Dropdown” feature
Save
Now add the below code into the section shown
<li id="thecategories"><span class="category-menu"><i class="fa fa-fw fa-list"></i><a style="display: inherit;" class="dropdown-item rounded-1" href="/categories">All Categories</span></a></li>
Save your changes
Now to go /admin/appearance/customise#custom-js
Paste this code into the editor
$(document).ready(function() {
$.getJSON('/api/categories', function(data, status) {
$.each(data.categories, function(key, value) {
var categorylist = $(" \
<li><span class='category-menu'><i class='fal " + this.icon + "'></i><a style='display: inherit;' class='dropdown-item rounded-1' href='/category/" + this.slug + "'>" + this.name + "</a></span></li> \
<ul style='list-style: none;'>" +
this.children.map(c => `<li><span class='category-menu'><i class='fal ${c.icon}'></i><a class='dropdown-item rounded-1' style='display: inherit;' href='/category/${c.slug}'>${c.name}</a></span></li>`).join(" ") +
"</ul><li class='dropdown-divider'></li>"
);
if ($(window).width() < 767) {
$(".bottombar #thecategories").append(categorylist);
} else {
$(".sidebar-left #thecategories").append(categorylist);
}
});
});
});
Save the changes
Now go to /admin/appearance/customise#custom-css
Add the below code into the CSS console
li#thecategories {
min-width: 250px;
padding-left: 10px;
font-size: 90%;
padding-right: 10px;
}
span.category-menu {
display: inline;
margin-left: 10px;
margin-right: 10px;
}
Note, you’ll likely need to adjust this CSS to suit your own site and layout.
NOTES: It’s important to detail here that the JS function does all of the work for you, but will include any icons you’ve defined for categories etc. If you don’t use icons, you should remove the below sections
<i class='fal " + this.icon + "'></i>
Of equal importance is the below if/else
if ($(window).width() < 767) {
$(".bottombar #thecategories").append(categorylist);
} else {
$(".sidebar-left #thecategories").append(categorylist);
}
This determines the size of the viewport in use (mobile versus desktop) and then based on the output from the device, determines where to append the dynamic output - either the sidebar
or the bottombar
). As this is effectively choosing a location, we can use the same id of #thecategories
twice as it’s “one or zero” - either one, but not both - in a nutshell, you cannot declare the same ID
twice or this will cause you problems.
As this code uses the API, it never needs to be updated - if you remove or add any categories, these are reflected as soon as you reload the browser. So we don’t kill the CPU or the website itself, this code is only called onLoad
and does not trigger using any ajax
callbacks.
Enjoy.