Versioning & scheduling
Every page carries its own history, and going live can be scheduled — both fall out of the store's design, with no separate workflow to configure.
A version snapshot on every save
Tiger_Model_Page::save() snapshots the saved content to the append-only page_version table on every save — whether you saved from the page editor, the visual builder, or the /api service. Each snapshot records the title, body, format, meta, and status under an incrementing version number, so page_version[max] always mirrors the live page.
Versions are immutable: no update, no soft-delete. The write and the snapshot happen in one transaction, so a page and its history can't diverge.
You see the history in the editor (the most recent versions, newest first — Tiger_Model_PageVersion::recentForPage).
Restore any prior version
Restoring rolls the page back to an earlier snapshot. restoreVersion() copies that version's content (title, body, format, meta, status) back onto the page — which, because it's a normal save, snapshots as a new version. So restoring is non-destructive: nothing in the history is ever lost, and you can restore forward again to what you had before.
From the admin this is a one-click action in the version history; over /api it's Cms_Service_Page::restore (page_id + version, admin+). (The model method is named restoreVersion to keep it distinct from Tiger_Model_Table::restore(), which is the soft-delete undelete.)
Scheduled publish
A page's status (draft / published / archived) and its published_at timestamp together give scheduling with no extra machinery:
- Publish now — status
published,published_atempty or in the past → served immediately. - Schedule — status
publishedwith a futurepublished_at→ the page is not served until that time arrives.
The public dispatch gate is:
status = 'published' AND (published_at IS NULL OR published_at <= NOW())
so a scheduled page goes live automatically the moment its time passes — no cron job, no publish queue, no approval step. The gate is applied identically by slug dispatch and by CMS/blog search, so a scheduled-but-not-live page can never leak into either. In the content list a scheduled page is flagged until it's live.
Set published_at in the editor (format YYYY-MM-DD HH:MM:SS); leave it empty to publish immediately.
See also
- Pages — status,
published_at, and slug dispatch - The visual builder — builder saves snapshot too