Reputation: 33378
I have a simple Eleventy site v0.11.0
I'm using tag in the front matter to generate collections.
Ex:
---
title: Some post
tags:
- apple
- banana
- soccer
---
I want to show a list each of each tag / collection but I can't figure out how to do it.
Upvotes: 1
Views: 2781
Reputation: 151
my version of the working code
// Display tag list on page
eleventyConfig.addCollection('tagsList', function (collectionApi) {
const tagsList = new Set()
collectionApi.getAll().map((item) => {
if (item.data.tags) {
// handle pages that don't have tags
item.data.tags.filter((tag) => !['yourtag'].includes(tag)).map((tag) => tagsList.add(tag))
}
})
return tagsList
})
Upvotes: 0
Reputation: 33378
I can get it working by creating a new collection in my .eleventy file...
eleventyConfig.addCollection("tagsList", function(collectionApi) {
const tagsList = new Set();
collectionApi.getAll().map( item => {
if (item.data.tags) { // handle pages that don't have tags
item.data.tags.map( tag => tagsList.add(tag))
}
});
return tagsList;
});
Then in the template:
{% for tag in collections.tagsList %}
<a href="/tags/{{tag}}">{{tag}}</a>
{% endfor %}
But this feels hacky and I suspect there must be a better way to do this.
Upvotes: 4
Reputation: 8540
Your own answer seems quite correct to me. Some comments:
addGlobalData()
method, but accessing the data like it's a collection (collections.tagsList
). I don't know how that's possible, but maybe I just have some problems on my end because I can't get addGlobalData()
to work at all.addGlobalData()
) would be to create a collection (addCollection()
). This is what I do on my 11ty site: I create a collection of tags in my .eleventy.config.js
. Looks like 11ty/eleventy-base-blog also uses a collection of tags.Array.prototype.map()
returns a new array. Your code uses map()
twice, but doesn't use their return values (i.e. the new arrays). If the new arrays are not needed, using Array.prototype.forEach()
would make more sense.Here's how I would create the collection (very similar to your solution):
config.addCollection('tagsList', (collectionApi) => {
const tagsSet = new Set()
collectionApi.getAll().forEach((item) => {
if (!item.data.tags) return
item.data.tags.forEach((tag) => tagsSet.add(tag))
})
return tagsSet
})
Usage in templates would be the same.
Bonus: with filtering (excludes tags "foo" and "bar") and alphabetical sorting:
config.addCollection('tagsList', (collectionApi) => {
const tagsSet = new Set()
collectionApi.getAll().forEach((item) => {
if (!item.data.tags) return
item.data.tags
.filter((tag) => !['foo', 'bar'].includes(tag))
.forEach((tag) => tagsSet.add(tag))
})
return [...tagsSet].sort((a, b) => b.localeCompare(a))
})
Upvotes: 1