-
Notifications
You must be signed in to change notification settings - Fork 0
/
.eleventy.js
141 lines (120 loc) · 4.35 KB
/
.eleventy.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
const { DateTime } = require("luxon");
const yaml = require("js-yaml");
const matter = require("gray-matter");
const markdownIt = require("markdown-it");
const markdownItAnchor = require("markdown-it-anchor");
const markdownItFootnote = require("markdown-it-footnote");
// @ts-ignore Third-party types being incomplete is not my problem right now
const { EleventyHtmlBasePlugin } = require("@11ty/eleventy");
const pluginRss = require("@11ty/eleventy-plugin-rss");
const syntaxHighlight = require("@11ty/eleventy-plugin-syntaxhighlight");
const seriesPlugin = require("./src/_lib/series");
const cloudinaryOGPlugin = require("./src/_lib/cloudinary");
const siteConfig = require("./src/_data/config");
const colors = require("./styles/colors");
module.exports = function (eleventyConfig) {
// 11ty plugins
eleventyConfig.addPlugin(EleventyHtmlBasePlugin);
eleventyConfig.addPlugin(pluginRss);
eleventyConfig.addPlugin(syntaxHighlight);
// My own plugins
eleventyConfig.addPlugin(seriesPlugin);
eleventyConfig.addPlugin(cloudinaryOGPlugin, {
cloudinaryId: siteConfig.cloudinary.id,
accentColor: colors.pank.DEFAULT,
});
// Extend markdown transformation with permalinks and footnotes support
eleventyConfig.amendLibrary("md", (mdLib) => mdLib.use(markdownItFootnote));
eleventyConfig.amendLibrary("md", (mdLib) =>
mdLib.use(markdownItAnchor, {
// @ts-ignore Missing third-party typing on `permalink` prop
permalink: markdownItAnchor.permalink.headerLink({
class: "markdown-it-anchor-permalink",
safariReaderFix: true,
}),
}),
);
// Add YAML support
eleventyConfig.addDataExtension("yaml", (contents) => yaml.load(contents));
// Necessary because `_tmp_ is gitignored and 11ty won't see it otherwise
// TODO: validate this
eleventyConfig.setUseGitIgnore(false);
// Build config
// Everything in src/public will pass through to _site
eleventyConfig.addPassthroughCopy({ "./src/public/": "/" });
// Styles
eleventyConfig.addWatchTarget("./_tmp/styles.css");
eleventyConfig.addPassthroughCopy({ "./_tmp/styles.css": "./styles.css" });
// Templating config
eleventyConfig.setNunjucksEnvironmentOptions({
throwOnUndefined: true,
autoescape: false,
});
const md = new markdownIt({
html: true,
});
// Add a custom shortcode to render the content as markdown, after first
// parsing out any front matter
eleventyConfig.addPairedShortcode("markdown", (content) => {
return md.render(matter(content).content);
});
// Custom date filters
eleventyConfig.addFilter("localeDate", (dateObj) => {
return DateTime.fromJSDate(dateObj, { zone: "utc" }).toLocaleString(
DateTime.DATE_MED,
);
});
eleventyConfig.addFilter("formatDate", (dateObj, format = "LLL dd, yyyy") => {
return DateTime.fromJSDate(dateObj).toFormat(format);
});
// These tags should not be shown when rendering blog-post tags
const excludedPostTags = ["all", "posts"];
const filterTags = (itemTags, disallowedTags = excludedPostTags) => {
return itemTags.filter((tag) => {
for (const disallowed of disallowedTags) {
// string comparison being speedier than `.match` if it's not a RegExp
if (typeof disallowed === "string" && tag === disallowed) {
return false;
} else if (tag.match(disallowed)) {
return false;
}
}
return true;
});
};
// Filter out excludedPostTags from an array of tags
eleventyConfig.addFilter("postTags", filterTags);
// Custom filter: Return all the tags used in a collection, with counts
// of how many items in the collection use each tag, sorted by count desc
eleventyConfig.addFilter("getAllTagsWithCount", (collection) => {
const tags = [];
for (let item of collection) {
const postTags = filterTags(item.data.tags || []);
postTags.forEach((tag) => {
const existingTag = tags.find((el) => el.tag === tag);
if (existingTag) {
existingTag.count++;
} else {
tags.push({ tag, count: 1 });
}
});
}
// Sort by count, descending
tags.sort((a, b) => {
if (a.count < b.count) {
return 1;
} else if (a.count > b.count) {
return -1;
}
return 0;
});
return tags;
});
// Config directories
return {
dir: {
input: "src",
includes: "_includes",
},
};
};