{"id":299766,"date":"2026-05-06T12:23:42","date_gmt":"2026-05-06T12:23:42","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/content-expiry\/"},"modified":"2026-05-06T12:23:54","modified_gmt":"2026-05-06T12:23:54","slug":"stalepilot","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/stalepilot\/","author":21092980,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.0.2","stable_tag":"1.0.2","tested":"7.0","requires":"6.6","requires_php":"7.4","requires_plugins":null,"header_name":"StalePilot - Content Expiry & Scheduled Post Actions","header_author":"Teydea Studio","header_description":"Control what happens to content after it expires: change status, notify editors, and display countdowns.","assets_banners_color":"","last_updated":"2026-05-06 12:23:54","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"https:\/\/teydeastudio.com\/?utm_source=WP+StalePilot","rating":0,"author_block_rating":0,"active_installs":0,"downloads":22,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.2":{"tag":"1.0.2","author":"teydeastudio","date":"2026-05-06 12:23:54"}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3524397,"resolution":"128x128","location":"assets","locale":""},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3524397,"resolution":"256x256","location":"assets","locale":""},"icon.svg":{"filename":"icon.svg","revision":3524397,"resolution":false,"location":"assets","locale":false}},"assets_banners":[],"assets_blueprints":{},"all_blocks":{"stalepilot\/countdown":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"stalepilot\/countdown","title":"Countdown","category":"widgets","icon":"clock","description":"Display a countdown timer or static date for the content expiry.","textdomain":"stalepilot","usesContext":["postId","postType"],"attributes":{"displayMode":{"type":"string","default":"countdown"},"dateFormat":{"type":"string","default":"F j, Y g:i a"},"prefixText":{"type":"string","default":""},"suffixText":{"type":"string","default":""},"expiredMessage":{"type":"string","default":""},"countdownFormat":{"type":"string","default":"compact"},"warningThresholdValue":{"type":"number","default":2},"warningThresholdUnit":{"type":"string","default":"days"},"warningColor":{"type":"string","default":""},"urgentThresholdValue":{"type":"number","default":12},"urgentThresholdUnit":{"type":"string","default":"hours"},"urgentColor":{"type":"string","default":""}},"supports":{"color":{"text":true,"background":false},"spacing":{"margin":["horizontal","vertical"],"padding":["horizontal","vertical"]},"typography":{"fontSize":true,"lineHeight":true,"__experimentalFontFamily":true,"__experimentalFontWeight":true,"__experimentalFontStyle":true,"__experimentalTextTransform":true,"__experimentalDefaultControls":{"fontSize":true}}},"editorScript":"file:.\/index.js","viewScript":"file:.\/view.js","style":"file:.\/index.css"},"stalepilot\/timed-content":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"stalepilot\/timed-content","title":"Timed Content","category":"widgets","icon":"visibility","description":"Show or hide inner blocks based on a date\/time condition.","textdomain":"stalepilot","usesContext":["postId","postType"],"attributes":{"visibilityMode":{"type":"string","default":"show-until"},"dateTime":{"type":"string","default":""},"relativeEnabled":{"type":"boolean","default":false},"relativeValue":{"type":"number","default":7},"relativeUnit":{"type":"string","default":"days"},"usePostExpiry":{"type":"boolean","default":false}},"example":{"innerBlocks":[{"name":"core\/paragraph","attributes":{"content":"This content will be shown or hidden based on the schedule."}}]},"editorScript":"file:.\/index.js","editorStyle":"file:.\/index.css"}},"tagged_versions":["1.0.2"],"block_files":[],"assets_screenshots":[],"screenshots":[],"jetpack_post_was_ever_published":false},"plugin_section":[],"plugin_tags":[56514,4917,262017,56512,20954],"plugin_category":[],"plugin_contributors":[162490,223836],"plugin_business_model":[],"class_list":["post-299766","plugin","type-plugin","status-publish","hentry","plugin_tags-content-expiry","plugin_tags-content-management","plugin_tags-expiration-date","plugin_tags-post-expiry","plugin_tags-scheduled-content","plugin_contributors-bartoszgadomski","plugin_contributors-teydeastudio","plugin_committers-teydeastudio","plugin_support_reps-bartoszgadomski"],"banners":[],"icons":{"svg":"https:\/\/ps.w.org\/stalepilot\/assets\/icon.svg?rev=3524397","icon":"https:\/\/ps.w.org\/stalepilot\/assets\/icon.svg?rev=3524397","icon_2x":false,"generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p><strong>StalePilot lets you set an expiry date on any post type and automatically take action when that date arrives.<\/strong><\/p>\n\n<p>Whether you manage time-sensitive promotions, seasonal content, legal notices with review deadlines, or news articles that lose relevance, StalePilot gives you the tools to handle content lifecycle directly within WordPress.<\/p>\n\n<p><strong>Key benefits:<\/strong><\/p>\n\n<ul>\n<li>Automatically move expired content to draft, private, or trash - no manual cleanup needed.<\/li>\n<li>Get notified by email before and after content expires, so nothing slips through the cracks.<\/li>\n<li>Show visitors countdown timers and timed content blocks that respond to expiry dates.<\/li>\n<li>Manage expiring content at scale with bulk edit, quick edit, and a dashboard widget.<\/li>\n<\/ul>\n\n<p>StalePilot works with posts, pages, and custom post types. It integrates with both the Block Editor (Gutenberg) and the Classic Editor.<\/p>\n\n<h3>Features<\/h3>\n\n<ul>\n<li><strong>Expiry Date and Action<\/strong> - Set an expiry date and time on any supported post type, and choose what happens: Move to Draft, Make Private, or Move to Trash.<\/li>\n<li><strong>Block Editor Integration<\/strong> - Sidebar panel in Gutenberg for configuring expiry date, time, and action.<\/li>\n<li><strong>Classic Editor Integration<\/strong> - Metabox in the sidebar for configuring expiry on sites using the Classic Editor.<\/li>\n<li><strong>Posts List Column<\/strong> - Sortable expiry column in admin list tables showing scheduled or past expiry dates.<\/li>\n<li><strong>Expired Posts Filter<\/strong> - Dedicated \"Expired\" view in the posts list with a count of expired posts.<\/li>\n<li><strong>Quick Edit and Bulk Edit<\/strong> - Edit expiry settings inline or for multiple posts at once.<\/li>\n<li><strong>Dashboard Widget<\/strong> - \"Expiring Soon\" widget showing posts approaching their expiry date within a configurable time window.<\/li>\n<li><strong>Email Notifications<\/strong> - Get notified when content expires, with optional pre-expiry warnings (1, 3, or 7 days before).<\/li>\n<li><strong>Configurable Recipients<\/strong> - Send notifications to specific user roles or individual users.<\/li>\n<li><strong>Expiry Countdown Block<\/strong> - Display a live countdown timer or static date on the front end, with customizable colors and thresholds. Also available as a <code>[stalepilot_countdown]<\/code> shortcode.<\/li>\n<li><strong>Timed Content Block<\/strong> - Show or hide content based on a date, relative time from publish, or the post's expiry date. Also available as a <code>[stalepilot_timed_content]<\/code> shortcode.<\/li>\n<li><strong>Automatic Scheduling<\/strong> - Expiry is automatically cancelled on trash\/delete and rescheduled on restore.<\/li>\n<li><strong>Developer Hooks<\/strong> - Extensible via actions and filters for custom integrations.<\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>stalepilot<\/code> directory to <code>\/wp-content\/plugins\/<\/code>, or install it directly through the WordPress plugin screen.<\/li>\n<li>Activate the plugin through the \"Plugins\" screen in WordPress.<\/li>\n<li>Go to <strong>Settings &gt; StalePilot<\/strong> to choose which post types support expiry and configure default actions and notifications.<\/li>\n<li>Edit any post or page and use the \"StalePilot\" panel in the sidebar to set an expiry date and action.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"which%20post%20types%20are%20supported%3F\"><h3>Which post types are supported?<\/h3><\/dt>\n<dd><p>By default, StalePilot is enabled for posts and pages. You can enable it for any public custom post type in the plugin settings under <strong>Settings &gt; StalePilot<\/strong>.<\/p><\/dd>\n<dt id=\"what%20happens%20when%20a%20post%20expires%3F\"><h3>What happens when a post expires?<\/h3><\/dt>\n<dd><p>The plugin performs the action you selected for that post: it moves the post to draft, makes it private, or moves it to trash. You can set a default action in the settings and override it per post.<\/p><\/dd>\n<dt id=\"can%20i%20display%20a%20countdown%20timer%20on%20the%20front%20end%3F\"><h3>Can I display a countdown timer on the front end?<\/h3><\/dt>\n<dd><p>Yes. The plugin includes an Expiry Countdown block (and a <code>[stalepilot_countdown]<\/code> shortcode) that displays either a live countdown timer or a static formatted date. You can customize colors, threshold warnings, and the expired message.<\/p><\/dd>\n<dt id=\"what%20happens%20if%20i%20restore%20a%20trashed%20post%20that%20had%20an%20expiry%20date%3F\"><h3>What happens if I restore a trashed post that had an expiry date?<\/h3><\/dt>\n<dd><p>If the expiry date is still in the future, the plugin automatically reschedules the expiry. If the expiry date has already passed, the stale expiry metadata is cleaned up.<\/p><\/dd>\n<dt id=\"where%20can%20i%20find%20the%20unminified%20source%20code%3F\"><h3>Where can I find the unminified source code?<\/h3><\/dt>\n<dd><p>All source ships with the plugin: the plugin's own JavaScript is in <code>src\/<\/code>, and the bundled <code>@teydeastudio\/components<\/code> and <code>@teydeastudio\/utils<\/code> libraries are in <code>deps\/js\/components\/src\/<\/code> and <code>deps\/js\/utils\/src\/<\/code>. To rebuild, install Node.js 20 and run <code>npm install &amp;&amp; npm run build<\/code> in the plugin directory.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.0.2 (2026-04-27)<\/h4>\n\n<ul>\n<li>An FAQ entry added to readme.txt, explaining where the unminified source code lives in the plugin and how to rebuild it from source<\/li>\n<\/ul>\n\n<h4>1.0.1 (2026-04-24)<\/h4>\n\n<ul>\n<li>The \"Pre-expiry warning\" and \"Dashboard widget window\" settings now accept any number of days within a reasonable range, with quick-set presets for common values<\/li>\n<li>Direct loading of wp-includes\/version.php in the WordPress version detection fallback removed<\/li>\n<\/ul>\n\n<h4>1.0.0 (2026-04-07)<\/h4>\n\n<ul>\n<li>Initial release.<\/li>\n<\/ul>","raw_excerpt":"Set expiry dates on posts and pages to automatically change status, notify editors, and display countdowns.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/299766","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=299766"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/teydeastudio"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=299766"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=299766"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=299766"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=299766"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=299766"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=299766"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}