Publishr for Craft CMS

Editorial calendar for Craft CMS 5

Craft knows when it was published. Publishr knows the rest.

Craft does not know who is writing the next piece, when it is due, who has to sign it off, or that the pricing page has not been checked since 2021. Publishr keeps that second set of facts beside the content and puts them on a calendar. Lite plans the work. Pro governs it.

Publishr

Read-only in your templates

Everything on craft.publishr reads. Anything that changes a piece goes through a controller with a permission check on it, because a template is not the place a piece gets signed off from.

twig
{% set item = craft.publishr.item(entry) %}

{% if item %}
    {{ item.getStage().name }}
    {{ item.getAssignee().friendlyName ?? 'Unassigned' }}
    {% if item.isOverdue() %}{{ item.daysUntilDue()|abs }} days late{% endif %}
{% endif %}

{# Next month's plan, publish lane only #}
{% for day, events in craft.publishr.month(2026, 6, ['publish']) %}
    <h3>{{ day|date('j F') }}</h3>
    {% for event in events %}<p>{{ event.entry.title }}</p>{% endfor %}
{% endfor %}

Features

Lite covers the calendar, the board, stages, assignments and comments. Pro adds requirements, freshness, notifications and the report.

An entry is not an event

A piece has up to four dates worth seeing: when the work is due, when it publishes, when it expires and when it is next up for review. Each gets its own lane, so one piece can turn up on four different days in a month. That is the point.

  • Drafts that have never been published are on it
  • Drag a pip and the date its lane stands for is the one that moves

A stage is not a status

Craft answers "is this public". Publishr answers "where is this in the process". The two run side by side and never merge, so Publishr cannot break a front end. Switch it off and every entry is exactly as public as it was.

  • Idea, In progress, Needs edit, Ready, Published, or whatever your desk calls them
  • The stage survives every draft created, applied and thrown away underneath it

Owners and deadlines

Who owns this piece now, and when the work is due. Both are separate from the entry's author and post date, because the person who wrote it in March is rarely the person fixing it in October.

  • Days count in the site's time zone, at whole-day granularity
  • A met deadline is cleared when the piece goes live

Comments beside the piece, not in it

A threaded conversation stored next to the entry rather than in a field on it. It never renders on the site, never lands in a revision, and survives the draft it was written against. @name tells somebody.

Requirements at sign-off, not at save

Pro adds a checklist a piece must pass before it reaches a gated stage: required fields, a lead image with alt text, a minimum length, no open comments, boxes a person ticks, and a clean pass from RedPen if you have it.

  • Required blocks the move; advisory only warns
  • An override is allowed, and the overrider's name goes in the history

"I don't know" is never "no"

A requirement that cannot run is skipped, and a skipped requirement never blocks. RedPen not installed, a timeout, a custom gate that throws: none of those mean the copy failed. They mean nobody read it.

  • Uninstalling an optional plugin cannot lock a desk out of sign-off

Freshness reviews

Nothing on a website tells you it has gone out of date. Pro policies say how long a kind of content stays good for, and the clock runs from the last time a person said it was still true, not from the last re-save.

  • Never reviewed? The clock runs from the post date, so the first sweep finds the real backlog

A report on the desk, not the site

Pro's governance report shows how much of the site is on the calendar at all, where work piles up, who is carrying what, what is late, unowned or stale, and how much shipped each week. Plus a morning digest for anybody with something on their desk.

  • Median age per stage, not mean: every desk has one piece abandoned for eight months
  • CSV export

Alarm Clock is the engine

Craft fires no event when the clock passes a post date, so Publishr owns no scheduler. Alarm Clock notices the crossing and Publishr reacts: the piece moves to the published stage within a minute, its met deadline is cleared, and the freshness clock starts from the scheduled instant. Without Alarm Clock, one cron line catches up instead.

bash
# Idempotent. Every ten minutes and once a day are both correct;
# the only difference is how promptly a reminder arrives.
*/10 * * * *  cd /path/to/site && php craft publishr/sweep
0    8 * * *  cd /path/to/site && php craft publishr/sweep --digest=1

# Bring the content you already have onto the calendar
php craft publishr/track --section=news --dryRun=1

Frequently Asked Questions

The questions worth answering before you install it.

Lite plans the work, Pro governs it

Lite is $59: the four-lane calendar, the board, five stages, assignments, deadlines and comments. Pro is $129 and adds unlimited stages, publish requirements, freshness reviews, notifications and the governance report.