Skip to content

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_at empty or in the past → served immediately.
  • Schedule — status published with a future published_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