- 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>
2 KiB
2 KiB
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-timect_eq); which routes are gated and by which token is policy, soAdminEditchecks 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 intw_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).