emersonthis
emersonthis

Reputation: 33378

How to generate a list of all collections in 11ty

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

Answers (3)

Alexander Krupnitsky
Alexander Krupnitsky

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

emersonthis
emersonthis

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

Matias Kinnunen
Matias Kinnunen

Reputation: 8540

Your own answer seems quite correct to me. Some comments:

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

Related Questions