]>
Witch of Git - web/blog/blob - .eleventy.js
1 // @TODO: Update to the new virtual template setup?
2 const pluginRss
= require("@11ty/eleventy-plugin-rss");
3 const pluginSyntaxHighlight
= require("@11ty/eleventy-plugin-syntaxhighlight");
4 const Nunjucks
= require("nunjucks");
5 const dateFilter
= require("nunjucks-date-filter");
6 const uslug
= require("uslug");
7 const anchor
= require("markdown-it-anchor");
8 const md
= require("markdown-it")({
12 slugify
: s
=> uslug(s
),
14 permalinkBefore
: true,
15 permalinkClass
: "header-anchor c-sun dec-none",
17 const CleanCSS
= require("clean-css");
18 const htmlMinifier
= require("html-minifier-terser");
19 const util
= require("util");
21 module
.exports
= (eleventyConfig
) => {
22 eleventyConfig
.addNunjucksFilter('date', dateFilter
);
23 eleventyConfig
.addPlugin(pluginRss
);
24 eleventyConfig
.addPlugin(pluginSyntaxHighlight
);
26 eleventyConfig
.setLibrary("md", md
);
28 eleventyConfig
.addTransform("html-minifier", htmlMinifierTransform
);
30 eleventyConfig
.addPassthroughCopy("img");
31 eleventyConfig
.addPassthroughCopy("static");
32 eleventyConfig
.addPassthroughCopy("stamps");
33 eleventyConfig
.addPassthroughCopy({ "favicon": "/" });
35 eleventyConfig
.addNunjucksShortcode("youtube", youtubeShortcode
);
36 eleventyConfig
.addPairedNunjucksShortcode("tweet", tweetShortcode
);
37 eleventyConfig
.addPairedShortcode("aside", asideShortcode
);
38 eleventyConfig
.addPairedShortcode("figure", figureShortcode
);
40 eleventyConfig
.addFilter("markdown", value
=> md
.renderInline(value
));
41 eleventyConfig
.addFilter("groupby", groupbyFilter
);
42 eleventyConfig
.addFilter("cssmin", css
=>
43 new CleanCSS({}).minify(css
).styles
);
44 eleventyConfig
.addFilter("debug", util
.inspect
);
46 eleventyConfig
.setDataDeepMerge(true);
48 eleventyConfig
.addCollection("years", collection
=> {
49 const posts
= collection
.getFilteredByTag("posts");
50 const items
= groupby(posts
, item
=> item
.date
.getFullYear());
51 return items
.reduce((obj
, [k
, v
]) => (obj
[k
] = v
, obj
), {});
55 markdownTemplateEngine
: "njk",
59 function access(item
, path
) {
60 const segments
= path
.split(".");
61 for (const seg
of segments
) {
62 if (item
=== undefined) { return null; }
63 if (seg
.endsWith("()")) {
64 const method
= item
[seg
.slice(0, -2)];
65 if (method
=== undefined) { return null; }
66 item
= method
.bind(item
)();
74 function groupby(items
, keyFn
) {
76 for (const item
of items
) {
77 const key
= keyFn(item
);
78 if (results
.length
== 0 || key
!= results
[results
.length
-1][0]) {
79 results
.push([key
, [item
]]);
81 results
[results
.length
-1][1].push(item
);
87 function groupbyFilter(items
, path
) {
88 return groupby(items
, item
=> access(item
, path
));
91 function youtubeShortcode(items
, inWidth
= 560, inHeight
= 315) {
92 const width
= items
.width
|| inWidth
;
93 const height
= items
.height
|| inHeight
;
94 const allow
= items
.allow
|| "accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
95 const border
= items
.border
|| "0";
96 const video
= items
.video
|| items
;
98 throw "Required argument 'video'.";
100 const src
= "https://www.youtube.com/embed/" + video
;
101 return `<div class="youtube row hcenter">
102 <iframe width="${width}" height="${height}" src="${src}"
103 frameborder="${border}" allow="${allow}" allowfullscreen></iframe>
107 function tweetShortcode(content
, items
) {
108 // @TODO: Handle parsing date
109 return `<div class="row hcenter">
110 <blockquote class="twitter-tweet">
111 <p lang="en" dir="ltr">${content}</p> — ${items.name} (@${items.at})
112 <a href="${items.link}">${items.date}</a>
114 <script async src="https://platform.twitter.com/widgets.js" charset="utf-8">
119 function asideShortcode(content
, style
='') {
120 const html
= md
.render(content
);
122 return `<aside class="${style}">${html}</aside>`;
124 return `<aside>${html}</aside>`;
128 function figureShortcode(content
, { src
, alt
}) {
129 const captionHtml
= md
.render(content
);
130 return `<figure class="col hcenter">
131 <img src="${src}" alt="${alt}">
132 <figcaption>${captionHtml}</figcaption>
136 function htmlMinifierTransform(content
, outputPath
) {
137 if (outputPath
.endsWith(".html")) {
138 return htmlMinifier
.minify(content
, {
139 useShortDoctype
: true,
140 removeComments
: true,
141 collapseWhitespace
: true,