Nodes

The unified content primitive and how to edit one.

What a node is

Everything you publish in Squilla — a page, a blog post, a recipe, a doc article, a portfolio entry — is a node. There's no separate pages, posts, recipes table; one content_nodes table holds them all, distinguished by their node_type. Custom fields live in JSONB columns with a GIN index, so adding a new kind of content is metadata-only — no SQL migration.

The columns that matter

  • node_type — which schema applies (page, post, recipe, etc.)
  • statusdraft or published
  • language_code — which language this row is in
  • translation_group_id — links translations of the same logical content
  • slug, title, excerpt
  • featured_image — thumbnail / OG image, an object {url, alt, ...}
  • blocks_data — array of {type, fields} content blocks
  • fields_data — the node-type-level custom fields
  • taxonomies — attached terms keyed by taxonomy slug
  • seo_settings — meta title / description override
  • layout_slug — optional per-node layout override

The edit screen

Find the list at /admin/nodes/<type> (e.g. /admin/nodes/page). Click any row to open the edit screen, or hit "New" to create one.

Anatomy

The edit screen is a familiar two-column layout:

  • Top bar — title, slug (auto-generated from title, editable, validated unique within type+language), status toggle, language switcher, Save button
  • Main column — the block editor and any node-type-level custom fields, plus a tab for layout-block (partial) field overrides if the active layout uses partials with fields
  • Sidebar — featured image, excerpt, taxonomies, translations, layout override, SEO panel

The block editor

The main column hosts the block editor. Click Add block to open the block library — a searchable picker of every block registered by the active theme, by extensions, and any custom blocks you've built in /admin/blocks. Click a block to insert it.

Per-block actions

  • Up / Down arrows — move a block up or down in the stack
  • Duplicate — clone with the same field values
  • Delete — remove from the node
  • Collapse — hide field details, keep the block in place

Each block renders its own field_schema as a form: text, richtext, image picker, repeater, and so on. Fields are validated client-side against the schema (required, type) before save.

Sidebar panels

Featured image

Opens the media library modal. Pick or upload an image. Used as thumbnail in lists, OG image for social shares, and accessible via .node.featured_image in templates.

Excerpt

Plain text summary. Used in archive listings, search results, and as the default og:description when no SEO override is set.

Taxonomies

One multi-select per taxonomy attached to the node type. Selecting a term stores it as {slug, name} object in taxonomies.<taxonomy_slug>.

Translations

Lists existing translations linked via translation_group_id. Click Add translation, choose a language, and a fresh node is cloned into the same group. See the Multi-language page for details.

Layout override

By default a node uses its node-type's default layout. Override here when this specific node needs a different layout (e.g. a landing page using a wide layout while regular pages use the default).

SEO

Meta title and meta description. Empty falls back to title and excerpt respectively.

HEADS UP
Top-level node uses fields_data: — blocks INSIDE blocks_data use fields:. Mismatching either silently drops the data. The save endpoint warns at runtime, but the admin UI handles this for you when you stay inside the editor.