Content Blocks

Lego bricks of node bodies — pick from the library or build your own.

What a content block is

A content block is a typed, reusable fragment that an editor drops into a node body. Hero, Two-column text, Gallery, CTA, Code sample, Callout — the kinds of building blocks every CMS calls something different. In Squilla they live as { type, fields } objects in each node's blocks_data array.

Where they come from

  • Theme-owned — declared in themes/<t>/blocks/<slug>/ as block.json + view.html
  • Extension-owned — same shape, shipped by an extension (e.g. content-blocks ships a stock library)
  • User-owned — created in the admin or detached from a theme/extension block

Manage at /admin/blocks

Lists every registered block with slug, label, source, field count. Click a block to view its schema and template; theme/extension blocks are read-only until detached.

Create a custom block

Click New block. Fill in:

  • Slug — must be unique. Prefix theme blocks (e.g. sq-hero, mytheme-cta) to avoid collisions
  • Label
  • Field schema — the editor form; uses key:, see Custom Fields
  • HTML template — Go html/template source rendered with .fields and .node
  • Test data — sample values used by the live preview in the editor

Detach & reattach

Detach a theme/extension block to take ownership and edit. Reattach discards your edits and follows the source.

block.json (excerpt)
{
  "slug": "sq-cta",
  "label": "Call to action",
  "field_schema": [
    { "key": "heading", "type": "text",  "required": true },
    { "key": "body",    "type": "richtext" },
    { "key": "button",  "type": "link" }
  ],
  "test_data": {
    "heading": "Try Squilla today",
    "body":    "<p>Open source. Self-hostable.</p>",
    "button":  { "label": "Get started", "url": "/docs/quickstart" }
  }
}
HEADS UP
test_data must cover every field in field_schema. The admin renders test_data as the live preview when the editor first opens a fresh block. A missing entry shows as a broken empty area until you fill the field.

The in-node editor

On any node edit screen, the main column hosts the block editor:

  • Add block — opens the block library (searchable, grouped by category if a theme tags blocks)
  • Up / Down arrows — move a block up or down in the stack
  • Duplicate — clone with the same field values
  • Delete
  • Collapse — hide field details, keep the block in place

Each inserted block renders its own field schema as a sub-form. Saving a node writes the entire blocks_data array atomically.

Template scope

Block view.html templates see only the block's own fields at the root of the data context, plus .node for the parent node. They do not see .app, settings, or menus — those belong in the layout. This isolation is intentional: blocks are atomic, easy to reason about, and reusable across themes.

Optional per-block CSS / JS

Drop style.css or script.js alongside view.html in a theme/extension block. The kernel scopes them to the block (BEM-prefixed for CSS; module-loaded for JS) and only emits them on pages that actually use the block.