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
| Status | Visible by URL | Appears in Listings | Use Case |
|---|---|---|---|
draft | Dev mode only | Dev mode only | Work in progress |
review | Dev mode only | Dev mode only | Ready for editorial review |
published | Yes | Yes | Live content (default) |
archived | Yes | No | Old 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:
published: falsealways maps todraft(backward compatibility)publish_datein the future maps todraft(not yet visible)unpublish_datein the past maps toarchived(expired)- The explicit
statusfield 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
| Mode | Behavior |
|---|---|
accent serve | Returns HTTP 301 or 302 with Location header |
accent build | Writes 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
| Redirect | Rewrite | |
|---|---|---|
| Browser URL | Changes to target | Stays the same |
| HTTP response | 301 or 302 | 200 |
| Use case | Moved pages, vanity URLs | Aliases, landing pages |
| Frontmatter | redirect: /target | rewrite: /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
| URL | Behavior |
|---|---|
/docs/v1.1/getting-started | Serves v1.1 content directly |
/docs/v1.1/api-reference | Falls back to v1.0 content (transparent, 200 response) |
/docs | Redirects to /docs/v1.1 (the default version) |
/docs/v0.9/getting-started | Redirects 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 ---