const { DateTime } = require('luxon') const fs = require('fs').promises const path = require('path') const pluginRss = require('@11ty/eleventy-plugin-rss') const pluginSyntaxHighlight = require('@11ty/eleventy-plugin-syntaxhighlight') const pluginNavigation = require('@11ty/eleventy-navigation') const markdownIt = require('markdown-it') const markdownItAnchor = require('markdown-it-anchor') const createHash = require('crypto').createHash const pluginImage = require('@11ty/eleventy-img') // Widths in pixels of responsive images to be generated const IMAGE_SIZES = [300, 600, 900, 1200] const dirs ={ input: '_src', includes: '_includes', data: '_data', output: '_site', } module.exports = (eleventyConfig) => { eleventyConfig.setServerOptions({ liveReload: false, }) // Add plugins eleventyConfig.addPlugin(pluginRss) eleventyConfig.addPlugin(pluginSyntaxHighlight) eleventyConfig.addPlugin(pluginNavigation) // https://www.11ty.dev/docs/data-deep-merge/ eleventyConfig.setDataDeepMerge(true) // Alias `layout: post` to `layout: layouts/post.njk` eleventyConfig.addLayoutAlias('post', 'layouts/post.njk') eleventyConfig.addFilter('readableDate', dateObj => DateTime.fromJSDate(dateObj, {zone: 'utc'}).toFormat('dd LLL yyyy') ) // https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-date-string eleventyConfig.addFilter('htmlDateString', (dateObj) => DateTime.fromJSDate(dateObj, {zone: 'utc'}).toFormat('yyyy-LL-dd') ) // Get the first `n` elements of a collection. eleventyConfig.addFilter('head', (array, n) => (n<0)? array.slice(n): array.slice(0, n) ) // Sanitize out apostrophes eleventyConfig.addFilter('noApostrophes', (str) => str.replace(/['"]+/g,'') ) // Return the smallest number argument eleventyConfig.addFilter('min', (...numbers) => Math.min.apply(null, numbers) ) eleventyConfig.addFilter('toFixed', (num,digits) => num? num.toFixed(digits) : '' ) eleventyConfig.addFilter('srintegrity', async (asset,bits=256) => `sha${String(bits)}-` + createHash(`sha${String(bits)}`) .update(await fs.readFile(`${dirs.input}${asset}`)) .digest('base64') ) eleventyConfig.addFilter('filterCatList', cats => // should match the list in categories.njk (cats || []).filter(cat => ['all','nav','post','posts'].indexOf(cat) === -1) ) eleventyConfig.addFilter('filterTagList', tags => // should match the list in tags.njk (tags || []).filter(tag => ['all','nav','post','posts'].indexOf(tag) === -1) ) eleventyConfig.addFilter('dimsToVol', (dims) => { return { in3: Object.values(dims.in).reduce((a,c) => a*c, 1) } } ) // Create an array of all tags eleventyConfig.addCollection('tagList', function(collection) { let tagSet = new Set() collection.getAll().forEach(item => { (item.data.tags || []).forEach(tag => tagSet.add(tag)) }); return [...tagSet]; }) // Markdown "md" filter for nunjucks // https://github.com/11ty/eleventy/issues/658#issuecomment-599173643 const mdFilter = new markdownIt({html:true}) eleventyConfig.addPairedShortcode('md', (content) => mdFilter.render(content) ) // Override Browsersync defaults (used only with --serve) eleventyConfig.setBrowserSyncConfig({ callbacks: { ready: function(err, browserSync) { const content_404 = fs.readFileSync('_site/404.html') browserSync.addMiddleware('*', (req, res) => { // Provides the 404 content without redirect. res.writeHead(404, { 'Content-Type': 'text/html; charset=UTF-8' }) res.write(content_404) res.end() }); }, }, ui: false, ghostMode: false, }) eleventyConfig.addPassthroughCopy('_src/assets/fonts') eleventyConfig.addPassthroughCopy('_src/assets/base.css') eleventyConfig.addPassthroughCopy('_src/assets/shop.css') eleventyConfig.addPassthroughCopy('_src/assets/site.webmanifest') eleventyConfig.addPassthroughCopy('_src/assets/scripts') // Optimized images // https://www.11ty.dev/docs/plugins/image/#make-your-own-markup eleventyConfig.addShortcode('image', async (src, alt) => { const metadata = await pluginImage(`./_src${src}`, { widths: [...IMAGE_SIZES, 'auto'], formats: ['auto', 'webp', 'avif'], // https://www.11ty.dev/docs/plugins/image/#custom-filenames filenameFormat: (id, src, width, format) => `${path.basename(src,path.extname(src))}-${width}w.${format}`, // https://alexpeterhall.com/blog/2021/04/05/responsive-images-eleventy/#eleventy-configuration urlPath: path.dirname(src), outputDir: `_site/${path.dirname(src)}`, }) const lowsrc = metadata.webp[0] const highsrc = metadata.webp[metadata.webp.length - 1] return `${Object.values(metadata).map(imageFormat => `\t`).join('')}${alt}` }) // Video embed eleventyConfig.addShortcode('vid', (src, autoplay=false) => `` ) eleventyConfig.addShortcode('vidraw', (src) => `` ) // YouTube eleventyConfig.addShortcode('yt', (shortcode) => `` ) // Audio embed eleventyConfig.addShortcode('audio', (src, fmt) => `` ) // iFrame eleventyConfig.addShortcode('iframe', (url, height) => `