const fs = require('fs'); const { DateTime } = require('luxon'); const pluginRss = require('@11ty/eleventy-plugin-rss'); const pluginSyntaxHighlight = require('@11ty/eleventy-plugin-syntaxhighlight'); const pluginNavigation = require('@11ty/eleventy-navigation'); const Image = require('@11ty/eleventy-img'); const markdownIt = require('markdown-it'); const markdownItAnchor = require('markdown-it-anchor'); const markdownItAttrs = require('markdown-it-attrs'); function hyphenize(input) { return input .replace(/[^\w- ]/, '') .replace(/[_ ]/, '-') .toLowerCase(); } module.exports = function (eleventyConfig) { eleventyConfig.addPlugin(pluginRss); eleventyConfig.addPlugin(pluginSyntaxHighlight); eleventyConfig.addPlugin(pluginNavigation); eleventyConfig.setDataDeepMerge(true); // // Filters // eleventyConfig.addFilter('readableDate', (dateObj) => { return DateTime.fromJSDate(dateObj, { zone: 'utc' }).toFormat( 'dd LLL yyyy' ); }); eleventyConfig.addFilter('htmlDateString', (dateObj) => { return DateTime.fromJSDate(dateObj, { zone: 'utc' }).toFormat('yyyy-LL-dd'); }); eleventyConfig.addFilter('head', (array, n) => n < 0 ? array.slice(n) : array.slice(0, n) ); eleventyConfig.addFilter('min', (...numbers) => Math.min.apply(null, numbers) ); function filterTagList(tags) { return (tags || []).filter( (tag) => ['all', 'nav', 'post', 'posts'].indexOf(tag) === -1 ); } eleventyConfig.addFilter('filterTagList', filterTagList); // Build collections for the top and bottom navigation - the first one // contains the main sites and the latter contains legal pages. eleventyConfig.addCollection('topNavigation', (collection) => { return collection .getAll() .filter((item) => !(item.data.tags || []).includes('legal')); }); eleventyConfig.addCollection('bottomNavigation', (collection) => { return collection .getAll() .filter((item) => (item.data.tags || []).includes('legal')); }); eleventyConfig.addCollection('posts', (collection) => { return collection.getAll().filter((item) => item.data.layout === 'post'); }); // // Widgets // eleventyConfig.addPairedShortcode( 'section', (content, inverted) => `
${content}
` ); eleventyConfig.addPairedShortcode( 'tabs', (content) => `
${content}
` ); eleventyConfig.addPairedShortcode('tab', (content, title) => { const hyphenizedTitle = hyphenize(title); return `
${content}
${title} `; }); eleventyConfig.addPairedShortcode('timeline', (content, stamp) => { return `
${stamp || ''}
${content}
`; }); eleventyConfig.addPairedAsyncShortcode( 'banner', async (content, title, backgroundSource, backgroundAlt) => { const backgroundMetadata = await Image(`src/images/${backgroundSource}`, { widths: [1200, 1980, 4000], formats: ['avif', 'webp', 'jpeg'], urlPath: '/assets/img', outputDir: './dist/assets/img', sharpAvifOptions: { quality: 40 }, sharpWebpOptions: { quality: 50 }, sharpJpegOptions: { quality: 65 }, }); const backgroundHTML = Image.generateHTML(backgroundMetadata, { alt: backgroundAlt, sizes: '100vw', loading: 'lazy', decoding: 'async', whitespaceMode: 'inline', }); return `
${backgroundHTML}
${title ? '
' + title + '
' : ''} ${ // The '\n's here are required so that markdown still gets rendered in the // content block: content.trim() ? '
\n' + content + '\n
' : '' }
`; } ); // // Templating // eleventyConfig.addLayoutAlias('page', 'layouts/page.njk'); eleventyConfig.addLayoutAlias('post', 'layouts/post.njk'); let markdownLibrary = markdownIt({ html: true, breaks: false, linkify: true, }) .use(markdownItAnchor) .use(markdownItAttrs); eleventyConfig.setLibrary('md', markdownLibrary); // // Build settings // eleventyConfig.addPassthroughCopy({ 'src/assets': 'assets' }); eleventyConfig.setBrowserSyncConfig({ callbacks: { ready: function (err, browserSync) { const content_404 = fs.readFileSync('dist/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, }); // // Other settings // return { dir: { input: 'src/content', // These are all relative to the input directory so the paths get a little // weird: includes: '../includes', data: '../data', output: 'dist', }, templateFormats: ['md', 'njk', 'html', 'liquid'], markdownTemplateEngine: 'njk', htmlTemplateEngine: 'njk', dataTemplateEngine: false, }; };