mirror of
https://codeberg.org/angestoepselt/homepage.git
synced 2025-05-24 14:46:16 +00:00
218 lines
5.3 KiB
JavaScript
218 lines
5.3 KiB
JavaScript
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) {
|
|
const siteName = process.env.SITE;
|
|
if (!siteName) {
|
|
throw 'Cannot determine the name of the site to build. Make sure to set the SITE environment variable.';
|
|
}
|
|
|
|
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) => `
|
|
<section class="page-section${inverted ? ' inverse' : ''}">
|
|
${content}
|
|
</section>
|
|
`
|
|
);
|
|
|
|
eleventyConfig.addPairedShortcode(
|
|
'tabs',
|
|
(content) => `
|
|
<div class="tabs-widget">
|
|
${content}
|
|
</div>
|
|
`
|
|
);
|
|
eleventyConfig.addPairedShortcode('tab', (content, title) => {
|
|
const hyphenizedTitle = hyphenize(title);
|
|
return `
|
|
<div id="${hyphenizedTitle}" class="tab">
|
|
${content}
|
|
</div>
|
|
<a href="#${hyphenizedTitle}" rel="tab">${title}</a>
|
|
`;
|
|
});
|
|
|
|
eleventyConfig.addPairedShortcode('timeline', (content, stamp) => {
|
|
return `
|
|
<section class="timeline">
|
|
<span class="stamp${stamp === undefined ? ' small' : ''}">
|
|
${stamp || ''}
|
|
</span>
|
|
<div class="content">
|
|
${content}
|
|
</div>
|
|
</section>
|
|
`;
|
|
});
|
|
|
|
eleventyConfig.addPairedAsyncShortcode(
|
|
'banner',
|
|
async (content, title, backgroundSource, backgroundAlt) => {
|
|
const backgroundMetadata = await Image(
|
|
`sites/${siteName}/_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 `
|
|
<div class="page-banner">
|
|
<div class="background">${backgroundHTML}</div>
|
|
<div class="content">
|
|
${title ? '<div class="title">' + title + '</div>' : ''}
|
|
${
|
|
// The '\n's here are required so that markdown still gets rendered in the
|
|
// content block:
|
|
content.trim() ? '<div>\n' + content + '\n</div>' : ''
|
|
}
|
|
</div>
|
|
</div>
|
|
`;
|
|
}
|
|
);
|
|
|
|
//
|
|
// 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({
|
|
assets: 'assets',
|
|
[`sites/${siteName}/_static`]: '.',
|
|
});
|
|
|
|
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: `sites/${siteName}`,
|
|
output: 'dist',
|
|
// These are all relative to the input directory so the paths get a little
|
|
// weird:
|
|
includes: '../../includes',
|
|
data: '_data',
|
|
},
|
|
|
|
templateFormats: ['md', 'njk', 'html', 'liquid'],
|
|
|
|
markdownTemplateEngine: 'njk',
|
|
htmlTemplateEngine: 'njk',
|
|
dataTemplateEngine: false,
|
|
};
|
|
};
|