Appearance
Unpublish posts at a date in Laravel — PublishPress Future's data, no WordPress
An autumn sale ends on Sunday night. Someone has to take its page down on Monday morning, and usually nobody does: the offer stays on the site for a month, a customer quotes it at the till, and the price list on the about page still says "until October". The same happens to an event page after the event, a job ad after the deadline, a "New" badge on a product half a year old.
On WordPress, more than a hundred thousand sites hand this to PublishPress Future (it was Post Expirator before). kitloom/future-actions does the same on a Laravel site — and reads that plugin's own data, so a site that moves from WordPress keeps the actions it had scheduled.
Ask the agent
With kitloom/ai connected, an AI agent schedules actions with the rights of the user whose key it holds:
- "Take the autumn sale post off the site on Sunday at midnight."
- "Move every workshop post of October to Past workshops on November 1."
- "What is due to change on the site this week?"
It calls future_actions_schedule, future_actions_list and future_actions_cancel, and describe_site tells it which post types have future actions and what each does by default. An author's key schedules only on the author's own posts; sticking a post to the blog's top asks for the right to edit others' posts, as WordPress asks it; nothing is deleted for good by a timer — a delete becomes the trash. How to connect one: Run your site from Claude or Cursor.
On the post's form
Every post and page gets a Future action box: Enable future action, When, and the Action:
| Action | What happens at the date |
|---|---|
| Change status to draft, pending or private | the record leaves the site, or is kept for signed-in users |
| Move to the trash | into the trash, where it can be restored |
| Stick, Unstick | on or off the top of the blog |
| Replace, add or remove terms | the categories or tags you pick; or all of them come off |
The list of posts has a Future action column and filter, and a bulk action that gives many posts the same action at once. Future Actions → Scheduled lists everything that waits, of every type, the nearest first, with Cancel. In Settings, each post type is turned on or off and gets its default action and date — +1 week, or its own — and the addresses that hear when an action was done.
A sentence of the post can carry the date itself: "Every reading lamp is a fifth off until [futureaction type=date]." When the action is done or cancelled, the shortcode writes nothing.
The data is the plugin's
The action of a record is kept where PublishPress Future keeps it — post meta _expiration-date, _expiration-date-status, _expiration-date-type and the rest — and its options under the plugin's names (expirationdateDefaultsPost, expirationdateEmailNotification). The plugin keeps its own schedule in Action Scheduler, but it writes that meta on every schedule and can rebuild its schedule from it. So a WordPress site that moves to kitloom keeps every waiting action with nothing to import, and [futureaction] and the older [postexpirator] in its content keep showing their dates.
Done by the scheduler
future-actions:run runs every minute from Laravel's scheduler — the usual schedule:run cron line of the server. It does each action through the same writers the admin uses, so the change is announced as an edit would be: the activity log, webhooks, the page cache and the term counts follow. An action that fails — a post someone deleted meanwhile — is turned off and reported, and kitloom/notifications can send that to a Telegram or Slack channel (Future action failed).
The same cron line now also publishes scheduled posts at their time: a post dated ahead goes live by itself, as WordPress's publish_future_post does.
Watch it
Try it
Open a sandbox in one click, with no sign-up: Filament or Nova. Every detail of the module is in the Future Actions guide.