module.exports = function (eleventyConfig) { // Collection: all posts sorted by date descending eleventyConfig.addCollection("posts", function (collectionApi) { return collectionApi .getFilteredByGlob("src/blog/posts/**/*.md") .sort((a, b) => b.date - a.date); }); // Collection: about window content eleventyConfig.addCollection("aboutContent", (api) => api.getFilteredByGlob("src/content/about.md") ); // Collection: contact window content eleventyConfig.addCollection("contactContent", (api) => api.getFilteredByGlob("src/content/contact.md") ); // Collection: projects, sorted alphabetically by title eleventyConfig.addCollection("projects", (api) => api .getFilteredByGlob("src/projects/**/*.md") .filter((p) => !p.fileSlug.startsWith("_")) .sort((a, b) => a.data.title.localeCompare(b.data.title)) ); // Filter: human-readable date, e.g. "March 24, 2026" eleventyConfig.addFilter("readableDate", function (date) { return new Date(date).toLocaleDateString("en-US", { year: "numeric", month: "long", day: "numeric", }); }); // Filter: aggregate tags across a post collection // Returns [{tag, count}, ...] sorted by count desc, excluding "posts" eleventyConfig.addFilter("tagCounts", function (posts) { const counts = {}; for (const post of posts) { for (const tag of post.data.tags || []) { if (tag === "posts") continue; counts[tag] = (counts[tag] || 0) + 1; } } return Object.entries(counts) .map(([tag, count]) => ({ tag, count })) .sort((a, b) => b.count - a.count); }); // Pass through static assets eleventyConfig.addPassthroughCopy("src/assets"); return { dir: { input: "src", output: "_site", includes: "_includes", data: "_data", }, templateFormats: ["njk", "md", "html"], markdownTemplateEngine: "njk", htmlTemplateEngine: "njk", }; };