Posts — Reference
The Posts surface is the blog engine — and, less obviously, the shared write layer for every long-form record on the platform. It owns blog post records, post categories, post tags, post-type taxonomies, content import / export, the per-post revision system, and the duplicate / soft-delete / restore lifecycle that Pages, Events, and custom content types all reuse.
This page is a reference for platform engineers and integrators. Customer-facing walkthroughs for writing and publishing blog posts live in the customer docs set; this page describes the surface, not the editorial flow.
Overview
Posts live under the Blog module in SG-Admin (the user-facing label is "Blog"; the underlying record type is post). The module renders the standard list / create / edit / history views and exposes a settings panel for blog-wide behavior — default category, posts-per-page on the archive, RSS feed visibility, social-card defaults.
The Posts surface is dual-role. Externally, it is the blog. Internally, it is the post-record action layer — the engine that every long-form content type on the platform reuses for its write operations. Pages, Events, custom objects, and the Blog itself all route their saves, duplicates, deletes, and restores through this layer. When you read the SG-Admin source, the actions file for posts is one of the largest in the codebase; that size is because it serves four content types, not blog posts.
Where it lives in SG-Admin:
- Sidebar: SG-Admin → Blog
- URL prefix:
/sg-admin/blog/ - View templates:
application/views/Admin/Blogs/ - Shared write surface: this module's action layer (also used by Pages, Events, Custom Objects)
┌──────────────────────────────────────────────────────────────────────┐│ SG-Admin → Blog [+ New post] │├──────────────────────────────────────────────────────────────────────┤│ Title Categories Status Posted ││ ───────────────────────────── ───────────── ────────── ────────││ Five lessons from migration Engineering published 3d ago ││ Q1 platform recap Highlights published 8d ago ││ How we handle revision histo… Engineering draft 1d ago ││ Spring sale postmortem Highlights, Ops scheduled in 2d ││ Old launch announcement News trash 30d ago ││ ││ [⋯ Edit] [⋯ Duplicate] [⋯ Categories] [⋯ Tags] [⋯ Delete] │└──────────────────────────────────────────────────────────────────────┘Actions
The Posts surface exposes the following operations.
List and search
Returns the post records, paginated, with title, author, categories, tags, status, and publication-date columns. Supports column sort, multi-faceted filter (status, category, tag, author, date range), and per-page count.
Create post
Opens an empty editor. Required: title. Optional and common: slug, body (classic HTML or SG-Builder canvas), excerpt, featured image, categories, tags, publication state, scheduled-publish date, SEO meta, and social-card overrides. On submit, the record persists in draft status by default.
Edit post
Loads an existing record into the editor. Submit replaces the stored state with the posted values. The editor remembers which write path the record uses — opening a Builder-authored post loads the Builder canvas, opening a classic post loads the rich-text editor.
Save and publish
Two-step publication, identical in shape to the Pages surface. Save persists the draft; Publish moves the record to published and stamps published_at. Schedule sets a future published_at and leaves the status as scheduled until the cron worker promotes it.
Duplicate
Creates a new post record with the same content, a copy-suffix in the title, a unique slug, and status: draft. Taxonomies (categories, tags) carry over; the duplicate is otherwise independent.
Soft delete
Marks the record as trash. Trashed posts disappear from the default list, the archive, the RSS feed, and any cross-referenced widget — immediately.
Restore
Returns a trashed post to its prior status. Slug uniqueness is rechecked; collision returns a structured rejection.
Permanent delete
Hard-removes a trashed record. Irreversible.
Per-post revision history
Same shape as the Pages revision system. Every save writes a revision row. The history view lists revisions in reverse-chronological order. Restore revision loads a historic snapshot back into the live record as a new save.
Manage categories
Categories live in a separate taxonomy table. The category panel exposes list, create, edit, delete, and merge operations. A post can belong to many categories; setting a category to "default" means new posts pick it up automatically.
Manage tags
Tags are a flat, non-hierarchical taxonomy. Same panel shape as categories — list, create, edit, delete. Tag creation can happen inline from the post editor (typing a new tag creates the row on save).
Manage custom taxonomies
Beyond the built-in Categories and Tags, the surface supports operator-defined taxonomies — for example, a "Region" taxonomy on news posts or an "Industry" taxonomy on case studies. Each custom taxonomy is itself a record (name, slug, hierarchy mode) with its own term list.
Set homepage post
A blog-specific homepage flag — pins a post to the top of the blog archive. Distinct from the site-wide homepage role (which is a Pages concern).
Update post configuration
Writes the blog-wide settings: default category, posts-per-page, archive layout, RSS feed visibility, social-card defaults, post-type slug.
Export posts
Produces a bundle of post records (and their taxonomies, revisions, and media references) suitable for re-import into another SGEN site.
Import posts
Bulk-loads posts from an exported bundle. Validates structure, resolves taxonomy collisions (merge or rename), and reports per-record success or skip.
Data model
A post record carries the following fields.
| Field | Type | Notes |
|---|---|---|
id | integer | Primary key. Stable across edits. |
type | enum | post, page, event, or a custom-object slug. The action layer keys on this. |
title | string | Display title. |
slug | string | URL segment. Unique across post records. |
status | enum | draft, published, scheduled, trash. |
body | text | Classic-editor HTML. Sanitized on save. |
canvas_state | JSON | Serialized SG-Builder component tree. Used when the Builder write path saved. |
write_path | enum | classic or builder. Determines render. |
excerpt | string | Optional. Used in archive cards and RSS. |
featured_image_id | integer | Foreign key to a Media record. |
categories | array | Many-to-many to the category taxonomy. |
tags | array | Many-to-many to the tag taxonomy. |
custom_taxonomies | object | Map of taxonomy slug → term array. |
seo_meta | JSON | Title, description, canonical, OpenGraph, schema. |
social_card | JSON | Per-post override of the default social card. |
author_id | integer | Foreign key to Users. |
published_at | timestamp | Set on publish, drives archive sort. |
created_at | timestamp | Immutable. |
updated_at | timestamp | Touched on save. |
andfrom the body and rewrites iframesrcdocattributes that carry embedded styles or scripts.Authors who need raw style or script must use the dedicated Custom CSS or Custom Codes modules.Shortcode interpolation.The body supports{{shortcode}}syntax.Shortcodes resolve on render,not on save — the stored body keeps the literal token.
Revision storage.Revisions write to a separate table,one row per save.The Settings module exposes a per-post retention cap.
POST RECORD TAXONOMY TABLES├── id ┌─────────────────┐├── type="post"│ categories │├── title,slug,status │ id name slug │ hierarchical├── body OR canvas_state └────────┬────────┘├──...│├── categories ───────────────────────►├── tags ──────────────────────────► ┌─────────────────┐├── custom_taxonomies │ tags ││"region"→["apac","emea"]│ id name slug │ flat│"industry"→["saas"]└─────────────────┘└── author_id ┌─────────────────┐│ custom taxonomy ││ per-slug term │ configurable│ list │└─────────────────┘Permissions
Access follows the standard admin gate plus per-action capability checks.
| Capability | Administrator | Editor | Author | Viewer |
|---|---|---|---|---|
| List posts | ✔ | ✔ | ✔ | ✔ |
| Create post | ✔ | ✔ | ✔ | — |
| Edit any post | ✔ | ✔ | — | — |
| Edit own posts | ✔ | ✔ | ✔ | — |
| Publish | ✔ | ✔ | — | — |
| Duplicate | ✔ | ✔ | — | — |
| Soft delete | ✔ | ✔ | own only | — |
| Restore | ✔ | ✔ | own only | — |
| Permanent delete | ✔ | — | — | — |
| Manage categories / tags | ✔ | ✔ | — | — |
| Manage custom taxonomies | ✔ | — | — | — |
| Restore revision | ✔ | ✔ | own only | — |
| Export bundle | ✔ | — | — | — |
| Import bundle | ✔ | — | — | — |
| Update post configuration | ✔ | — | — | — |
Audit.Every save,publish,schedule promotion,delete,restore,revision restore,taxonomy change,import,and configuration update emits an Activity Log entry.
POST EDITOR(write_path on record)│├─── classic ────────────────┐│ ▼│ ┌──────────────────────┐│ │ Body sanitizer │ strips<script>,<style>;│ │ │ rewrites iframe srcdoc│ └─────────┬────────────┘│ ││ ▼│ persist body(HTML)│└─── builder ────────────────┐▼┌──────────────────────┐│ Canvas serialization │ serialized component tree└─────────┬────────────┘▼persist canvas_state(JSON)Render path picks classic vs builder based on write_path flag.Related references
- Pages — Reference. Shares the same write surface and revision system. Many actions described here apply identically there.
- Events — Reference. Same — routes through this surface for its writes.
- Custom Objects — Reference. Operator-defined content types use this surface for save and lifecycle.
- Media — Reference. Featured-image references resolve against the Media library.
- SEO — Reference. Post SEO meta defaults (per-post-type) live under SEO.
- Users — Reference. Author attribution and capability checks resolve against the Users module.
- Settings — Reference. Revision retention, sanitizer rules, default categories live under Settings.
/docs/blog.