import { HtmlBasePlugin } from "@11ty/eleventy"; import { eleventyImageTransformPlugin } from "@11ty/eleventy-img"; import pluginNavigation from "@11ty/eleventy-navigation"; import { attrs } from "@mdit/plugin-attrs"; import { markdownitLinkAttributes } from 'markdown-it-link-attributes'; import markdownitIdAttributes from "markdown-it-anchor"; import path from "node:path"; import { chunk } from "lodash-es"; import pluginFilters from "./_config/filters.js"; export default async function (eleventyConfig) { /* Markdown HTML attribute parsing */ eleventyConfig.amendLibrary("md", (mdLib) => mdLib.use(attrs)); /* Markdown apply target="_blank" to all external links */ eleventyConfig.amendLibrary("md", (mdLib) => mdLib.use(markdownitLinkAttributes, { matcher(href) { return href.match(/^https?:\/\//); }, attrs: { target: "_blank", rel: "external", }, })); /* Markdown apply ID attributes to headers */ eleventyConfig.amendLibrary("md", (mdLib) => mdLib.use(markdownitIdAttributes, { level: [2, 3, 4], tabIndex: false, })); /* Bundles */ /* CSS */ eleventyConfig.addBundle("css", { toFileDirectory: "dist", bundleHtmlContentFromSelector: "style", }); /* Javascript */ eleventyConfig.addBundle("js", { toFileDirectory: "dist", bundleHtmlContentFromSelector: "script", }); /* Paginate tags */ eleventyConfig.addCollection("doublePagination", function(collection) { // Get unique list of tags let tagSet = new Set(collection.getAllSorted().flatMap((post) => post.data.tags || [])); // Get each item that matches the tag let paginationSize = 20; let tagMap = []; let tagArray = [...tagSet]; for( let tagName of tagArray) { let tagItems = collection.getFilteredByTag(tagName); let pagedItems = chunk(tagItems.reverse(), paginationSize); // console.log( tagName, tagItems.length, pagedItems.length ); for( let pageNumber = 0, max = pagedItems.length; pageNumber < max; pageNumber++) { tagMap.push({ tagName: tagName, pageNumber: pageNumber, pageSize: pagedItems.length, pageData: pagedItems[pageNumber] }); } } //console.log( tagMap ); return tagMap; }); /* Passthroughs */ eleventyConfig .addPassthroughCopy("favicon.ico") .addPassthroughCopy("robots.txt"); /* HTML base */ eleventyConfig.addPlugin(HtmlBasePlugin); /* Images */ eleventyConfig.addPlugin(eleventyImageTransformPlugin, { // output image formats formats: ["auto"], // output image widths widths: ["auto"], // optional, attributes assigned on nodes override these values htmlOptions: { imgAttributes: { loading: "lazy", decoding: "async", }, }, filenameFormat: function (hash, src, width, format, options) { // If you're building multiple widths // const extension = path.extname(src); // const name = path.basename(src, extension); // return `${name}-${width}.${extension}`; return path.basename(src); }, }); /* Navigation */ eleventyConfig.addPlugin(pluginNavigation); /* All filters from _config/filters.js */ eleventyConfig.addPlugin(pluginFilters); /* Draft handling */ eleventyConfig.addPreprocessor("drafts", "*", (data, content) => { if (data.draft) { data.title = `${data.title} (draft)`; } if(data.draft && process.env.ELEVENTY_RUN_MODE === "build") { return false; } }); /* Shortcodes */ eleventyConfig.addShortcode("currentBuildDate", () => { return new Date().toISOString(); }); /* Watch when serving */ eleventyConfig.addWatchTarget("css"); } export const config = { dir: { input: "src", includes: "../_includes", layouts: "../_includes/layouts", data: "../_data", }, markdownTemplateEngine: "njk", htmlTemplateEngine: "njk", templateFormats: ["html", "md", "njk"], };