Mark Llobrera

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:

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.