Features

Markdown

Content versioning & revisions

Externa uses a lean content versioning model: one published bag of field values plus optional draft_data. It is not Directus-style named version trees.

Schema changes with pending drafts

Renaming a field while items have pending drafts can lead to data loss when those drafts are published on older cores. From 1.2.1 renames preserve drafts; from 1.3.0 type / translatable flips with stored values are rejected. See Schema changes.

Enable

On the collection edit drawer, turn on Versioning. Editors then get Draft / Published workspaces on the item form.

Draft vs published

WorkspaceWhat you editSave
Draftdraft_data JSON bagSaves draft only; published values unchanged
PublishedLive field valuesRead-only when versioning is on — switch to Draft to edit

Badges on the item form (and a Draft chip on the items list) show whether an unpublished draft exists.

Publish (promote)

Publish copies draft_data into published field values, then clears the draft. Confirm before promote. Requires can-edit-collections and item write access.

When Approvals required is on, Publish is blocked until the item is approved — see Editorial approvals.

Discard draft

Discard draft drops draft_data without touching published values. Confirm before discard. Same permission gate as Publish.

Browser localStorage “unsaved draft” (autosave while typing) is separate — use Discard browser draft on that banner.

List filter

On versioned collections, Has draft filters the items list to rows with unpublished draft_data.

Revisions

Every save / draft save / publish / discard / hard restore can record a revision snapshot. Open History on the item toolbar (or the full revisions page). Soft-apply compares fields; Hard restore writes immediately and clears any draft.

Retention (count / days) is configured per collection or as a project default — it prunes old rows; it does not hide the History entry point.

Scheduled publish / unpublish

On a versioned item form, set Publish at / Unpublish at (app timezone), then Save schedule. Badge shows Scheduled when a future publish_at is set. Cancel schedule clears both timestamps.

  • Due drafts are promoted by collections:process-schedules (every minute via Laravel scheduler).
  • Due unpublish_at soft-deletes the item (same as trash).
  • Requires a running scheduler (schedule:run / Compose scheduler) — see Operations.
  • Emit webhook item.published with scheduled: true on scheduled promote (Outbound webhooks).
  • Failures (core 1.3.0+): if promote fails (e.g. approvals required but draft no longer approved, or another promote error), the cron persists schedule_error + schedule_failed_at on the item, keeps a paired unpublish_at, notifies the last editor/submitter and users with can-approve-collections, and emits item.publish_failed (core PR #303). The item form shows a failure alert; the list shows a badge. Successful promote, reschedule, schedule clear, or discard draft clears the failure state.

Ops note

Versioning is editorial only. Public CMS API returns published values unless you use Live Preview with version=draft. Scheduled publish needs the scheduler process running.