Editing Features
A whirlwind tour of everything Squilla's admin UI can do.
Familiar by design
The Squilla admin UI was made to resemble something most people already know: WordPress. If you've used WP, you'll find your bearings in minutes — node types are post types, taxonomies are taxonomies, the media library looks like the media library, menus look like menus.
TL;DR — imagine WordPress with these plugins pre-installed
- Fluent Forms — built-in form builder with conditional logic
- Advanced Custom Fields — custom fields on basically everything
- WPML — multi-language content (basic but workable)
- PostSMTP / Resend provider — pluggable email delivery
- Email templates — layouts + templates + rules engine
- Image optimizer — WebP, multi-size, quality controls, originals backup
Everything below is shipped, in the box, on a fresh install.
Content editing
Full CRUD on every primitive, accessible from the sidebar.
Node types (post types)
Manage at /admin/node-types. Each node type supports excerpt and a featured image (thumbnail) out of the box. Define a custom field schema per type, choose which taxonomies it accepts, configure URL prefixes per language. Adding a node type is metadata-only — no SQL migration, fields live in JSONB with a GIN index.
Taxonomies and terms
Manage at /admin/taxonomies. Hierarchical or flat. Terms are per-language with linked translations — see the i18n section below.
Menus
Manage at /admin/menus. Drag-and-drop nesting, item types include static URLs and node-linked items. Node-linked items resolve by slug, so renaming the target page doesn't break the menu.
SEO
For now: site title and description (per-language) plus an automatically generated Yoast-style sitemap via the sitemap-generator extension. Per-node SEO fields (meta title, description) are on every node's edit screen.
Media manager
Manage at /admin/media. Grid view, list view, search, alt-text editing. Multi-image-size support with automatic WebP conversion and original-file backups. Reoptimize on demand. Quality, sizes, and formats are configurable. Provided by the media-manager extension.
core.* tool surface. The admin UI and the AI agent are looking at the exact same data.Custom fields
Squilla's custom-field system is the most pervasive feature of the admin UI. Custom fields can be attached to:
- Node types — fields stored in
fields_dataon each node - Taxonomy terms — per-term metadata
- Layout blocks (partials) — page-level fields, e.g. a hero override per page (page-level only for now; global per-partial values are planned)
- Content blocks — the regular block editor surface
Available field types
A wide catalogue out of the box: text, textarea, richtext, number, email, url, select, radio, checkbox, multi-select, repeater (nested sub-fields), image / media picker, file picker, date picker, color, term picker, link picker, true/false, JSON, and more. List the canonical set via core.field_types.list.
Per-field configuration
Every field supports:
- Width — half / third / full grid columns, controllable per breakpoint
- Required — admin-side validation
- Help label — hint text shown beneath the input (also surfaced through MCP so the AI understands what the field is for)
- Default value
- Placeholder
Repeaters can nest other field types as sub_fields, including additional repeaters.
"key":. Field schema entries on a node type registered through Tengo use "name":. Easy to mix up — the admin renders empty inputs when they don't match.Multi-language (i18n)
Configured at /admin/settings/languages. The current implementation is intentionally pragmatic — closer to a v1 MVP than to WPML's full feature set.
What works
- Add languages from a list, mark one as default
- Pick the editing language with the language switcher in the admin top bar (sets the
X-Admin-Languageheader for all admin requests) - Each node has a
language_codecolumn; translations of the same logical content are linked via a sharedtranslation_group_id - The public-site language switcher follows the link — clicking Slovak on an English post takes you to that post's Slovak version, not the homepage or a 404
- Taxonomy terms are per-language with the same translation-group linking; create a translation via
POST /admin/api/terms/<id>/translations - Site settings rows are per-language with default-language fallback. There is no separate translatable flag — every settings field is implicitly per-locale, and reads fall back to the default language when no localised value exists
- URL prefixes per node type can differ per language (e.g.
/recipesvs/recepty)
What's not WPML-grade (yet)
- No bulk translation workflow / queues
- No per-string translation tables for theme strings (themes inherit per-locale settings instead)
- No translation memory or external service connectors
Good for an MVP launch with two or three languages; the linked-translation model gives you a solid foundation to grow into.
Theming surface
The admin shows three distinct theme primitives, each editable from the UI.
Layouts
Top-level page chrome (e.g. default, 2-col, my-special-layout). Layouts are theme- or extension-owned by default. They can be detached from their source so you own them and can edit freely from /admin/layouts, or even created from scratch in the admin without touching the filesystem.
Layout blocks (a.k.a. layout partials)
Reusable fragments shared across multiple layouts — site header, site footer, sidebar, etc. The naming says "blocks" but you can think of them as partials. They support custom fields, but those fields are page-level only: each page can override the partial's field values for itself. A global way to set a partial's custom-field values for all pages at once is on the roadmap.
Content blocks
The lego bricks of a page body — hero, gallery, CTA, two-column text, code block, callout, etc. Authored as block.json + view.html in a theme or extension, or created from scratch in the admin. Content blocks have full custom-field support and live in blocks_data on the node.
Detach / reattach
Theme-owned layouts and blocks can be detached to user-owned (so admin edits stick across theme reinstalls) and later reattached to discard custom edits and follow the theme again.
Mailing
Provided by the email-manager extension plus pluggable provider extensions. Manage at /admin/email.
What's included
- Email layouts — outer wrapper templates (header/footer/branding)
- Email templates — individual messages composed against a layout, with custom-field-style placeholders
- Logs — every send recorded with provider response, status, retry state
- Providers —
smtp-provider(gRPC plugin) andresend-provider(Tengo extension, ~20 lines). Activate one; switch by deactivating + activating another - Rules — when X happens, send template Y to Z. Supports core lifecycle events (e.g. user registers → welcome email, page deleted → notify editors) plus extension-emitted events. Multi-recipient, conditional, multi-template per rule
If you've used PostSMTP for delivery and FluentSMTP-style routing in WP, this is the equivalent.
Forms
Provided by the forms extension. The design is a hybrid of two WordPress plugins — Contact Form 7's custom-HTML escape hatch and Fluent Forms' visual builder.
What you get
- Visual field builder — text, email, number, select, radio, checkbox, file upload, date, hidden, honeypot, and more
- Custom HTML mode — drop into raw HTML when the visual builder isn't enough; the extension still wires up validation and submission
- Multi-condition logic — show/hide/require fields based on AND/OR groups using
=,!=,>,<,>=,<=,contains, etc. - Multiple notifications per form — each with its own template, recipients, and conditions
- Webhooks — POST submissions to external services with retry
- Submission database — every submission stored, browsable, exportable
- Honeypot & rate limiting — built-in spam defenses
Users and roles
Users
Manage at /admin/users. For now, a basic profile is enough for content-editing and admin work — name, email, password, language preference, role assignments. Password resets via the admin UI; CLI fallback via ./squilla reset-password.
Roles
Manage at /admin/roles. Fine-grained access control with capabilities across two axes:
Module capabilities
Toggle access to each core module: admin access, manage users, manage roles, manage emails, manage menus, manage settings, manage media, manage themes, manage extensions, etc.
Node access control
Per role, set a default access level (none / read / write) for each node type, with overrides per individual node when needed. So you can grant a user write access to blog_post only, read-only to page, and nothing on internal_doc.
Email subscriptions
Per-role and per-user subscriptions to lifecycle events of any built-in entity:
- Block type — create / update / delete
- Layout + layout block — create / update / delete
- Menu — create / update / delete
- Node — create / update / delete (filterable by node type)
- User — create / update / delete
Subscribe to one specific verb, several, or all. Pairs with the email-manager rule engine to wire up custom notifications.