on master help sign in
build: re-structure buildPageTree as a prebuild script
commitbdd41e71857213fa4716e53969a67d393b1a9189 authorMatilde Park <matilde.park@urbit.org> dateThu 5 May 2022, 16:13 (4 years ago) parent8c5855b
8 files changed+142−116
lib/buildPageTree.js+110 lib/lib.js−70 package.json+9−3 pages/community/[[...slug]].js+5−9 pages/docs/[[...slug]].js+4−8 pages/getting-started/[[...slug]].js+5−9 pages/understanding-urbit/[[...slug]].js+5−14 pages/using/[[...slug]].js+4−3
lib/buildPageTree.jsnew file+110
@@ -0,0 +1,110 @@
1+const fs = require("fs");
2+const path = require("path");
3+const matter = require("gray-matter");
4+const toml = require("@iarna/toml");
5+
6+// node ./buildPageTree.js [directory] [sort]
7+// eg. node ./buildPageTree docs weight
8+// will produce docs.json in the cache folder.
9+
10+const options = {
11+ engines: {
12+ toml: toml.parse.bind(toml),
13+ },
14+ language: "toml",
15+ delimiters: "+++",
16+};
17+
18+/**
19+ * buildPageTree is written to provide a recursive index of posts
20+ * for nested directories for creating sidebars
21+ * @param {string} path Absolute path to the subdirectory.
22+ * @returns {Object.<string,string|Object<string,string[]|number>>} Title of the directory, child pages, and child directories (recursive structure).
23+ *
24+ */
25+
26+// type PageTree =
27+// { title: string,
28+// pages: [{
29+// title: string,
30+// base: string,
31+// slug: string,
32+// weight: number,
33+// }],
34+// children: { [string]: PageTree },
35+// }
36+
37+function buildPageTree(dirPath, ordering = "", content = false) {
38+ const metadata = matter(
39+ fs.readFileSync(path.join(dirPath, "_index.md")),
40+ options
41+ );
42+ // get a list of contents at the dirPath, with file types so that the item at the dirPath can be identified as file or folder
43+ const children = fs.readdirSync(dirPath, { withFileTypes: true });
44+ // get a list of files
45+ const pages = children.filter((f) => f.isFile() && f.name !== "_index.md");
46+ // get a list of folders
47+ const subdirs = children.filter((f) => f.isDirectory());
48+ // return a pagetree datastructure
49+ return {
50+ title: metadata.data.title,
51+ pages: pages
52+ .map((page) => {
53+ // retrieve topmatter as JSON
54+ const { content, data } = matter(
55+ fs.readFileSync(path.join(dirPath, page.name)),
56+ options
57+ );
58+
59+ return {
60+ title: data.title,
61+ base: page.name,
62+ slug: page.name.replace(/.md$/, ""),
63+ ...(ordering === "weight" && { weight: data?.weight ?? 0 }),
64+ ...(ordering === "date" && {
65+ date: data?.date ?? "2000-01-01T00:00:00.000Z",
66+ }),
67+ };
68+ })
69+ .sort((a, b) => a.weight - b.weight),
70+ children: Object.fromEntries(
71+ subdirs
72+ .sort((a, b) => {
73+ const aMetadata = matter(
74+ fs.readFileSync(path.join(dirPath, a.name, "_index.md")),
75+ options
76+ );
77+ const bMetadata = matter(
78+ fs.readFileSync(path.join(dirPath, b.name, "_index.md")),
79+ options
80+ );
81+ return aMetadata?.data?.weight - bMetadata?.data?.weight || 0;
82+ })
83+ .map((subdir) => [
84+ subdir.name,
85+ buildPageTree(path.join(dirPath, subdir.name), ordering, content),
86+ ])
87+ ),
88+ };
89+}
90+
91+const process = require("process");
92+
93+const arg = process.argv?.[2];
94+const sort = process?.argv?.[3] || "weight";
95+
96+const dir = buildPageTree(path.join(process.cwd(), `content/${arg}`), sort);
97+const fileContents = `${JSON.stringify(dir)}`;
98+
99+try {
100+ fs.readdirSync("cache");
101+} catch (err) {
102+ fs.mkdirSync("cache");
103+}
104+
105+fs.writeFile(`cache/${arg}.json`, fileContents, function (err) {
106+ if (err) return console.error(err);
107+ console.log(`${arg} directory structure created.`);
108+});
109+
110+module.exports = { buildPageTree };
lib/lib.js−70
@@ -198,76 +198,6 @@ export function formatDate(dateTimeObject) {
198198// }))
199199// }
200200
201−/**
202− * buildPageTree is written to provide a recursive index of posts
203− * for nested directories for creating sidebars
204− * @param {string} path Absolute path to the subdirectory.
205− * @returns {Object.<string,string|Object<string,string[]|number>>} Title of the directory, child pages, and child directories (recursive structure).
206− *
207− */
208−
209−// type PageTree =
210−// { title: string,
211−// pages: [{
212−// title: string,
213−// base: string,
214−// slug: string,
215−// weight: number,
216−// }],
217−// children: { [string]: PageTree },
218−// }
219−
220−export function buildPageTree(path, ordering = "", content = false) {
221− const metadata = matter(fs.readFileSync(join(path, "_index.md")), options);
222− // get a list of contents at the path, with file types so that the item at the path can be identified as file or folder
223− const children = fs.readdirSync(path, { withFileTypes: true });
224− // get a list of files
225− const pages = children.filter((f) => f.isFile() && f.name !== "_index.md");
226− // get a list of folders
227− const subdirs = children.filter((f) => f.isDirectory());
228− // return a pagetree datastructure
229− return {
230− title: metadata.data.title,
231− pages: pages
232− .map((page) => {
233− // retrieve topmatter as JSON
234− const { content, data } = matter(
235− fs.readFileSync(join(path, page.name)),
236− options
237− );
238−
239− return {
240− title: data.title,
241− base: page.name,
242− slug: page.name.replace(/.md$/, ""),
243− ...(ordering === "weight" && { weight: data?.weight ?? 0 }),
244− ...(ordering === "date" && {
245− date: data?.date ?? "2000-01-01T00:00:00.000Z",
246− }),
247− };
248− })
249− .sort((a, b) => a.weight - b.weight),
250− children: Object.fromEntries(
251− subdirs
252− .sort((a, b) => {
253− const aMetadata = matter(
254− fs.readFileSync(join(path, a.name, "_index.md")),
255− options
256− );
257− const bMetadata = matter(
258− fs.readFileSync(join(path, b.name, "_index.md")),
259− options
260− );
261− return aMetadata?.data?.weight - bMetadata?.data?.weight || 0;
262− })
263− .map((subdir) => [
264− subdir.name,
265− buildPageTree(join(path, subdir.name), ordering, content),
266− ])
267− ),
268− };
269−}
270−
271201export const getPage = (path) => {
272202 try {
273203 let fileContents = fs.readFileSync(`${path}.md`, "utf8");
package.json+9−3
@@ -3,11 +3,17 @@
33 "version": "0.1.0",
44 "private": true,
55 "scripts": {
6− "dev": "npm run cache-posts && npm run rss && next dev",
7− "build": "npm run cache-posts && npm run rss && next build",
8− "export": "npm run cache-posts && npm run rss && next build && next export",
6+ "dev": "npm run prebuild && next dev",
7+ "build": "next build",
8+ "export": "npm run prebuild && next build && next export",
99 "start": "next start",
1010 "prepare": "husky install",
11+ "prebuild": "npm run cache-posts && npm run rss && npm run community-tree && npm run docs-tree && npm run getting-started-tree && npm run understanding-urbit-tree && npm run using-tree",
12+ "community-tree": "node lib/buildPageTree community weight",
13+ "docs-tree": "node lib/buildPageTree docs weight",
14+ "getting-started-tree": "node lib/buildPageTree getting-started weight",
15+ "understanding-urbit-tree": "node lib/buildPageTree understanding-urbit weight",
16+ "using-tree": "node lib/buildPageTree using weight",
1117 "cache-posts": "node lib/cache.js",
1218 "rss": "node lib/rss.js"
1319 },
pages/community/[[...slug]].js+5−9
@@ -4,12 +4,13 @@ import { useRouter } from "next/router";
44import { useState } from "react";
55import classnames from "classnames";
66import { join } from "path";
7−import { getDocs, formatDate, buildPageTree, getPage } from "../../lib/lib";
7+import { getDocs, formatDate, getPage } from "../../lib/lib";
88import Meta from "../../components/Meta";
99import Markdown from "../../components/Markdown";
1010import ContentArea from "../../components/ContentArea";
1111import Sidebar from "../../components/Sidebar";
1212import { decode } from "html-entities";
13+import communityTree from "../../cache/community.json";
1314
1415const breadcrumbs = (posts, paths) => {
1516 const results = [
@@ -89,10 +90,7 @@ export default function UsingLayout({ posts, data, params, search, markdown }) {
8990}
9091
9192export async function getStaticProps({ params }) {
92− const posts = buildPageTree(
93− join(process.cwd(), "content/community"),
94− "weight"
95− );
93+ const posts = communityTree;
9694
9795 const { data, content } = getPage(
9896 join(process.cwd(), "content/community", params.slug?.join("/") || "/")
@@ -104,10 +102,8 @@ export async function getStaticProps({ params }) {
104102}
105103
106104export async function getStaticPaths() {
107− const posts = buildPageTree(
108− join(process.cwd(), "content/community"),
109− "weight"
110− );
105+ const posts = communityTree;
106+
111107 const slugs = [];
112108
113109 const allHrefs = (thisLink, tree) => {
pages/docs/[[...slug]].js+4−8
@@ -4,17 +4,13 @@ import { useRouter } from "next/router";
44import { useState, useEffect, useRef } from "react";
55import classnames from "classnames";
66import { join } from "path";
7−import {
8− getPreviousPost,
9− getNextPost,
10− buildPageTree,
11− getPage,
12−} from "../../lib/lib";
7+import { getPreviousPost, getNextPost, getPage } from "../../lib/lib";
138import Meta from "../../components/Meta";
149import Pagination from "../../components/Pagination";
1510import Markdown from "../../components/Markdown";
1611import ContentArea from "../../components/ContentArea";
1712import Sidebar from "../../components/Sidebar";
13+import docsPageTree from "../../cache/docs.json";
1814
1915import { decode } from "html-entities";
2016
@@ -193,7 +189,7 @@ export default function DocsLayout({
193189}
194190
195191export async function getStaticProps({ params }) {
196− const posts = buildPageTree(join(process.cwd(), "content/docs"), "weight");
192+ const posts = docsPageTree;
197193
198194 const { data, content } = getPage(
199195 join(process.cwd(), "content/docs", params.slug?.join("/") || "/")
@@ -221,7 +217,7 @@ export async function getStaticProps({ params }) {
221217}
222218
223219export async function getStaticPaths() {
224− const posts = buildPageTree(join(process.cwd(), "content/docs"), "weight");
220+ const posts = docsPageTree;
225221 const slugs = [];
226222
227223 const allHrefs = (thisLink, tree) => {
pages/getting-started/[[...slug]].js+5−9
@@ -4,10 +4,11 @@ import Link from "next/link";
44import { useRouter } from "next/router";
55import classnames from "classnames";
66import { join } from "path";
7−import { buildPageTree, getPage } from "../../lib/lib";
7+import { getPage } from "../../lib/lib";
88import Markdown from "../../components/Markdown";
99import ContentArea from "../../components/ContentArea";
1010import Sidebar from "../../components/Sidebar";
11+import GettingStartedTree from "../../cache/getting-started.json";
1112
1213import { decode } from "html-entities";
1314
@@ -108,10 +109,7 @@ export default function UsingLayout({ posts, data, params, search, markdown }) {
108109}
109110
110111export async function getStaticProps({ params }) {
111− const posts = buildPageTree(
112− join(process.cwd(), "content/getting-started"),
113− "weight"
114− );
112+ const posts = GettingStartedTree;
115113
116114 const { data, content } = getPage(
117115 join(
@@ -127,10 +125,8 @@ export async function getStaticProps({ params }) {
127125}
128126
129127export async function getStaticPaths() {
130− const posts = buildPageTree(
131− join(process.cwd(), "content/getting-started"),
132− "weight"
133− );
128+ const posts = GettingStartedTree;
129+
134130 const slugs = [];
135131
136132 const allHrefs = (thisLink, tree) => {
pages/understanding-urbit/[[...slug]].js+5−14
@@ -4,16 +4,12 @@ import Link from "next/link";
44import { useRouter } from "next/router";
55import classnames from "classnames";
66import { join } from "path";
7−import {
8− buildPageTree,
9− getPage,
10− getPreviousPost,
11− getNextPost,
12−} from "../../lib/lib";
7+import { getPage, getPreviousPost, getNextPost } from "../../lib/lib";
138import Markdown from "../../components/Markdown";
149import ContentArea from "../../components/ContentArea";
1510import Sidebar from "../../components/Sidebar";
1611import Pagination from "../../components/Pagination";
12+import UnderstandingUrbitTree from "../../cache/understanding-urbit.json";
1713
1814import { decode } from "html-entities";
1915
@@ -150,10 +146,7 @@ export default function UnderstandingLayout({
150146}
151147
152148export async function getStaticProps({ params }) {
153− const posts = buildPageTree(
154− join(process.cwd(), "content/understanding-urbit"),
155− "weight"
156− );
149+ const posts = UnderstandingUrbitTree;
157150
158151 const { data, content } = getPage(
159152 join(
@@ -185,10 +178,8 @@ export async function getStaticProps({ params }) {
185178}
186179
187180export async function getStaticPaths() {
188− const posts = buildPageTree(
189− join(process.cwd(), "content/understanding-urbit"),
190− "weight"
191− );
181+ const posts = UnderstandingUrbitTree;
182+
192183 const slugs = [];
193184
194185 const allHrefs = (thisLink, tree) => {
pages/using/[[...slug]].js+4−3
@@ -5,10 +5,11 @@ import { useRouter } from "next/router";
55import { useState } from "react";
66import classnames from "classnames";
77import { join } from "path";
8−import { getDocs, formatDate, buildPageTree, getPage } from "../../lib/lib";
8+import { getDocs, formatDate, getPage } from "../../lib/lib";
99import Markdown from "../../components/Markdown";
1010import ContentArea from "../../components/ContentArea";
1111import Sidebar from "../../components/Sidebar";
12+import UsingTree from "../../cache/using.json";
1213
1314import { decode } from "html-entities";
1415
@@ -128,7 +129,7 @@ export default function UsingLayout({ posts, data, params, search, markdown }) {
128129}
129130
130131export async function getStaticProps({ params }) {
131− const posts = buildPageTree(join(process.cwd(), "content/using"), "weight");
132+ const posts = UsingTree;
132133
133134 const { data, content } = getPage(
134135 join(process.cwd(), "content/using", params.slug?.join("/") || "/")
@@ -140,7 +141,7 @@ export async function getStaticProps({ params }) {
140141}
141142
142143export async function getStaticPaths() {
143− const posts = buildPageTree(join(process.cwd(), "content/using"), "weight");
144+ const posts = UsingTree;
144145 const slugs = [];
145146
146147 const allHrefs = (thisLink, tree) => {