-
-
Notifications
You must be signed in to change notification settings - Fork 227
Expand file tree
/
Copy patheleventy.config.js
More file actions
118 lines (103 loc) · 4.01 KB
/
Copy patheleventy.config.js
File metadata and controls
118 lines (103 loc) · 4.01 KB
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
import { feedPlugin } from "@11ty/eleventy-plugin-rss";
import syntaxHighlight from "@11ty/eleventy-plugin-syntaxhighlight";
export default async function (eleventyConfig) {
eleventyConfig.addPlugin(syntaxHighlight);
eleventyConfig.addPlugin(feedPlugin, {
type: "atom",
outputPath: "/blog/feed.xml",
collection: { name: "posts", limit: 20 },
metadata: {
language: "en",
title: "WhatCable Blog",
subtitle:
"USB-C cables, Thunderbolt, and the deep weeds of port diagnostics.",
base: "https://www.whatcable.uk/blog/",
author: {
name: "Darryl Morley",
},
},
});
eleventyConfig.addFilter("stripDatePrefix", (slug) =>
String(slug).replace(/^\d{4}-\d{2}-\d{2}-/, "")
);
eleventyConfig.addFilter("cleanUrl", (url) => {
const u = String(url);
if (u === "/") return "/";
// Strip .html extension (posts now output as filename.html) then trailing slash.
return u.replace(/\.html$/, "").replace(/\/$/, "");
});
// Treat "now", null, and undefined as today so templates can render
// a build-time stamp without juggling Date objects in frontmatter.
const resolveDate = (date) => {
if (date == null || date === "now") return new Date();
return new Date(date);
};
eleventyConfig.addFilter("isoDate", (date) => resolveDate(date).toISOString());
eleventyConfig.addFilter("readableDate", (date) =>
resolveDate(date).toLocaleDateString("en-GB", {
year: "numeric",
month: "long",
day: "numeric",
})
);
// Capture Eleventy's bundled markdown-it instance so we can render arbitrary
// markdown strings (e.g. FAQ answers from a post's frontmatter) using the
// same config as the post body.
let mdLib = null;
eleventyConfig.amendLibrary("md", (md) => {
mdLib = md;
});
eleventyConfig.addFilter("markdownify", (str) => {
if (!str) return "";
return mdLib ? mdLib.render(String(str)) : String(str);
});
// Escape any </script> sequence inside a string that's about to be inlined
// into a <script type="application/ld+json"> block. JSON itself doesn't
// require this, but the browser's HTML parser will close the script tag
// early if it sees the literal sequence anywhere in the content.
eleventyConfig.addFilter("jsonLdSafe", (str) =>
String(str || "").replace(/<\/(script)/gi, "<\\/$1")
);
eleventyConfig.addCollection("posts", (api) =>
api
.getFilteredByGlob("./src/blog/posts/**/*.md")
.sort((a, b) => b.date - a.date)
);
// Wrap every <table> in a scrollable div so wide tables don't blow out the
// layout on narrow screens. The markdown renderer can't add wrapper markup
// directly, so this transform does it as a post-processing step on HTML.
eleventyConfig.addTransform("wrapTables", function (content) {
if (!this.page.outputPath?.endsWith(".html")) return content;
return content
.replace(/<table/g, '<div class="table-wrap"><table')
.replace(/<\/table>/g, "</table></div>");
});
eleventyConfig.addTransform("stripFeedTrailingSlashes", function (content) {
if (!this.page.outputPath || !this.page.outputPath.endsWith("feed.xml")) {
return content;
}
return content
.replace(/(https?:\/\/[^\s"<>]+?)\.html(?=["<\s])/g, "$1")
.replace(/(https?:\/\/[^\s"<>]+?)\/(?=["<\s])/g, "$1");
});
eleventyConfig.addPassthroughCopy("src/icon.png");
eleventyConfig.addPassthroughCopy("src/CNAME");
eleventyConfig.addPassthroughCopy("src/robots.txt");
eleventyConfig.addPassthroughCopy("src/screenshot*.webp");
eleventyConfig.addPassthroughCopy("src/press");
// Decap CMS lives at /admin. Copy it verbatim (no Nunjucks pass), so the
// HTML/JS isn't accidentally parsed if it ever contains brace-heavy code.
eleventyConfig.ignores.add("src/admin/**");
eleventyConfig.addPassthroughCopy("src/admin");
return {
dir: {
input: "src",
output: "docs",
includes: "_includes",
layouts: "_layouts",
data: "_data",
},
markdownTemplateEngine: "njk",
htmlTemplateEngine: "njk",
};
}