Skip to content

Commit 67358aa

Browse files
committed
Add blog example
1 parent e2ec56e commit 67358aa

File tree

23 files changed

+864
-0
lines changed

23 files changed

+864
-0
lines changed

examples/blog/package.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"name": "blog",
3+
"version": "0.0.0",
4+
"description": "A blog example for domstack demonstrating global.data.ts, nested layouts, and feeds.",
5+
"type": "module",
6+
"scripts": {
7+
"start": "npm run watch",
8+
"build": "npm run clean && domstack",
9+
"clean": "rm -rf public && mkdir -p public",
10+
"watch": "npm run clean && dom --watch",
11+
"test": "tsc"
12+
},
13+
"keywords": [],
14+
"author": "Bret Comnes <bcomnes@gmail.com> (https://bret.io/)",
15+
"license": "MIT",
16+
"devDependencies": {
17+
"@voxpelli/tsconfig": "^16.0.0",
18+
"typescript": "~5.9.2"
19+
},
20+
"dependencies": {
21+
"@domstack/static": "file:../../.",
22+
"htm": "^3.1.1",
23+
"mine.css": "^10.0.0",
24+
"preact": "^10.26.6",
25+
"preact-render-to-string": "^6.5.13"
26+
}
27+
}

examples/blog/src/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
title: Home
3+
---
4+
5+
# Welcome
6+
7+
This is a blog built with [domstack](https://github.com/bcomnes/domstack).
8+
Recent posts are listed below — the list is generated automatically by `global.data.ts`
9+
at build time, with no manual wiring needed in this file.
10+
11+
{{{ vars.recentPostsHtml }}}
12+
13+
See [all posts →](/blog/)
14+
15+
Hello

examples/blog/src/about/README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
title: About
3+
---
4+
5+
# About
6+
7+
This blog is a demonstration of [domstack](https://github.com/bcomnes/domstack),
8+
a static site generator built around a simple idea: pages are functions, layouts are
9+
functions, and data flows through plain JavaScript objects.
10+
11+
## The author
12+
13+
**Ada Lovelace** was a mathematician and writer who worked on Charles Babbage's proposed
14+
mechanical general-purpose computer, the Analytical Engine. She is widely regarded as the
15+
first computer programmer.
16+
17+
## This site
18+
19+
Built with:
20+
21+
- [domstack](https://github.com/bcomnes/domstack) — the build system
22+
- [preact](https://preactjs.com) — JSX rendering for layouts
23+
- [mine.css](https://mine.css.bret.io) — baseline styles
24+
- [esbuild](https://esbuild.github.io) — JS/CSS bundling
25+
26+
Source is on [GitHub](https://github.com/bcomnes/domstack/tree/master/examples/blog).
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
title: "2024"
3+
layout: year-index
4+
---
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
---
2+
layout: post
3+
title: "Hello, World"
4+
publishDate: "2024-03-15T12:00:00.000Z"
5+
description: "The first post on this blog. An introduction to what this is all about."
6+
tags:
7+
- meta
8+
- intro
9+
---
10+
11+
# Hello, World
12+
13+
Welcome to this blog. It's built with [domstack](https://github.com/bcomnes/domstack),
14+
a static site generator that lets you write pages in TypeScript, Markdown, or plain HTML
15+
and compose them with layouts written in JSX (via preact).
16+
17+
## What makes this interesting
18+
19+
The post list you saw on the home page and the `/blog/` index weren't manually maintained.
20+
They're generated at build time by `global.data.ts`:
21+
22+
```ts
23+
// src/global.data.ts
24+
const blogPosts = pages
25+
.filter(p => p.vars?.layout === 'post' && p.vars?.publishDate)
26+
.sort((a, b) => new Date(b.publishDate) - new Date(a.publishDate))
27+
```
28+
29+
The returned object is stamped onto every page's `vars`, so any page or layout can read
30+
`vars.blogPosts` directly — no postVars, no custom wiring.
31+
32+
## This layout
33+
34+
This post uses the `post` layout (`src/layouts/post.layout.ts`), which wraps the root layout
35+
and adds article chrome: an `h-entry` microformat wrapper, author card, publish date, and tag list.
36+
37+
More posts coming soon.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
---
2+
layout: post
3+
title: "Layouts All the Way Down"
4+
publishDate: "2024-07-04T09:00:00.000Z"
5+
description: "How domstack's nested layout system works and why it keeps things simple."
6+
tags:
7+
- domstack
8+
- layouts
9+
---
10+
11+
# Layouts All the Way Down
12+
13+
Domstack layouts are just functions. The `post` layout is a TypeScript function that
14+
receives `children` (the rendered page content), wraps it in article markup, and
15+
delegates to the `root` layout for the full HTML shell:
16+
17+
```ts
18+
const postLayout: LayoutFunction<PostVars> = (args) => {
19+
const { children, ...rest } = args
20+
const wrappedChildren = render(html`
21+
<article class="h-entry">
22+
<header>...</header>
23+
<div class="e-content">${children}</div>
24+
</article>
25+
`)
26+
return rootLayout({ ...rest, children: wrappedChildren })
27+
}
28+
```
29+
30+
No magic inheritance, no template partials, no special syntax. Just function composition.
31+
32+
## Styles follow the same pattern
33+
34+
`post.layout.css` imports `root.layout.css` with a plain CSS `@import`. esbuild
35+
bundles them together. Each layout advertises its own stylesheet and client script,
36+
and domstack injects the right ones automatically based on which layout a page uses.
37+
38+
## The `vars` merge order
39+
40+
```
41+
{ ...globalVars, ...globalDataVars, ...pageVars, ...builderVars }
42+
```
43+
44+
`globalDataVars` sits between global and page vars, so `global.data.ts` output is
45+
available everywhere but can be overridden per-page if needed.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
title: "2025"
3+
layout: year-index
4+
---
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
layout: post
3+
title: "A New Year, A New Post"
4+
publishDate: "2025-01-10T08:30:00.000Z"
5+
description: "Kicking off 2025 with some thoughts on building for the web."
6+
tags:
7+
- web
8+
- meta
9+
---
10+
11+
# A New Year, A New Post
12+
13+
It's 2025. The web is still here. Static sites are still a good idea.
14+
15+
## Why static?
16+
17+
- Fast. No server render time.
18+
- Cheap. A CDN and an object store is enough.
19+
- Durable. HTML files outlast frameworks.
20+
- Understandable. The output is exactly what the browser sees.
21+
22+
The build step is the complexity budget. Spend it wisely, then ship files.
23+
24+
## What global.data.ts gives you
25+
26+
Before `global.data.ts`, aggregating data across pages (blog indexes, RSS feeds) required
27+
a `postVars` escape hatch that ran after the main build pass. It was implicit and hard
28+
to reason about.
29+
30+
`global.data.ts` makes it explicit: one function, runs once, receives the fully initialized
31+
page array, returns an object that every page can read. The blog index on this site is
32+
just `vars.blogPosts.map(...)`. No special setup.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
layout: post
3+
title: "Thoughts on the Web Platform"
4+
publishDate: "2025-02-14T14:00:00.000Z"
5+
description: "Web components, view transitions, and why the platform keeps getting better."
6+
tags:
7+
- web
8+
- platform
9+
---
10+
11+
# Thoughts on the Web Platform
12+
13+
The web platform has been quietly getting very good.
14+
15+
## View Transitions
16+
17+
The View Transitions API lets you animate between page states with a few lines of CSS.
18+
Works for both same-document and cross-document navigation. No JavaScript framework required.
19+
20+
## Custom Elements
21+
22+
Web Components via Custom Elements (`customElements.define`) are now well-supported
23+
everywhere. They're not a replacement for component frameworks, but they're great for
24+
leaf-node UI that needs to work anywhere.
25+
26+
## CSS
27+
28+
Container queries. `:has()`. Cascade layers. Logical properties. The CSS working group
29+
has shipped more useful features in the last three years than in the decade before.
30+
31+
## The takeaway
32+
33+
Build with the platform where you can. Reach for frameworks and build tools when the
34+
platform isn't enough. domstack tries to stay close to the platform — your JS is
35+
bundled with esbuild, your HTML is just HTML, your CSS is just CSS.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
console.log('yo')

0 commit comments

Comments
 (0)