Skip to content

Commit 3db5cac

Browse files
committed
refactor(website): generate /blog/ by scanning for files
The list of links on /blog/ is manually maintained. This is prone to mistakes; I could put the wrong title, or forget to link a post altogether. Generate the list of links on /blog/ by scanning the filesystem and reading the front matter.
1 parent e2886b4 commit 3db5cac

File tree

5 files changed

+48
-21
lines changed

5 files changed

+48
-21
lines changed

website/public/blog/bug-journey/index.ejs.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<!---{
22
"title": "Sometimes it *is* a compiler bug",
3+
"linkLabelHTML": "Sometimes it <em>is</em> a compiler bug",
34
"description": "My journey in finding and fixing a bug in a C++ toolchain",
45
"blogDate": "2022-05-25T21:04:02-07:00"
56
}--->

website/public/blog/index.ejs.html

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,40 @@
99
<head>
1010
<%- await include("../common-head.ejs.html") %> <%- await
1111
include("./blog-head.ejs.html") %>
12+
<script>
13+
//<%
14+
let ejs = await import("ejs");
15+
let fs = await import("node:fs");
16+
let path = await import("node:path");
17+
let { readFrontMatterFromFileAsync } = await importFileAsync("../../src/front-matter.mjs");
18+
19+
async function loadBlogPostsAsync() {
20+
let directories = await fs.promises.readdir(absoluteFilePath('.'), {withFileTypes: true});
21+
directories = directories.filter(dir => dir.isDirectory());
22+
let posts = await Promise.all(directories.map(async dir => {
23+
let indexPath = absoluteFilePath(path.join(dir.name, "index.ejs.html"));
24+
let meta = await readFrontMatterFromFileAsync(indexPath);
25+
if (typeof meta.blogDate === 'undefined') {
26+
throw new Error(`Missing blogDate in front matter of ${indexPath}`);
27+
}
28+
return {
29+
dir: dir.name,
30+
meta: meta,
31+
};
32+
}));
33+
sortPostsReverseChronologically(posts);
34+
return posts;
35+
}
36+
37+
function sortPostsReverseChronologically(posts) {
38+
posts.sort((a, b) => {
39+
if (a.meta.blogDate < b.meta.blogDate) return +1;
40+
if (a.meta.blogDate > b.meta.blogDate) return -1;
41+
return 0;
42+
});
43+
}
44+
//%>
45+
</script>
1246
<link href="../main.css" rel="stylesheet" />
1347
</head>
1448
<body class="side-bar-nav">
@@ -18,30 +52,13 @@
1852
<h2>quick-lint-js blog</h2>
1953

2054
<ul>
55+
<% for (let post of await loadBlogPostsAsync()) { %>
2156
<li>
22-
<a href="cpp-vs-rust-build-times/"
23-
>Is coding in Rust as bad as in C++?</a
24-
>
25-
</li>
26-
<li>
27-
<a href="bug-journey/">Sometimes it <em>is</em> a compiler bug</a>
28-
</li>
29-
<li>
30-
<a href="show-js-errors-neovim-macos/"
31-
>Show JavaScript errors in Neovim on macOS</a
32-
>
33-
</li>
34-
<li>
35-
<a href="version-2.0/">Release: version 2.0</a>
36-
</li>
37-
<li>
38-
<a href="version-1.0/">Release: version 1.0</a>
39-
</li>
40-
<li>
41-
<a href="syntax-errors-2021/"
42-
>JavaScript syntax errors compared (2021)</a
57+
<a href="<%= post.dir %>/"
58+
><%- post.meta.linkLabelHTML ?? ejs.escapeXML(post.meta.title) %></a
4359
>
4460
</li>
61+
<% } %>
4562
</ul>
4663
</main>
4764

website/public/blog/version-1.0/index.ejs.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<!---{
22
"title": "Faster, easier, friendlier: how quick-lint-js will take over ESLint",
3+
"linkLabelHTML": "Release: version 1.0",
34
"blogDate": "2021-12-13T19:27:37-08:00"
45
}--->
56

website/public/blog/version-2.0/index.ejs.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<!---{
22
"title": "Reacts rocks with quick-lint-js",
3+
"linkLabelHTML": "Release: version 2.0",
34
"blogDate": "2022-02-04T21:43:20-08:00"
45
}--->
56

website/src/front-matter.mjs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Copyright (C) 2020 Matthew "strager" Glazar
22
// See end of file for extended copyright information.
33

4+
import fs from "node:fs";
5+
46
// @returns { data: object, strippedHTML: string }
57
export function stripHTMLFrontMatter(html) {
68
let match = html.match(/^<!---(?<json>.*?)--->\n*/s);
@@ -17,6 +19,11 @@ export function stripHTMLFrontMatter(html) {
1719
};
1820
}
1921

22+
export async function readFrontMatterFromFileAsync(filePath) {
23+
let html = await fs.promises.readFile(filePath, "utf-8");
24+
return stripHTMLFrontMatter(html).data;
25+
}
26+
2027
// quick-lint-js finds bugs in JavaScript programs.
2128
// Copyright (C) 2020 Matthew "strager" Glazar
2229
//

0 commit comments

Comments
 (0)