]> Witch of Git - web/blog/blob - .eleventy.js
Remove console.log
[web/blog] / .eleventy.js
1 const pluginRss = require("@11ty/eleventy-plugin-rss");
2 const pluginSyntaxHighlight = require("@11ty/eleventy-plugin-syntaxhighlight");
3 const Nunjucks = require("nunjucks");
4 const nunjucksDate = require("nunjucks-date");
5 const md = require("markdown-it")();
6
7 module.exports = (eleventyConfig) => {
8 eleventyConfig.addNunjucksFilter('date', nunjucksDate);
9 eleventyConfig.addPlugin(pluginRss);
10 eleventyConfig.addPlugin(pluginSyntaxHighlight);
11
12 eleventyConfig.addPassthroughCopy("img");
13 eleventyConfig.addPassthroughCopy("static");
14
15 eleventyConfig.addNunjucksShortcode("youtube", youtubeShortcode);
16 eleventyConfig.addPairedNunjucksShortcode("tweet", tweetShortcode);
17
18 eleventyConfig.addFilter("markdown", value => md.renderInline(value));
19 eleventyConfig.addFilter("groupby", groupbyFilter);
20
21 eleventyConfig.addCollection("years", collection => {
22 const posts = collection.getFilteredByTag("posts");
23 const items = groupby(posts, item => item.date.getFullYear());
24 return items.reduce((obj, [k, v]) => (obj[k] = v, obj), {});
25 });
26
27 return {
28 markdownTemplateEngine: "njk",
29 };
30 };
31
32 function access(item, path) {
33 const segments = path.split(".");
34 for (const seg of segments) {
35 if (item === undefined) { return null; }
36 if (seg.endsWith("()")) {
37 const method = item[seg.slice(0, -2)];
38 if (method === undefined) { return null; }
39 item = method.bind(item)();
40 } else {
41 item = item[seg];
42 }
43 }
44 return item;
45 }
46
47 function groupby(items, keyFn) {
48 const results = [];
49 for (const item of items) {
50 const key = keyFn(item);
51 if (results.length == 0 || key != results[results.length-1][0]) {
52 results.push([key, [item]]);
53 } else {
54 results[results.length-1][1].push(item);
55 }
56 }
57 return results;
58 }
59
60 function groupbyFilter(items, path) {
61 return groupby(items, item => access(item, path));
62 }
63
64 function youtubeShortcode(items, inWidth, inHeight) {
65 const width = items.width || inWidth || 560;
66 const height = items.height || inHeight || 315;
67 const allow = items.allow || "accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
68 const border = items.border || "0";
69 const video = items.video || items;
70 if (!video) {
71 throw "Required argument 'video'.";
72 }
73 const src = "https://www.youtube.com/embed/" + video;
74 return `<div class="row flex-center">
75 <iframe width="${width}" height="${height}" src="${src}"
76 frameborder="${border}" allow="${allow}" allowfullscreen></iframe>
77 </div>`;
78 }
79
80 function tweetShortcode(content, items) {
81 // @TODO: Handle parsing date
82 return `<div class="row flex-center">
83 <blockquote class="twitter-tweet">
84 <p lang="en" dir="ltr">${content}</p> &mdash; ${items.name} (@${items.at})
85 <a href="${items.link}">${items.date}</a>
86 </blockquote>
87 <script async src="https://platform.twitter.com/widgets.js" charset="utf-8">
88 </script>
89 </div>`;
90 }