- docs/examples/wo-html: library dep — esc(), element builders,
Tailwind-style utility sheet as one static string, page() shell;
self-contained responses, no CDN/JS/build step
- docs/examples/site: the language tutorial served by the language —
9 seeded chapters in a @table (hello/values+bitwise/containers/
classes/optionals+traps/tables/actors/deps/serving), server-rendered
via wo-html, seed-if-empty so WAL restarts keep admin edits
- routes: / index, /ch/:slug (styled 404), /health, POST /admin/ch/
:slug (bearer handler-side — mechanism framework's, policy app's;
form-encoded title/body update by assignment, 302 back)
- chapter code samples use the lexer's \$ escape to show ${...}
literally; .. never straddles newlines (accumulator style)
- gate: scripts/site-accept.sh + just site — TWO file:// dep remotes,
11 checks incl. authed-edit-survives-restart; /health polling, no
boot-race sleep
- README: run + nginx sketch for writeonce.de; CODE-LOGIC beside code
- full battery 13/13 (site gate included)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
36 lines
2 KiB
Markdown
36 lines
2 KiB
Markdown
# site — how it is put together
|
|
|
|
Written 2026-08-23, with the sample's landing. Three files, one binary.
|
|
|
|
| file | what it owns |
|
|
| --- | --- |
|
|
| `main.wo` | the `Chapter` table, seed-if-empty, the HTML shell (header/nav), four handlers (Home, ShowChapter, AdminEdit, Health), `main` |
|
|
| `content.wo` | the nine chapter bodies as functions returning HTML fragments, and `seed_chapters()` — same directory, so it shares `main.wo`'s declarations without `use` |
|
|
| `wo.toml` | the two [deps]: `framework` (serving) and `html` (markup) |
|
|
|
|
Decisions that are not obvious from the code:
|
|
|
|
- **Chapters are rows, not constants.** `seed_if_empty()` inserts them only
|
|
when the table answers empty, so a WAL restart keeps admin edits instead
|
|
of reseeding over them — the sample's own proof of chapter 6's claim.
|
|
The seed bodies are BUILT with wo-html's builders at boot; after that
|
|
the table is the truth and the builders are never consulted again.
|
|
- **Auth is handler-side by doctrine.** The framework ships mechanism
|
|
(`bearer_token`, constant-time `ct_eq`); which routes are gated and by
|
|
which token is policy, so `AdminEdit` checks its own field. No global
|
|
middleware — the public pages stay public.
|
|
- **`\$` in chapter code samples.** Chapter sources show interpolation
|
|
(`${port}`) inside string literals of a language that interpolates —
|
|
the lexer's `\$` escape keeps them literal; `code_block()` then
|
|
HTML-escapes the result.
|
|
- **One-line concat chains.** `..` does not straddle newlines (Go-style
|
|
implicit statement ends), so long fragments build accumulator-style
|
|
(`b = b .. "...";` per line) — the same shape serve.wo uses for
|
|
response heads.
|
|
- **wo-html's sheet is static.** Tailwind's class NAMES, one hand-written
|
|
CSS string inlined per page by `page()` — self-contained responses, no
|
|
toolchain; growing the sheet is appending a line in `tw_css()`.
|
|
|
|
Gate: `just site` — see scripts/site-accept.sh (11 checks; the restart
|
|
leg polls `/health` instead of sleeping, so it does not share
|
|
web-app-accept's 0.5s boot race).
|