The editing experience
CTXR has no admin panel. Editors work on the live site — the same HTML, the same CSS, the same URL a visitor sees — with a thin editing layer on top. When the lifecycle tells a template “this viewer is an editor,” your page activates its editing affordances in place. There’s no second application to keep in sync, because there’s no second application.
So how does your template become editable? Through a contract in three layers.
The three-layer contract
layout → your templates render the page, calling helpers
binding → helpers are the only bridge to the editor
composition → a semantic wrapper holds a repeatable container of typed atoms
Layout is what you write: the markup, the structure, the order of things. You’re free here — any HTML, any CSS.
Binding is the helper API. The moment a value is read through a helper, the editor can find and edit it. Helpers are the only binding; nothing else hooks the editor in.
Composition is the shape the editor expects to find: a semantic wrapper (this region means “the stops”), a repeatable container (an ItemList you can add to and reorder), and typed atoms inside (each a known kind of editable thing). Follow that shape and the editor wires itself up.
Atoms: data + anatomy + a11y
Each editable atom is a triple — it’s not just a value, it’s a value with a defined HTML5 anatomy and an accessibility contract. The editor knows all three for every type:
| Atom | Edits | Example use |
|---|---|---|
text | inline prose run | captions, body |
heading | a heading line | titles |
link | href + label | buttons, nav |
field | a typed scalar | rating, price |
media | an ImageObject | hero, thumbnail |
code | a code block | snippets |
embed | external content | video, map |
geo | lat/long via map | coordinates |
block | a nested node | a card |
action | a button bound to an operation | “submit” |
Because the type carries the anatomy and the a11y contract, the editor renders the right control and the right semantics — a link atom is a real <a> with an accessible name, a media atom a real <figure> — without you specifying it each time.
Two surfaces, one set of data
The same property can be edited two ways, and both write to the same node:
Form — a structured panel listing the node’s fields. You fill it in and submit; changes collect and commit together. Best for precise, multi-field edits and for properties with no visible representation.
Inline visual — click the thing on the page and change it where it sits. Faster, more direct, and it never makes you leave the layout.
They’re not two data models — they’re two doors into the same draft. Edit a title inline or in the form; either way it’s the same name property on the same node.
Placing images & video
A media atom edits more than a file. Because a placement is a reference to a media node, the editor exposes the choices that belong to this placement. An image or video field shows a preview with:
- a clickable focus point (“click to set focus point”) — the anchor the image or video crops around, so the same media can be framed differently in each place it appears;
- a decorative toggle (images only) that empties the
alt, for media that carries no information; and - a Choose or upload button that opens the media library — a picker where you reuse an existing media node or upload a new file.
The picker and uploader are kind-scoped: an image slot accepts images, a video slot accepts videos. The file’s mime type decides the node type — a video/mp4 becomes a VideoObject, an image/* an ImageObject — so you never have to declare it.
Video previews show the first frame; they don’t auto-play in previews or in the library, which keeps a screen full of clips calm and cheap. A real page hero is free to auto-play — that’s the layout’s call, not the editor’s.
Four interaction surfaces
The chrome that hosts all of this is four fixed surfaces:
toolbar vertical rail, the always-present controls
drawer slides in for browsing and management
dialog a focused modal — inspect, confirm
node-bar a floating bar scoped to the node in focus
You don’t build these; you inherit them. Your job is the layout and the helper calls — the surfaces appear around your page automatically.
In development: the prose editor
The inline prose editor — the step-2 surface that makes rich-text (the_richtext) editable directly on the page, with formatting controls in place — is being built. Today rich text renders correctly for visitors and is editable through the structured form; the in-place prose surface arrives with the editor’s next layer. Everything else on this page is live.
The throughline: you write a normal page, read values through helpers, and the editor activates from the data the lifecycle hands you. One template, one set of data, one site — told who’s looking.