doc to prefer literal html injection
This commit is contained in:
parent
465cc74796
commit
684a89460f
2 changed files with 30 additions and 1 deletions
24
CLAUDE.md
24
CLAUDE.md
|
|
@ -17,7 +17,29 @@ Requires a `.env` file with `VAPID_PUBLIC_KEY` and `VAPID_PRIVATE_KEY` for web p
|
||||||
|
|
||||||
Bliss is a browser-based low-code platform where users build mini web apps ("Structures") entirely through a `/workshop` UI. Each Structure has routes, templates, and SQLite databases — all stored in the main app database and executed at runtime via Node's `vm` module.
|
Bliss is a browser-based low-code platform where users build mini web apps ("Structures") entirely through a `/workshop` UI. Each Structure has routes, templates, and SQLite databases — all stored in the main app database and executed at runtime via Node's `vm` module.
|
||||||
|
|
||||||
## Architecture
|
## Design philosophy: this is a hypermedia homestead
|
||||||
|
|
||||||
|
Bliss templates are not a web-app-with-an-API. There is no client-side framework,
|
||||||
|
no JSON contract, no build step — the HTML *is* the application, and it composes
|
||||||
|
by embedding more HTML (see "page-nesting primitive" below). Every template you
|
||||||
|
write or edit should lean into that instead of fighting it:
|
||||||
|
|
||||||
|
- **Prefer `<%~ %>` (raw) over `<%= %>` (HTML-escaped) in Eta templates, always,
|
||||||
|
unless you are interpolating into an HTML attribute value.** Attribute values
|
||||||
|
(`id="..."`, `data-*="..."`, `href="..."`, `style="..."`, `value="..."`) are
|
||||||
|
the one place escaping is not optional — an unescaped `"` there breaks the tag
|
||||||
|
itself, not just a security nicety. Everywhere else (text content, `<script>`
|
||||||
|
string literals, anything that isn't sitting inside `attr="…"`) use `<%~ %>`.
|
||||||
|
Arbitrary HTML/JS in user content is a *feature* here, not a bug to guard
|
||||||
|
against — see the `aim` structure's `message` template for the canonical
|
||||||
|
comment explaining why. When in doubt: default to raw, escape only when the
|
||||||
|
HTML would literally break otherwise.
|
||||||
|
- **Prefer htmx attributes over hand-rolled JS for anything hypermedia-shaped**
|
||||||
|
— polling (`hx-trigger="every 10s"`), lazy loading (`hx-trigger="load"`),
|
||||||
|
swapping (`hx-swap-oob`), cross-fragment events (`hx-trigger="foo from:body"`)
|
||||||
|
— instead of `setTimeout`/`fetch`/manual DOM patching. If htmx (or Hyperscript
|
||||||
|
for small imperative glue) can express it declaratively, don't write the
|
||||||
|
imperative version.
|
||||||
|
|
||||||
### Two layers of routes
|
### Two layers of routes
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,13 @@ own SQLite file). Ids are integers. Build a structure by: create it → add a db
|
||||||
write its library → add routes whose handlers call the library → add templates
|
write its library → add routes whose handlers call the library → add templates
|
||||||
the handlers render.
|
the handlers render.
|
||||||
|
|
||||||
|
**Templates are hypermedia, not escaped-string templates.** Default to `<%~ %>`
|
||||||
|
(raw) over `<%= %>` (escaped) in Eta content — only use `<%= %>` inside an HTML
|
||||||
|
attribute value, where an unescaped `"` would break the tag. Reach for htmx
|
||||||
|
attributes (`hx-trigger="every 10s"`, `hx-swap-oob`, etc.) instead of JS
|
||||||
|
`setTimeout`/`fetch` polling loops. See CLAUDE.md's "hypermedia homestead"
|
||||||
|
section for the full rationale.
|
||||||
|
|
||||||
## Reads (JSON)
|
## Reads (JSON)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue