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"],
};