Scaffold basic page layout and site generation

Set up the basic layout of the site and greybox its content based on
statically generated pages.  Content pages uses general base layouts
defined centrally to avoid duplicating code.
This commit is contained in:
Hornwitser 2025-01-22 04:54:03 +01:00
parent 51b458103b
commit 8fb809fa95
10 changed files with 268 additions and 21 deletions

23
content/bases.tsx Normal file
View file

@ -0,0 +1,23 @@
import type { Node } from "antihtml";
interface BaseProps {
title: string;
children: Node | Node[],
}
export function BasePage(props: BaseProps) {
return <html lang="en">
<head>
<meta charset="utf-8" />
<title>{props.title}</title>
<link rel="stylesheet" href="./style.css" />
</head>
<body>
<header class="header">
<nav>
<a href="./index.html">Home</a> <a href="./updates.html">Updates</a> <a href="./projects.html">Projects</a>
</nav>
</header>
{props.children}
</body>
</html>
}

34
content/index.tsx Normal file
View file

@ -0,0 +1,34 @@
import { BasePage } from "./bases.js";
import { projects } from "./projects.js"
import { updates } from "./updates.js"
const title = "Hornwitser's Site";
export const index = {
title,
ref: "index.html",
content: <BasePage title={title}>
<main>
<div class="hero" />
<div class="author">
<div style="width: 4em; height: 4em; background-color: grey" />
<hgroup>
<h1>Hi, I'm Hornwitser!</h1>
<p>
Grown up, he/him, aro, gray ace
</p>
</hgroup>
</div>
<p>
I'm a red dragon that mostly dabble in hobby programming and the occasional artwork.
</p>
<h2>Latest <a href="./updates.html">Updates</a></h2>
<ul>
{ updates.map(update => <li><a href={"./" + update.ref}>{update.title}</a></li>)}
</ul>
<h2>Projects</h2>
<ul>
{ projects.map(project => <li><a href={"./" + project.ref}>{project.title}</a></li>)}
</ul>
</main>
</BasePage>,
};

12
content/pages.tsx Normal file
View file

@ -0,0 +1,12 @@
import type { Page } from "./types.js";
import { index } from "./index.js";
import { updates, updatesIndex } from "./updates.js";
import { projects, projectsIndex } from "./projects.js";
export const pages: Page[] = [
index,
updatesIndex,
...updates,
projectsIndex,
...projects,
];

47
content/projects.tsx Normal file
View file

@ -0,0 +1,47 @@
import { BasePage } from "./bases.js";
import type { Page } from "./types.js";
export const projects: Page[] = [
{
title: "Buddhabrot renderer",
ref: "projects/buddhabrot.html",
},
{
title: "Wooden Drawing Board",
ref: "projects/drafting-board.html",
},
{
title: "Flying Hornwitser Paper Craft",
ref: "projects/paper-hornwitser.html",
},
{
title: "Prototype Soren Plush",
ref: "projects/plush-soren.html",
},
{
title: "Blender to CSS export script",
ref: "projects/blender-css.html",
},
].map(page => ({
title: page.title,
ref: page.ref,
content: <BasePage title={page.title}>
<h1>{page.title}</h1>
<p>Placeholder content</p>
</BasePage>
}));
const title = "Hornwitser's Projects";
export const projectsIndex: Page = {
title,
ref: "projects.html",
content: <BasePage title={title}>
<main>
<h1>{title}</h1>
<ul>
{ projects.map(project => <li><a href={"./" + project.ref}>{project.title}</a></li>)}
</ul>
</main>
</BasePage>
}

7
content/types.ts Normal file
View file

@ -0,0 +1,7 @@
import { Element } from "antihtml";
export interface Page {
title: string,
ref: string,
content: Element,
}

32
content/updates.tsx Normal file
View file

@ -0,0 +1,32 @@
import { BasePage } from "./bases.js";
import type { Page } from "./types.js";
export const updates: Page[] = [
{
published: "2025-xx-xx",
title: "Website Launch",
ref: "updates/site-launch.html",
}
].map(page => ({
title: page.title,
ref: page.ref,
content: <BasePage title={page.title}>
<h1>{page.title}</h1>
<p>Published: {page.published}</p>
<p>Placeholder content</p>
</BasePage>
}));
const title = "Website Updates";
export const updatesIndex: Page = {
title,
ref: "updates.html",
content: <BasePage title={title}>
<main>
<h1>{title}</h1>
<ul>
{ updates.map(update => <li><a href={"./" + update.ref}>{update.title}</a></li>)}
</ul>
</main>
</BasePage>
}