@@ -0,0 +1,135 @@
1+import Head from "next/head";
2+import Link from "next/link";
3+import { useRouter } from "next/router";
4+import classnames from "classnames";
5+import { join } from "path";
6+import { buildPageTree, getPage } from "../../lib/lib";
7+import Markdown from "../../components/Markdown";
8+import ContentArea from "../../components/ContentArea";
9+import Sidebar from "../../components/Sidebar";
10+import markdownStyles from "../../styles/markdown.module.css";
11+import { decode } from "html-entities";
12+
13+const breadcrumbs = (posts, paths) => {
14+ const results = [
15+ <Link href="/">Urbit</Link>,
16+ <span className="px-1">/</span>,
17+ <Link href="/understanding-urbit">Understanding Urbit</Link>,
18+ ];
19+ let thisLink = "/understanding-urbit";
20+ for (const path of paths) {
21+ posts = posts.children[path];
22+ thisLink = join(thisLink, path);
23+ results.push(
24+ <span className="px-1">/</span>,
25+ <Link href={thisLink}>{posts.title}</Link>
26+ );
27+ }
28+ return results;
29+};
30+
31+const childPages = (thisLink, children, level = 0) => (
32+ <ul className="pl-1">
33+ {children?.map((child) => (
34+ <li>{pageTree(join(thisLink, child.slug), child, level)}</li>
35+ ))}
36+ </ul>
37+);
38+
39+const pageTree = (thisLink, tree, level = 0) => {
40+ const router = useRouter();
41+
42+ const isThisPage = router.asPath === thisLink;
43+
44+ const pageItemClasses = classnames({
45+ "pl-4 text-black text-base hover:text-green": level === 0,
46+ "pl-8 text-black text-base hover:text-green": level === 1,
47+ "pl-12 text-black text-base hover:text-green": level === 2,
48+ "dot relative": isThisPage,
49+ "text-green": isThisPage,
50+ });
51+
52+ return (
53+ <>
54+ <Link href={thisLink}>
55+ <a className={`${pageItemClasses} cursor-pointer`}>{tree.title}</a>
56+ </Link>
57+ </>
58+ );
59+};
60+
61+export default function UnderstandingLayout({
62+ posts,
63+ data,
64+ params,
65+ search,
66+ markdown,
67+}) {
68+ return (
69+ <>
70+ <Head>
71+ <title>{data.title} / Understanding Urbit / urbit.org</title>
72+ </Head>
73+ <div className="flex w-screen h-screen min-h-screen w-screen">
74+ <Sidebar>{childPages("/understanding-urbit", posts.pages)}</Sidebar>
75+ <ContentArea
76+ breadcrumbs={breadcrumbs(posts, params.slug?.slice(0, -1) || "")}
77+ title={data.title}
78+ search={search}
79+ section={"Understanding Urbit"}
80+ >
81+ <div className={markdownStyles["markdown"]}>
82+ <article
83+ dangerouslySetInnerHTML={{ __html: decode(markdown) }}
84+ ></article>
85+ </div>
86+ </ContentArea>
87+ </div>
88+ </>
89+ );
90+}
91+
92+export async function getStaticProps({ params }) {
93+ const posts = buildPageTree(
94+ join(process.cwd(), "content/understanding-urbit"),
95+ "weight"
96+ );
97+
98+ const { data, content } = getPage(
99+ join(
100+ process.cwd(),
101+ "content/understanding-urbit",
102+ params.slug?.join("/") || "/"
103+ )
104+ );
105+
106+ const markdown = await Markdown({ post: { content: content } });
107+
108+ return { props: { posts, data, markdown, params } };
109+}
110+
111+export async function getStaticPaths() {
112+ const posts = buildPageTree(
113+ join(process.cwd(), "content/understanding-urbit"),
114+ "weight"
115+ );
116+ const slugs = [];
117+
118+ const allHrefs = (thisLink, tree) => {
119+ slugs.push(thisLink, ...tree.pages.map((e) => join(thisLink, e.slug)));
120+ allHrefsChildren(thisLink, tree.children);
121+ };
122+
123+ const allHrefsChildren = (thisLink, children) => {
124+ Object.entries(children).map(([childSlug, child]) => {
125+ allHrefs(join(thisLink, childSlug), child);
126+ });
127+ };
128+
129+ allHrefs("/understanding-urbit", posts);
130+
131+ return {
132+ paths: slugs,
133+ fallback: false,
134+ };
135+}