This commit is contained in:
Brad Treloar 2025-11-01 21:33:17 +10:30
parent 9a65be07e4
commit d17cb3509a
9 changed files with 89 additions and 34 deletions

View file

@ -1,17 +1,20 @@
// @ts-check
import { defineConfig } from "astro/config";
const setLayout = () => {
return function (_, file) {
if (file.data.astro.frontmatter.layout === undefined) {
file.data.astro.frontmatter.layout = "@layouts/BaseLayout.astro";
}
};
};
//const setLayout = () => {
// return function (_, file) {
// if (file.data.astro.frontmatter.layout === undefined) {
// file.data.astro.frontmatter.layout = "@layouts/BaseLayout.astro";
// }
// };
//};
// https://astro.build/config
export default defineConfig({
markdown: {
remarkPlugins: [setLayout],
//remarkPlugins: [setLayout],
shikiConfig: {
theme: "catppuccin-latte",
},
},
});

View file

@ -0,0 +1,18 @@
---
import { getDocumentPath, getDocumentTitle, getAncestorDocuments } from "@utils/docs";
const { document } = Astro.props;
const ancestorDocuments = await getAncestorDocuments(document);
---
<div class="breadcrumbs">
<a href="/">Home</a>
{ancestorDocuments.map(document => {
const title = getDocumentTitle(document);
const path = getDocumentPath(document);
return (
<span>⟩</span>
<a href={path}>{title}</a>
);
})}
</div>

View file

@ -4,14 +4,14 @@ import { getDocumentPath, getDocumentTitle, getChildDocuments } from "@utils/doc
const { document } = Astro.props;
const childDocuments = await getChildDocuments(document);
---
<ul>
<ul class="menu">
{childDocuments.map(document => {
const title = getDocumentTitle(document);
const path = getDocumentPath(document);
return (
<li>
<a href={path}>{title}</a>
<a href={path}>{title}</a>
</li>
);
})}

View file

@ -1,5 +1,6 @@
---
const { pageTitle } = Astro.props;
import "@styles/main.css";
---
<html lang="en">
<head>

View file

@ -1,12 +0,0 @@
---
import BaseLayout from "@layouts/BaseLayout.astro";
import DocumentMenu from "@components/DocumentMenu.astro";
import { getDocumentPath, getDocumentTitle } from "@utils/docs";
const { document } = Astro.props;
const pageTitle = getDocumentTitle(document);
---
<BaseLayout pageTitle={pageTitle}>
<slot />
<DocumentMenu document={document} />
</BaseLayout>

View file

@ -1,7 +1,9 @@
---
import { getCollection, render } from 'astro:content';
import DocumentLayout from "@layouts/DocumentLayout.astro";
import BaseLayout from "@layouts/BaseLayout.astro";
import DocumentMenu from "@components/DocumentMenu.astro";
import DocumentBreadcrumbs from "@components/DocumentBreadcrumbs.astro";
import { getDocumentPath, getDocumentTitle, getChildDocuments } from "@utils/docs";
export async function getStaticPaths() {
@ -14,9 +16,11 @@ export async function getStaticPaths() {
}
const { document } = Astro.props;
const paths = await getStaticPaths();
const pageTitle = getDocumentTitle(document);
const { Content } = await render(document);
---
<DocumentLayout document={document}>
<BaseLayout pageTitle={pageTitle}>
<DocumentBreadcrumbs document={document} />
<Content />
</DocumentLayout>
<DocumentMenu document={document} />
</BaseLayout>

18
astro/src/styles/main.css Normal file
View file

@ -0,0 +1,18 @@
html, body {
font-family: sans-serif;
}
main {
margin: 0 auto;
max-width: 600px;
line-height: 1.35;
}
.astro-code {
padding: 1rem;
}
ul.menu {
list-style: none;
padding: 0;
}

View file

@ -1,11 +1,13 @@
import type { MarkdownHeading } from "astro";
import { getCollection, type CollectionEntry } from "astro:content";
export function getDocumentPath(document: CollectionEntry<"documents">) {
export type Document = CollectionEntry<"docs">;
export function getDocumentPath(document: Document) {
return "/" + document.id.replace(/\/_index$/, "");
}
export function getDocumentTitle(document: CollectionEntry<"documents">) {
export function getDocumentTitle(document: Document) {
const headings: MarkdownHeading[] =
(document.rendered?.metadata?.headings as MarkdownHeading[]) || [];
const firstHeading = headings[0];
@ -17,17 +19,37 @@ export function getDocumentTitle(document: CollectionEntry<"documents">) {
return null;
}
export async function getChildDocuments(
parentDocument: CollectionEntry<"documents"> | undefined,
) {
export async function getChildDocuments(parentDocument: Document | undefined) {
const documents = await getCollection("docs");
const basePath =
parentDocument !== undefined ? getDocumentPath(parentDocument) : "";
const pathPattern = new RegExp(`^${basePath}/[^/]+$`);
return documents.filter((document) => {
const documentPath = getDocumentPath(document);
return pathPattern.test(documentPath) && documentPath !== basePath;
const childDocuments = documents.filter((document) => {
const path = getDocumentPath(document);
return pathPattern.test(path) && path !== basePath;
});
return childDocuments.sort((a, b) => {
const aWeight = a.data.weight || 0;
const bWeight = b.data.weight || 0;
return aWeight - bWeight;
});
}
export async function getAncestorDocuments(document: Document) {
const documents = await getCollection("docs");
const descendantPath = getDocumentPath(document);
const ancestorDocuments = documents.filter((document) => {
const path = getDocumentPath(document);
return descendantPath.startsWith(path) && path !== descendantPath;
});
return ancestorDocuments.sort((a, b) => {
return getDocumentPath(a).length - getDocumentPath(b).length;
});
}

View file

@ -7,6 +7,7 @@
"@components/*": ["src/components/*"],
"@layouts/*": ["src/layouts/*"],
"@pages/*": ["src/pages/*"],
"@styles/*": ["src/styles/*"],
"@utils/*": ["src/utils/*"]
}
}