Eleventy: Tag List Sorting and Post Count
This week I’m focusing on building out the tag-related pages for my new site, and I had two straightforward requirements for the tag list:
- Order the list of tags alphabetically
- Display the post count for each tag
The starter repository I’m using has basic support for a tags collection, but I noticed that the tag list is not sorted, and can change order with a build. I also couldn’t figure out how to add a post count. Fortunately the Eleventy/Jamstack community has been pretty open about sharing their site repositories. I took a look at Phil Hawksworth’s blog repo and found both elements that I needed (thanks Phil!).
Sorting the Tag List #
Phil wrote his own getTagList function to generate the tagList collection (the main difference that I can see from the version from the starter repo is that Phil is using the getAllSorted()
method when grabbing collections. I copied Phil‘s function and defined the collection in my .eleventy.js file:
eleventyConfig.addCollection("tagList", require("./src/utils/getTagList.js"));
So far, so good. However, I have a couple of custom post types that I’m using: book and project, which each have their own tags. For now I want to exclude those custom types from the main post tag archive. So, I added a quick filter into the mix to only return items that matched the post content type. Note that to do this, I had to make sure that I had explicitly add a content_type
attribute to my posts.json file, which looks like this:
{
"content_type": "post",
"layout": "post",
"tags": ["posts"]
}
Here’s my getTagList()
method in full:
module.exports = function (collection) {
let tagSet = new Set();
collection
.getAllSorted()
.filter(function (item) {
return item.data.content_type == "post";
})
.forEach(function (item) {
if ("tags" in item.data) {
let tags = item.data.tags;
if (typeof tags === "string") {
tags = [tags];
}
tags = tags.filter(function (item) {
switch (item) {
// this list should match the `filter` list in tags.njk
case "all":
case "nav":
case "post":
case "posts":
return false;
}
return true;
});
for (const tag of tags) {
tagSet.add(tag);
}
}
});
// returning an array in addCollection works in Eleventy 0.5.3
return [...tagSet].sort();
};
Adding a Post Count to Each Tag #
The post count for tags was even simpler. In his tag list template I found this snippet for printing out the post count for a tag: {{ collections[tag].length }}
. So my template looks like this:
---
permalink: /tags/
layout: layouts/base.njk
templateClass: tmpl-tags-list
---
<div class="content-main container">
<h1>Tags</h1>
<ul class="postlist">
{% for tag in collections.tagList%}
{% set tagUrl %}/tags/{{ tag }}/{% endset %}
<li class="postlist-item">
<a href="{{ tagUrl | url }}" class="postlist-link">{{ tag }}</a> ({{ collections[tag].length }})
</li>
{% endfor %}
</ul>
Thanks again to Phil Hawksworth for making his code public.