]>
Witch of Git - web/blog/blob - .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")();
7 module
.exports
= (eleventyConfig
) => {
8 eleventyConfig
.addNunjucksFilter('date', nunjucksDate
);
9 eleventyConfig
.addPlugin(pluginRss
);
10 eleventyConfig
.addPlugin(pluginSyntaxHighlight
);
12 eleventyConfig
.addPassthroughCopy("img");
13 eleventyConfig
.addPassthroughCopy("static");
15 eleventyConfig
.addNunjucksShortcode("youtube", youtubeShortcode
);
16 eleventyConfig
.addPairedNunjucksShortcode("tweet", tweetShortcode
);
18 eleventyConfig
.addFilter("markdown", value
=> md
.renderInline(value
));
19 eleventyConfig
.addFilter("groupby", groupbyFilter
);
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
), {});
28 markdownTemplateEngine
: "njk",
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
)();
47 function groupby(items
, keyFn
) {
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
]]);
54 results
[results
.length
-1][1].push(item
);
60 function groupbyFilter(items
, path
) {
61 return groupby(items
, item
=> access(item
, path
));
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
;
71 throw "Required argument 'video'.";
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>
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> — ${items.name} (@${items.at})
85 <a href="${items.link}">${items.date}</a>
87 <script async src="https://platform.twitter.com/widgets.js" charset="utf-8">