writeonce/docs/examples/site/README.md
shoney.arickathil ad4b380cf1 feat: writeonce.de tutorial site + wo-html library (two-dep full stack)
- 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>
2026-08-23 01:51:14 +02:00

54 lines
2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# site — writeonce.de
The language tutorial, served BY the language. One binary carries the HTTP
server, the router, the pages and the database; the chapters you read are
rows in a `@table`, the markup is built by the `wo-html` dependency, and
the whole thing is chapter 9's own example.
```
[deps]
framework = { git = "https://github.com/shoneyj/writeonce-framework", rev = "v0.1.0" }
html = { git = "https://github.com/shoneyj/wo-html", rev = "v0.1.0" }
```
## Run it
```
woc . && SITE_TOKEN=change-me WO_DATA=./data ./target/site 8080
```
- `GET /` — the chapter index; `GET /ch/<slug>` — one chapter.
- `POST /admin/ch/<slug>` — edit a chapter (`title`/`body`, form-encoded,
`authorization: Bearer $SITE_TOKEN`). Edits are WAL-durable under
`WO_DATA` and replay on restart — that is chapter 6, demonstrated by
the site that teaches it.
- Without `WO_DATA` the chapters live in RAM and reseed on every boot.
The acceptance gate is `just site` (scripts/site-accept.sh): two file://
dep remotes, build, the page matrix, 401, an authed edit, SIGTERM, and
the edit surviving a restart.
## writeonce.de deployment
The framework speaks HTTP/1.1 keep-alive and no TLS by design — terminate
TLS at the proxy and forward:
```
server {
server_name writeonce.de;
listen 443 ssl http2; # certs via certbot/acme
location / { proxy_pass http://127.0.0.1:8080; }
}
```
Run the binary under systemd (`Restart=on-failure`, `Environment=SITE_TOKEN=...`,
`Environment=WO_DATA=/var/lib/writeonce-site`); SIGTERM drains cleanly.
## What it demonstrates
Chapters 1–9 teach the language (values, containers, classes, optionals,
tables, actors, deps, serving); the app itself exercises the framework's
routing/:params, the Logging middleware, bearer auth (mechanism from
`http/auth.wo`, policy here), `form_values`, `@table` + query + update by
assignment, and `wo-html`'s escaping/builders/Tailwind-style utility
sheet — self-contained pages, no CDN, no JS, no build step.