Simpli Revisions self-updates
Optimise WordPress by cleaning up post revisions
by Jon Mather · github.com/westcoastdigital/simpli-revisions
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/westcoastdigital/simpli-revisions/archive/refs/heads/main.zipShips its own WordPress updater (built-in updater), so new versions show up under Dashboard → Updates.
Readme
Simpli Revisions
Cleans up WordPress post revisions on demand. No cron, no auto-delete — you look at the numbers, choose how many to keep, and confirm.
For users
Tools → Revisions
- Top of page: total revision count and an estimated database size.
- Keep last: how many of the newest revisions to keep per post. Defaults to 5.
- Clean Up Revisions: asks you to confirm, then deletes every revision older than the newest N for every post on the site. This cannot be undone.
- View Revisions by Post: expands a table of every post/page that has revisions — title (linked to the editor), post type, revision count, and estimated size — sorted by count, worst offenders first. Click again to collapse it. It refreshes automatically after a cleanup if it's open; otherwise it just refetches next time you open it.
- There's also a Revisions link on the Plugins list page for quick access, next to Deactivate.
The size shown is an estimate (post_content + post_title +
post_excerpt length for revision rows), not a SHOW TABLE STATUS
figure — it's meant to give a sense of scale, not an exact byte count.
For developers
Flat procedural plugin, no build step, no external dependencies.
simpli-revisions.php Plugin bootstrap, all PHP logic, AJAX handlers
templates/page.php Admin page markup (included, not templated)
assets/admin.js Vanilla JS — fetch + DOM, no jQuery
Core functions
| Function | Purpose |
|---|---|
sw_rev_get_stats() |
['count' => int, 'bytes' => int] — site-wide totals. |
sw_rev_get_stats_by_post() |
Array of ['post_id', 'title', 'edit_link', 'post_type', 'count', 'bytes'], one row per parent post, sorted by count desc. |
sw_rev_cleanup_revisions( $keep = 5 ) |
Deletes all but the newest $keep revisions per post via wp_delete_post_revision(). Returns number deleted. |
sw_rev_capability() |
Capability required to view the page and hit the AJAX endpoints. |
sw_rev_default_keep() |
Default "keep" value, used by the AJAX handler fallback and the admin field. |
All three data functions are safe to call directly from other code
(e.g. WP-CLI commands, a scheduled cron job, a dashboard widget) — they
don't touch $_POST or output anything.
Filters
// Require a custom capability instead of manage_options
add_filter( 'sw_rev_capability', function () {
return 'edit_others_posts';
} );
// Change the default "keep" count
add_filter( 'sw_rev_default_keep', function () {
return 10;
} );
AJAX endpoints
Both require current_user_can( sw_rev_capability() ) and a
sw_rev_cleanup nonce (swRev.nonce, localized to admin.js).
wp_ajax_sw_rev_cleanup—POST { action, nonce, keep }→{ deleted, stats }wp_ajax_sw_rev_by_post—POST { action, nonce }→{ posts: [...] }
Extending
- Deletion behaviour:
sw_rev_cleanup_revisions()uses core'swp_delete_post_revision(), so anything already hookingdelete_post/deleted_poston revision deletes fires as normal — no separate hook needed on our side. - Excluding post types or specific posts: not built in. The
cleanest way to add it is a guard at the top of the loop in
sw_rev_cleanup_revisions()— skip$parent_idbased onget_post_type( $parent_id )before callingwp_delete_post_revision(), and mirror the same check insw_rev_get_stats()/sw_rev_get_stats_by_post()so the UI numbers match what cleanup will actually do. - New admin UI:
templates/page.phpis a plain include withsw_rev_get_stats()already in scope — add markup and wire it up inassets/admin.jsthe same way the existing table is (afetch()toswRev.ajaxUrlwithswRev.nonce). - Scheduling: there's no cron here by design (see "For users"
above). To automate it, hook
wp_scheduled_deleteor your own cron event and callsw_rev_cleanup_revisions( $keep )directly — it's a plain function, not gated behind the AJAX/nonce layer.