Let’s say you have an eleventy blog, and want to show the tags related to a given blog post.
E.g. this post is tagged with eleventy
as you can see above.
But, it has also other tags attached, e.g. post
and featured
for example, that are mainly used for creating the posts
and featured
collections.
The HTML/nunjucks code for showing the taglist on this very site is the following:
<div class="taglist">
Tagged with
{% for tag in tags | exclude("post") | exclude("featured") | limit(3) %}
<a aria-hidden href="/tags/{{ tag }}/" data-track="click-post-tag">{{ tag }}<sup>{{collections.tagList | findTagCount(tag)}}</sup></a>
{% endfor %}
</div>
There are a few things going on here:
- the post exposes its
tags
property, that’s straightforward - the filter
exclude
comes up twice, it’s chainable - the filter
limit
does exactly what you think - the link to the specific tag is
/tags/
, so there is a dedicated page for each tag - the collection
tagList
comes into play, together with the filterfindTagCount
Let’s break it down and go into each step and needed code
The exclude
filter
You can simply add the next few filters and collections to your eleventy config file.
The exclude
filter takes an array (namely the tags array as a list of tags/string) and excludes the first parameter passed to the filter
eleventyConfig.addFilter("exclude", (arr, exclude) => arr.filter(el => el !== exclude))
The limit
filter
Nothing fancy, limits a given array to a specified number of items:
eleventyConfig.addFilter("limit", (arr, limit) => arr.slice(0, limit))
The tagList
collection and findTagCount
filter
The tagList
collection goes over all blog posts, reduces them to an array of objects in the form {tag, count}
:
eleventyConfig.addCollection("tagList", collections => {
const tags = collections
.getAll()
.reduce((tags, item) => tags.concat(item.data.tags), [])
.filter(tag => !!tag && !["post", "featured", "popular", "opinion", "all"].includes(tag))
.sort()
return Array.from(new Set(tags)).map(tag => ({
tag,
count: collections.getFilteredByTag(tag).length,
}))
})
The findTagCount
filter takes the above tagList
and finds the number of occurrencies across all blog posts:
eleventyConfig.addFilter("findTagCount", (tagList, findTag) => tagList.find(({tag}) => tag === findTag)?.count)