New Feature: Post Labels
Now you might not see this too much since I plan to use the feature sparingly, categories and tags are both capable of sorting everything to a satisfactory level, but I’m using this thing that I just made to add extra little labels, which have a few cool uses.
So really, I’d have love to shortcode this, and just throw something like {{< multipart "1 of 2" >}}
in at the top, but that places them under the TOC for most posts, if they have one.
And generally if posts have a TOC, like the few ones that use this feature: My IPv6 rant, the Hackintosh guide, or my homelab overview, which are are pretty long, meaning you’d have a lot of scrolling.
And as much as some hack like setting toc: false
in the front-matter, and then slotting one in myself with the {{< toc >}}
shortcode, I just wasn’t feeling it.
The rest of this theme so far is pretty well templatized and everything like that is already controlled with front-matter, why can’t I do that with this?
Turns out, I can, but my current implementation isn’t that extensible as it stands.
Theme Modifications
Layout
For reference, the Bilberry Hugo theme, and by extension, my fork, works on a rather nested mechanism for templates.
The starting point, baseof.html
, is where Hugo starts, which can then add other “partials” like article-wrapper.html
or default-content.html
.
And yes, partials can include partials.
The one that I’m concerned with right now is the partial that will contain the actual post content, which is in layouts/partials/default-content.html
.
Here’s the modified section:
|
|
Right above the TOC part, I include a few if
s and with
s for each of the labels (obviously, internally referred to as “chips”, after their visual similarity to the similarly named Material Design element1).
The ones that have extra data along with them have a with
, and the ones that don’t have an if
.2
The entire <div>
that contains them is also wrapped in an if
so that if I don’t even include the key in the front-matter, this entire thing is skipped.
Now because of where I inserted this, this means that even in the “summary” view, say, as you see posts on the homepage or a category / tag listing, they will still be present, and will also show up above everything no matter what view its in.
Styling
You’ll notice that I gave everything there either an id
, a class
, or both
.
This is 100% just for styling, there’s no JS here.
I could do this with style
attributes, and indeed, when testing that’s what I did, and in the first revision of this that you didn’t see, that is what I did, but this is in production now, and I’d rather not have duplicate values all over the place, especially since the CSS for this theme is generated from a few different SASS files, which contain reusable variables, for things like text color, and the base theme color (my favorite green which nobody has yet guessed the source for, fun fact).
All these exist in assets/sass/_variables.scss
for this theme.
I edited _article.scss
, adding in some new rules:
|
|
This entire file is wrapped in an article
selector, meaning that none of these rules will take effect if found outside of a post’s markup.
As for my styling, there’s two main classes: “simple” chips with no extra data, they either exist, or don’t, and chips that do have extra data, like the last updated one.
Within the class I define some defaults, but then for each chip’s id
I can override them.
Note that none of the SASS here is actually live, it needs to be converted into the theme.css
file, which is done by running npm run production
from the theme’s root in this case.3 npm run dev
runs a lot quicker, which I can use when iteratively improving this piece by piece.
Usage
As I think I’ve mentioned a few times, Hugo posts can have “front matter”, which is either a JSON, YAML, or TOML block at the beginning of the file with some metadata. This theme’s templates (“archetypes”) use YAML. Here’s this post’s front matter:
---
title: "New Feature: Post Labels"
date: 2021-02-13T21:38:35-05:00
draft: false
categories: ["Blog improvements"]
tags: ["CSS", "JavaScript", "SASS"]
toc: false
author: "Teknikal_Domain"
---
Everything between the two ---
4 is the front matter block.
There’s a few values that aren’t present by default, like showComments
, or googleCharts
, or littlefoot
.
And then there’s… chips
.
For example, the Hackintosh post looks like this now:
---
title: "Hackintosh Up and Ready!"
date: 2020-01-07T21:47:35-05:00
draft: false
categories: ["Guides", "Hackintosh", "Tech tales"]
tags: ["Lenovo", "MacOS", "ThinkPad T440"]
toc: true
author: "Teknikal_Domain"
chips:
lastUpdate: Feb 4th 2020, 14:56 EST
---
This causes the little “last updated” label to appear with its value in there.5
For “simple” ones with no value, setting it to true
will show them, plain and simple.
List of Labels
-
Part 1 of 5
- Probably the least useful one of them all, but I’ll put this in there for multi-part posts, so as they’re coming out, you can see how many are going to be in that particular little series.
-
Updated Feb 4th 2020, 14:56 EST
- If I’ve ever updated a post after its initial publication, I’ll put this on there to mark that, A) it’s been updated, and B) when it was updated.
- This particular post just needs to be taken down and re-written (see also: IPv6). Afterwards, if I deem the original content isn’t relevant any longer and can be replaced, this will become an updated label, otherwise I’ll use…
-
Outdated
- Sort of like the improved label, but the other way around: this post is outdated and has a newer version up, but I decided that the original still had enough significance to keep it around. This one is also a link, clicking it will take you to the newer post automatically.6
-
New and improved!
- If a post is a rewrite, revision, or just overall newer version of a previous one, this will point out that what you’re about to read you might have seen before but it should be better this time around.
A Collateral Bugfix
So here’s something funny: I accidentally found and then fixed a bug as I was going through this.
What I noticed was that any messing with the TOC’s position, be it by manually adding a {{< toc >}}
shortcode, or by putting markup above the TOC in the templates, caused it to be collapsed whenever you toggled the top navbar.
This is because the theme uses <nav>
for the topnav, and, originally, that was the only thing that it was used for, meaning the jQuery that handles the toggling just selects nav
.
Since generated TOCs are also contained in a <nav>
element, that means that they get collapsed or expanded too.
Well the simple fix is to change the jQuery to select nav#topnav
instead, and give the topnav an id="topnav"
so now it will select one element instead of all elements of a given type. Done!
-
Note that chips in MD usually represent an input or action or some sort. The actual element that inspired this was GitLab’s issue labels, which is why I use the terms “label” and “chip” pretty interchangeably here. ↩︎
-
The real difference is that an
if
just checks if it exists, or in this case, it set totrue
. Awith
will allow me to get the content of that variable with{{ . }}
in that scope, but only if it actually exists, otherwise it’s skipped entirely. ↩︎ -
That
npm
invocation will generate a lot of files, the two main ones beingtheme.css
andtheme.js
, but also all the fonts, icons, and other static resources that it uses. Really, it rebuilds the entire theme and minifies it down into those static resources. ↩︎ -
---
is the YAML separator, expect to see+++
for TOML, just a plain{
and}
for JSON, and, I didn’t realize until writing this footnote, a group of#+KEY: VALUE
lines for org-mode front matter. ↩︎ -
If you’re kinda used to YAML but not completely familiar with it, you’re probably thinking that the line should be
- lastUpdate: date
notlastUpdate: date
, but you’d be incorrect. In YAML, the indentation is important, and prefixing your lines with-
makes it a normal array (with numerical indexes), but not using that-
on each item makes it a key: value dictionary. ↩︎ -
As you might have seen from the layout markup, this is the only one that uses the “simple” class and yet also has an actual data value: the path of the new post to link to. ↩︎