From dc8eb631b691fe01828339d06c81a23f1a6c01ef Mon Sep 17 00:00:00 2001 From: Leyla Becker Date: Thu, 19 Feb 2026 19:05:21 -0600 Subject: [PATCH] feat: made tags nestable --- eleventy.config.js | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/eleventy.config.js b/eleventy.config.js index a9ac6bc..07da226 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -41,6 +41,19 @@ const extractTags = (content, mdInstance) => { return [...new Set(tags)]; } +const expandHierarchicalTags = (tags) => { + const expanded = new Set(); + tags.forEach(tag => { + expanded.add(tag); + const parts = tag.split('/'); + for (let i = 1; i < parts.length; i++) { + const parentTag = parts.slice(0, i).join('/'); + expanded.add(parentTag); + } + }); + return [...expanded]; +}; + const getPostTags = (post, tagMdInstance) => { const filePath = post.inputPath; try { @@ -275,7 +288,8 @@ module.exports = (eleventyConfig) => { const tagMap = {}; posts.forEach(post => { - const tags = getPostTags(post, tagExtractorMd) + const rawTags = getPostTags(post, tagExtractorMd); + const tags = expandHierarchicalTags(rawTags); tags.forEach((tag) => { tagMap[tag] = { name: tag, @@ -286,7 +300,7 @@ module.exports = (eleventyConfig) => { }); Object.values(tagMap).forEach(tagData => { - tagData.posts.sort((a, b) => { + tagData.posts = [...new Set(tagData.posts)].sort((a, b) => { const aDate = a.data.createdAt || a.date; const bDate = b.data.createdAt || b.date; return aDate - bDate; @@ -349,7 +363,9 @@ module.exports = (eleventyConfig) => { const postTags = posts.flatMap(post => getPostTags(post, tagExtractorMd)); const recipeTags = recipes.flatMap(recipe => getRecipeTags(recipe)); - return [...new Set([...postTags, ...recipeTags])].sort(); + const allTags = expandHierarchicalTags([...postTags, ...recipeTags]); + + return [...new Set(allTags)].sort(); }); eleventyConfig.addCollection("contentByTag", (collectionApi) => { @@ -363,9 +379,9 @@ module.exports = (eleventyConfig) => { return aDate - bDate; }; - // Build tag map from posts const postTagMap = posts.reduce((acc, post) => { - const tags = getPostTags(post, tagExtractorMd); + const rawTags = getPostTags(post, tagExtractorMd); + const tags = expandHierarchicalTags(rawTags); return tags.reduce((innerAcc, tag) => ({ ...innerAcc, [tag]: { @@ -376,9 +392,9 @@ module.exports = (eleventyConfig) => { }), acc); }, {}); - // Merge recipe tags into the tag map const tagMap = recipes.reduce((acc, recipe) => { - const tags = getRecipeTags(recipe); + const rawTags = getRecipeTags(recipe); + const tags = expandHierarchicalTags(rawTags); return tags.reduce((innerAcc, tag) => ({ ...innerAcc, [tag]: { @@ -389,12 +405,12 @@ module.exports = (eleventyConfig) => { }), acc); }, postTagMap); - // Return with sorted posts return Object.entries(tagMap).reduce((acc, [tag, tagData]) => ({ ...acc, [tag]: { ...tagData, - posts: [...tagData.posts].sort(sortByDate), + posts: [...new Set(tagData.posts)].sort(sortByDate), + recipes: [...new Set(tagData.recipes)], }, }), {}); });