Picking Favorites
A Few of my Favorite Things
I’ve had this site for nearly a year now, and I have a few articles I’m most proud of. Unfortunately, as time passes and I produce more and more content, those articles are going to be pushed farther and farther down the list. It feels bad to see those articles getting pushed out, so I’ve made a list of things that get special treatment
How to do it
I found a webpage that tackled this very problem here. It covers a few different strategies, but I went with the frontmatter path. This made the most sense to me because favorites aren’t tags to me. The frontmatter approach is also flexible in that you can add and remove components outside of the default layouts without messing with established features. If you go down the tags route, and you don’t think of featured articles as tags, you’ll need to set up custom code in those layouts to exclude the tag.
What’s needed is 3 main things:
- You need to decide what your property name will be for “featured” articles
- Given the setup tag, you need to setup a “featured” page for your articles
- If you want your featured content to stand out, you’ll need to modify their presentation on the main pages.
The easy part is setting up the frontmatter. I picked the “featured” parameter, so the only thing I did with the content was put this in the frontmatter:
featured: true
That’s it! This is one of Hugo’s best features. You can define properties on the frontmatter of your content without having to do anything else and they show up as properties that the layouts can use. It just works. It’s one of my favorite features in Hugo.
Now, with this in place on a few key posts you can go into the layouts where we need this property and set up custom logic. I cover this in my Featured Page section and the following Adding Favorite Icons to the Post List. You don’t need to set up the Taxonomy, the list pages, or any of that if you don’t want to, but I think it’s neat and organized if you do.
The Featured Taxonomy
Setting up new taxonomies with new URL’s for Hugo is a bit of a checklist: fist you set up the taxonomy, then the partial, then you link up the taxonomies to point to the right pages, then you rework the partial to fit your needs, and finally write the content that goes with that landing page. It works, but it helps to have a list of things you need to do handy.
To set up the featured page as its own taxonomy, add it to the taxonomies group
in your config.toml
file.
[taxonomies]
category = "categories"
series = "series"
tag="tags"
featured="featured"
Something like that. Once you have a taxonomy, you can start doing some interesting things with Hugo. In general, a taxonomy usually gets a landing page. Things like posts, tags, and series (at least on my site) all get their own landing pages which have sub content, at least in the case of tags and series.
The Featured Page
Now that I’ve got a featured property that I can add to my articles, it’s time
to carve out a space on my site with a landing page. Hugo’s pretty smart about
finding what you want to build; once you have a taxonomy, you can set up a
custom page for the list
and single
etc. The specifics of which kinds of
layouts you can work with are here
but for taxonomies like favorites, I try to remember that I’m only hashing out
the list.
So under my layouts folder, I’d add the “featured” directory, and make a partial
called list.html
. Luckily for me, most of this is going to look a lot like my
basic list, so I’ve copy-pasted the partial from there. The only thing that’s
different is how this partial figures out what to display.
Luckily, it’s not too bad:
{{ $page := .Paginate (where (where .Site.RegularPages.ByPublishDate.Reverse "Section" "post") ".Params.featured" "=" true)}}
Adding Favorite Icons to the Post List
I also want my featured posts to show that they’re special in the main listing of my articles. Adding a star icon with material icons should do the trick.
I handle this with a conditional render based on the “featured” parameter
{{ if eq .Params.featured true }}
<span class="fav-star mdc-tab__icon material-icons" aria-hidden="true">
star_border
</span>
{{ end }}
Adding the “fav-star” class to my style sheet too:
.fav-star {
flex: 1;
color: $secondary;
font-size: map.get($size-map, 'font-small');
}
This style just makes sure that the star doesn’t get too big, and that it’s blue! I add this to the card component because this is the only place that style will show up, and we’re good to go on the
Adding to the Home Page and Side bar
So now we’ve got a custom “featured” page (that’s the taxonomy and list.html
page we made), we’ve got a special icon that lets these posts stand out a bit
more, but how ‘featured’ would these posts be if they don’t even show up on the
home page or the side bar? The changes for both of these are very similar so
I’ll go over the sidebar and let you fill in the details of the home page.
Before this enhancement I only have my “Tags” and “Series” collections. They’re pretty good, but I want my featured posts in there too. We can do something strikingly similar to the other two.
I based the features section off the tags entry:
<div class="side-nav-group">
<a href="/tags" class="no-dec">
<span class="side-nav-header">
<span class="mdc-tab__icon material-icons" aria-hidden="true">label</span>
<h3>Tags</h3>
</span>
</a>
<ul class="side-nav-list">
{{ range $stamp := first 9 (sort $latest_tags "stamp" "desc") -}}
{{- $key := index $stamp "term" -}}
{{- $value := index $.Site.Taxonomies.tags $key -}}
<li>
<a href="{{ $value.Page.Permalink}}" class="ninja">
{{ $key }} ({{$value.Count}})
</a>
</li>
{{ end }}
{{ if ge (len $.Site.Taxonomies.tags) 10 }}
<li>
<a class="ninja" href="/tags">
More Tags...
</a>
</li>
{{ end }}
<li>
</li>
</ul>
</div>
For both tags and series, I had to get variables that pre-sort at the top of the
partial. The featured section is straightforward by comparison: instead of
having a key value pair set up for each entry, and having to mess with the
iterator to properly pick out the right tags, I replace all the data before the
li
elements with this:
{{ range first 3 (where (where .Site.RegularPages.ByPublishDate.Reverse "Section" "post") ".Params.featured" "=" true) }}
If you can follow Hugo’s iterator language, it’s saying that we iterate through regular post pages (that’s things like content, excluding the “list” and “summary pages”), that also have my featured parameter. Swap out the anchor tag’s endpoint and text to go to my new taxonomy listing page, add a different icon (star_border to keep consistent) and it’s done. I Used that same iterator to update the homepage, and placed a similar list under a new header.
Writing that summary
The taxonomy page will look a bit empty with just a bunch of article cards, so I’ve gotten in the habit of writing a small summary for why these pages exist, and Hugo makes it pretty easy to do that.
With any taxonomy, (post, series, featured, etc.) Hugo will look for an
_index.md
file and display the content wherever the layout’s {.Content}
tag
is. So I drop a small markdown file at content/featured/_index.md
that has the
title and a short piece of text and it’s done.
That’s it!
There are a few more upgrades that we could do, like adding something on featured posts that link back to other featured posts. Those upgrades will all fall in line with what I’ve done here. And maybe I’ll write a quick post about those changes too.
I started this minor upgrade with feedback from a friend who wanted to know which articles they’d want to read the most - essentially what I’m most proud of on this site. I’ve got to say that setting this up was almost scarily easy with Hugo. I’m hoping that articles like this help out the Hugo community too: if I hadn’t found that webpage, I’m not sure how I’d have tried to tackle this without that kind of help.