diff --git a/content/guides/_index.md b/content/guides/_index.md
new file mode 100644
index 0000000..e6b4cdc
--- /dev/null
+++ b/content/guides/_index.md
@@ -0,0 +1,3 @@
++++
+title = "Guides"
++++
\ No newline at end of file
diff --git a/content/guides/additional/_index.md b/content/guides/additional/_index.md
new file mode 100644
index 0000000..8d32608
--- /dev/null
+++ b/content/guides/additional/_index.md
@@ -0,0 +1,5 @@
++++
+title = "Additional Guides"
+weight = 3
+type = "tab"
++++
\ No newline at end of file
diff --git a/content/guides/core/_index.md b/content/guides/core/_index.md
new file mode 100644
index 0000000..2e74eaf
--- /dev/null
+++ b/content/guides/core/_index.md
@@ -0,0 +1,5 @@
++++
+title = "Core Curriculum"
+weight = 2
+type = "tab"
++++
\ No newline at end of file
diff --git a/content/guides/quickstart/.gitkeep b/content/guides/quickstart/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/content/guides/quickstart/_index.md b/content/guides/quickstart/_index.md
new file mode 100644
index 0000000..20c654d
--- /dev/null
+++ b/content/guides/quickstart/_index.md
@@ -0,0 +1,4 @@
++++
+title = "Quickstart"
+weight = 1
++++
\ No newline at end of file
diff --git a/lib/lib.js b/lib/lib.js
index 0453c02..40e3111 100644
--- a/lib/lib.js
+++ b/lib/lib.js
@@ -135,3 +135,23 @@ export function getPreviousPost(slug, fields = [], key, sort = "date") {
});
return resultPost;
}
+
+export const getPage = (path) => {
+ try {
+ let fileContents = fs.readFileSync(`${path}.md`, "utf8");
+ if (fileContents) {
+ const { data, content } = matter(fileContents, options);
+ return { data, content };
+ }
+ } catch {
+ try {
+ let fileContents = fs.readFileSync(`${path}/_index.md`, "utf8");
+ if (fileContents) {
+ const { data, content } = matter(fileContents, options);
+ return { data, content };
+ }
+ } catch {
+ console.error("no md file for slug");
+ }
+ }
+};
diff --git a/pages/guides/[[...slug]].js b/pages/guides/[[...slug]].js
new file mode 100644
index 0000000..a20d475
--- /dev/null
+++ b/pages/guides/[[...slug]].js
@@ -0,0 +1,325 @@
+import Head from "next/head";
+import Link from "next/link";
+import { useRouter } from "next/router";
+import { useState } from "react";
+import classnames from "classnames";
+import Meta from "../../components/Meta";
+import Header from "../../components/Header";
+import Footer from "../../components/Footer";
+import Card from "../../components/Card";
+import ContentArea from "../../components/ContentArea";
+import Sidebar from "../../components/Sidebar";
+import TallCard from "../../components/TallCard";
+import Pagination from "../../components/Pagination";
+import {
+ Container,
+ Section,
+ SingleColumn,
+ TwoUp,
+ Markdown,
+} from "foundation-design-system";
+import { Comms, MintFiller } from "../../components/icons";
+import guidesTree from "../../cache/guides.json";
+import { join } from "path";
+import { getPage, getPreviousPost, getNextPost } from "../../lib/lib";
+
+export default function GuidePage({
+ search,
+ posts,
+ data,
+ markdown,
+ params,
+ previousPost,
+ nextPost,
+}) {
+ if (!params.slug) {
+ return ;
+ }
+ return (
+ <>
+
+ {data.title} • Guides • developers.urbit.org
+ {Meta(data)}
+
+
+
+ {childPages("/guides", posts.children)}
+
+
+
+
+
+
+ {previousPost === null ? (
+
+ ) : (
+
+ )}
+ {nextPost === null ? (
+
+ ) : (
+
+ )}
+
+
+ Edit this page on GitHub
+
+
+
+ >
+ );
+}
+
+const breadcrumbs = (posts, paths) => {
+ const results = [Guides];
+ let thisLink = "/guides";
+ for (const path of paths) {
+ posts = posts.children[path];
+ thisLink = join(thisLink, path);
+ results.push(
+ /,
+ {posts.title}
+ );
+ }
+ return results;
+};
+
+const childPages = (thisLink, children, level = 0) => (
+
+ {Object.entries(children).map(([childSlug, child]) => (
+ - {pageTree(join(thisLink, childSlug), child, level)}
+ ))}
+
+);
+
+const pageTree = (thisLink, tree, level = 0) => {
+ const router = useRouter();
+ const firstCrumb = "/" + router.asPath.split("/").slice(1, -1).join("/");
+
+ const includesThisPage = firstCrumb.includes(thisLink);
+ const isThisPage = router.asPath === thisLink;
+ const [isOpen, toggleTree] = useState(includesThisPage);
+
+ const activeClasses = classnames({
+ hidden: !isOpen,
+ });
+
+ const headingItemClasses = classnames({
+ "pl-0 text-wall-600 text-base font-semibold hover:text-green-400 leading-relaxed":
+ level === 0,
+ "pl-4 text-wall-600 text-base font-semibold hover:text-green-400":
+ level === 1,
+ "pl-8 text-wall-600 text-base hover:text-green-400": level === 2,
+ });
+
+ const pageItemClasses = classnames({
+ "pl-4 text-base hover:text-green-400": level === 0,
+ "pl-8 text-base hover:text-green-400": level === 1,
+ "pl-12 text-base hover:text-green-400": level === 2,
+ });
+
+ if (tree?.type === "tab") {
+ return (
+ <>
+
+ {tree.title}
+
+ {childPages(thisLink, tree.children, level)}
+ >
+ );
+ }
+
+ return (
+ <>
+ toggleTree(!isOpen)}>
+ {tree.title}
+
+
+
+ {tree.pages.map(({ title, slug }) => {
+ const href = join(thisLink, slug);
+ const isSelected = router.asPath === href;
+ const selectedClasses = classnames({
+ dot: isSelected,
+ "text-green-400": isSelected,
+ "text-wall-600": !isSelected,
+ });
+ return (
+ -
+
+
+ {title}
+
+
+
+ );
+ })}
+
+ {childPages(thisLink, tree.children, level + 1)}
+
+ >
+ );
+};
+
+function Landing({ search }) {
+ const post = {
+ title: "Guides",
+ description:
+ "Everything you need to know to start building applications on Urbit.",
+ };
+ return (
+
+
+ Guides • developers.urbit.org
+ {Meta(post)}
+
+
+
+
+
+ Quickstart: Lightning Tutorials
+
+ Build an application on Urbit in 15 minutes with these instant
+ application guides.
+
+
+ }
+ title="Encrypted Chat Application"
+ text="Build your own secure comms tool"
+ className="basis-1/2"
+ />
+ }
+ title="Lorem Ipsum Dolorem"
+ text="Roll your own encrypted chat application in minutes"
+ className="basis-1/2"
+ />
+
+
+
+ Core Curriculum
+
+ The following guides will teach you everything you need to know to
+ start building applications on Urbit.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export async function getStaticProps({ params }) {
+ let posts = guidesTree;
+
+ const { data, content } = getPage(
+ join(process.cwd(), "content/guides", params.slug?.join("/") || "/")
+ );
+
+ const previousPost =
+ getPreviousPost(
+ params.slug?.slice(-1).join("") || "guides",
+ ["title", "slug", "weight"],
+ join("guides", params.slug?.slice(0, -1).join("/") || "/"),
+ "weight"
+ ) || null;
+
+ const nextPost =
+ getNextPost(
+ params.slug?.slice(-1).join("") || "guides",
+ ["title", "slug", "weight"],
+ join("guides", params.slug?.slice(0, -1).join("/") || "/"),
+ "weight"
+ ) || null;
+
+ const markdown = JSON.stringify(Markdown.parse({ post: { content } }));
+
+ return { props: { posts, data, markdown, params, previousPost, nextPost } };
+}
+
+export async function getStaticPaths() {
+ const posts = guidesTree;
+ const slugs = [];
+
+ const allHrefs = (thisLink, tree) => {
+ slugs.push(thisLink, ...tree.pages.map((e) => join(thisLink, e.slug)));
+ allHrefsChildren(thisLink, tree.children);
+ };
+
+ const allHrefsChildren = (thisLink, children) => {
+ Object.entries(children).map(([childSlug, child]) => {
+ allHrefs(join(thisLink, childSlug), child);
+ });
+ };
+
+ allHrefs("/guides", posts);
+ return {
+ paths: slugs,
+ fallback: false,
+ };
+}
diff --git a/pages/guides/index.js b/pages/guides/index.js
deleted file mode 100644
index 74d20bc..0000000
--- a/pages/guides/index.js
+++ /dev/null
@@ -1,100 +0,0 @@
-import Head from "next/head";
-import Meta from "../../components/Meta";
-import Header from "../../components/Header";
-import Footer from "../../components/Footer";
-import Card from "../../components/Card";
-import TallCard from "../../components/TallCard";
-import {
- Container,
- Section,
- SingleColumn,
- TwoUp,
-} from "foundation-design-system";
-import { Comms, MintFiller } from "../../components/icons";
-
-export default function GuidePage({ search }) {
- const post = {
- title: "Guides",
- description:
- "Everything you need to know to start building applications on Urbit.",
- };
- return (
-
-
- Guides • developers.urbit.org
- {Meta(post)}
-
-
-
-
-
- Quickstart: Lightning Tutorials
-
- Build an application on Urbit in 15 minutes with these instant
- application guides.
-
-
- }
- title="Encrypted Chat Application"
- text="Build your own secure comms tool"
- className="basis-1/2"
- />
- }
- title="Lorem Ipsum Dolorem"
- text="Roll your own encrypted chat application in minutes"
- className="basis-1/2"
- />
-
-
-
- Core Curriculum
-
- The following guides will teach you everything you need to know to
- start building applications on Urbit.
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
-}