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.
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.
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:
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