Content Workflow

Accent CMS provides a publishing workflow that lets you control when content is visible on your site. Pages can be drafts, under review, published, or archived, and you can schedule dates for automatic transitions.

Page Status

Every page has a status field in its frontmatter. The default status is published, so existing content continues to work without changes.

Available Statuses

StatusVisible by URLAppears in ListingsUse Case
draftDev mode onlyDev mode onlyWork in progress
reviewDev mode onlyDev mode onlyReady for editorial review
publishedYesYesLive content (default)
archivedYesNoOld content, accessible but hidden from navigation

Setting the Status

Add a status field to your page’s frontmatter:

---
title: My New Article
status: draft
---

This content is only visible in development mode.

Valid values are draft, review, published, and archived. If omitted, the page defaults to published.

Scheduled Publishing

You can set a future date when a page should become visible using publish_date:

---
title: Product Launch Announcement
status: published
publish_date: "2026-06-01"
---

We are excited to announce...

Before the publish_date, the page is treated as a draft (hidden from public view). On and after the date, the page becomes visible according to its status.

Automatic Archiving

Set unpublish_date to automatically archive content after a specific date:

---
title: Summer Sale
publish_date: "2026-06-01"
unpublish_date: "2026-09-01"
---

Limited time offer...

After the unpublish_date, the page is treated as archived: still accessible by direct URL but removed from navigation, listings, and collections.

Date Window Example

Combine both dates to create a visibility window:

---
title: Conference Registration
publish_date: "2026-03-01"
unpublish_date: "2026-05-15"
---

This page is:

  • Hidden before March 1, 2026
  • Visible from March 1 through May 15, 2026
  • Archived (hidden from listings) after May 15, 2026

Previewing Drafts

By default, draft and review pages are hidden. To preview them during development, enable show_drafts in your config.yaml:

dev:
  show_drafts: true

With this setting enabled, all draft and review pages are visible when running accent serve. This is useful for content authors who want to preview their work before publishing.

In production mode (--production flag) or when building with accent build, show_drafts is always forced to false, ensuring that unpublished content never appears on your live site.

Template Integration

The current page’s effective status is available in templates as page.status:

{% if page.status == "draft" %}
  <div class="draft-notice">
    This page is a draft and not yet published.
  </div>
{% endif %}

{% if page.status == "archived" %}
  <div class="archive-notice">
    This content has been archived and may be outdated.
  </div>
{% endif %}

Filtering in Collections

Pages excluded by status are automatically removed from template listings (pages, all_pages, and page.collection). You do not need to filter by status in your templates.

Backward Compatibility

The legacy published: false frontmatter field continues to work and is treated as status: draft. New content should use the status field instead:

# Legacy (still works)
published: false

# Recommended
status: draft

When both published: false and an explicit status are present, published: false takes priority and the page is treated as a draft.

Priority Rules

The effective status is resolved in the following order:

  1. published: false always maps to draft (backward compatibility)
  2. publish_date in the future maps to draft (not yet visible)
  3. unpublish_date in the past maps to archived (expired)
  4. The explicit status field value

Invalid date formats (anything other than YYYY-MM-DD) are logged as warnings and ignored. The page falls through to the next rule.

Redirects

Use the redirect frontmatter field to send visitors from one URL to another. This is useful for moved pages, vanity URLs, or making the root URL forward to a landing page.

Simple Redirect (302)

A string value creates a temporary redirect (HTTP 302):

---
title: Accent CMS
redirect: /home
---

When a visitor opens this page, the browser immediately navigates to /home. In serve mode this returns an HTTP 302 response with a Location header and Cache-Control: no-cache, so browsers re-resolve the target on every visit – you can freely change or remove the redirect later. In static builds it generates a meta-refresh HTML file.

Permanent Redirect (301)

Use the detailed form with code: 301 for a deliberate, permanent URL migration:

---
title: Moved Page
redirect:
  url: /new-location
  code: 301
---

Browsers cache 301 responses indefinitely, so once a visitor has seen one, they will keep jumping straight to the target even if you later change or remove the redirect. Reserve 301 for URL changes that are truly final; the default 302 is the right choice everywhere else.

External Redirects

Redirect targets can be external URLs:

---
title: GitHub
redirect: https://github.com/your-org/your-repo
---

How Redirects Work

ModeBehavior
accent serveReturns HTTP 301 or 302 with Location header
accent buildWrites a meta-refresh HTML file

Redirect pages are automatically excluded from content collections (page.collection) but remain visible in menus and page hierarchy, so you can use them as navigation stubs that point elsewhere.

The redirect target URL is available in templates as page.redirect.

Rewrites

Use the rewrite frontmatter field to serve another page’s content at the current URL. The browser URL does not change, but the visitor sees the target page’s rendered content.

---
title: Getting Started
rewrite: /docs/getting-started
---

This is useful for:

  • Aliases: Serve the same content at multiple URLs without duplication
  • Landing pages: Use a simple URL that renders a more deeply nested page

Rewrite Behavior

  • The target page is loaded and rendered using its own template and frontmatter
  • The browser URL remains the original page’s URL
  • Only one level of rewrite is followed (no chaining)
  • If the target does not exist, the original page is served and a warning is logged

The rewrite target URL is available in templates as page.rewrite.

Redirect vs Rewrite

RedirectRewrite
Browser URLChanges to targetStays the same
HTTP response301 or 302200
Use caseMoved pages, vanity URLsAliases, landing pages
Frontmatterredirect: /targetrewrite: /target

If both redirect and rewrite are set on the same page, redirect takes precedence. The content validator warns about this conflict.

Processing Control

The process frontmatter field controls which rendering stages apply to a page. This is separate from the publishing workflow but is another per-page control that affects how content is handled.

Disabling Markdown Rendering

Set process.markdown to false to skip the markdown parser entirely:

---
title: Custom HTML Page
process:
  markdown: false
---
<div class="custom-layout">
  <h1>Raw HTML</h1>
  <p>This content is passed to the template without markdown processing.</p>
</div>

The page remains routable, indexed, and visible according to its status. Only the rendering step changes: the content body goes directly to the template as-is instead of being parsed as markdown.

When omitted, process.markdown defaults to true (standard markdown rendering).

See Processing Control for full details on what is affected.

Content Versioning

Accent CMS supports versioned content trees for maintaining multiple versions of a documentation section (or any content area) side by side. Versions use a sparse folder structure: only pages that differ between versions need their own files. Missing pages automatically fall back to an older version.

Setting Up Versions

Create version folders inside your content section:

site/content/main/
  04.docs/
    v1.0/
      01.getting-started/default.md
      02.api-reference/default.md
    v1.1/
      01.getting-started/default.md   # updated for v1.1
      03.migration/default.md         # new in v1.1

In this example, /docs/v1.1/api-reference automatically serves the v1.0 content because v1.1 has no 02.api-reference/ folder. Only changed or new pages need to exist in the newer version.

Versioning Configuration

Register each versioning root in config.yaml:

versioning:
  roots:
    /docs:
      versions:
        v1.0:
          label: "1.0 (LTS)"
          badge: lts
        v1.1:
          label: "1.1 (Latest)"
          badge: latest
          fallback: v1.0
      default: v1.1
      redirects:
        v0.9: v1.0

See the Configuration Reference for all fields.

How Versioning Works

URLBehavior
/docs/v1.1/getting-startedServes v1.1 content directly
/docs/v1.1/api-referenceFalls back to v1.0 content (transparent, 200 response)
/docsRedirects to /docs/v1.1 (the default version)
/docs/v0.9/getting-startedRedirects to /docs/v1.0/getting-started (deprecated version)

Fallback is transparent: the URL stays the same and the response is 200. This applies in both accent serve and accent build (which writes fallback content to the target version’s output path).

Fallback Chains

Versions can chain fallbacks: v1.2 -> v1.1 -> v1.0. The resolver walks the chain up to 5 levels deep. Circular chains are detected at startup and rejected with a clear error message.

Template Integration

Templates receive a version context variable on versioned pages (see the Page Context guide for all properties). Include the version dropdown partial in any template:

{% include "partials/version-dropdown.html.jinja" %}

Show a notice when content comes from a fallback version:

{% if version.is_fallback %}
<div class="notice">
  This page has not been updated for {{ version.label }}.
  You are viewing the {{ version.source }} version.
</div>
{% endif %}

Quick Reference

# Simple draft
---
title: Work in Progress
status: draft
---

# Scheduled for future publication
---
title: Upcoming Feature
publish_date: "2026-06-01"
---

# Time-limited content
---
title: Holiday Special
publish_date: "2026-12-20"
unpublish_date: "2026-12-26"
---

# Archived content (accessible by URL, hidden from listings)
---
title: Old Documentation
status: archived
---

# Under editorial review
---
title: Pending Approval
status: review
---

# Raw HTML page (no markdown processing)
---
title: Design System
process:
  markdown: false
---

# Temporary redirect (302, the default)
---
title: Seasonal
redirect: /winter-sale
---

# Permanent redirect (301, deliberate URL migration)
---
title: Old Page
redirect:
  url: /new-page
  code: 301
---

# Rewrite (serve another page's content)
---
title: Alias
rewrite: /docs/getting-started
---