Is a generator for creating tag pages from collections possible?

Hi! Is it possible to create a generator for creating tag pages from collections, the same way you do for posts? I know very, very little about Ruby, but I’m willing to learn for this. I’m using this code for generating tag pages for posts:

module Jekyll
  class TagPageGenerator < Generator
    safe true

    def generate(site)
      tags = site.posts.docs.flat_map { |post| post.data['tags'] || [] }.to_set
      tags.each do |tag|
        site.pages << TagPage.new(site, site.source, tag)
      end
    end
  end

  class TagPage < Page
    def initialize(site, base, tag)
      @site = site
      @base = base
      @dir  = File.join('tag', tag)
      @name = 'index.html'

      self.process(@name)
      self.read_yaml(File.join(base, '_layouts'), 'tag.html')
      self.data['tag'] = tag
      self.data['title'] = "Tag: #{tag}"
    end
  end
end

My dream would be for Jekyll to scrape all posts and collection pages for tags and create tag pages listing posts and pages with the tag in question.

1 Like

All solutions I’m aware of involve creating pages manually—either one big archive page where all tags are automatically listed, or one page for each tag.

I know no Ruby, so I’d probably design something with all tags on one page. You can link to anchors for each tag (e.g. example.com/tag-archive#that-tag) and make it close to what you’re looking for. If you give each tag section a min-height of 100vh and lazy load images, some users may not even notice.

If you’re writing a plugin, jekyll-category-archive-plugin may be an inspiration. That one looks rather stale, but maybe it can even do what you need.

jekyll-paginate-v2’s Autopages feature can also be looked at for inspiration. It creates archive pages for categories, tags, and collections.

You can sort collections by custom variables if you are willing to create a custom page for each tag. This solution works if you need a few taxonomies and don’t need pagination.

Here is a sample code to sort through a single collection with custom variables:

1 Like

So, in the end I just modified the code above slightly to generate tag pages from all collections (including posts, so I’m excluding them in the layout “tag” referenced in the code):

module Jekyll
  class TagPageGenerator < Generator
    safe true

    def generate(site)
      tags = site.documents.flat_map { |post| post.data['tags'] || [] }.to_set
      tags.each do |tag|
        site.pages << TagPage.new(site, site.source, tag)
      end
    end
  end

  class TagPage < Page
    def initialize(site, base, tag)
      @site = site
      @base = base
      @dir  = File.join('tag', tag)
      @name = 'index.html'

      self.process(@name)
      self.read_yaml(File.join(base, '_layouts'), 'tag.html')
      self.data['tag'] = tag
      self.data['title'] = "Tag: #{tag}"
    end
  end
end

Any chance you can elaborate on how to implement your solution?

This page looks on topic: Tags in Jekyll

Also, I set this up for my site. See https://github.com/okjuan/vbook/blob/main/_plugins/generateTags.rb