{"id":315284,"date":"2026-05-21T00:22:50","date_gmt":"2026-05-21T00:22:50","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/effortless-timeline-posts\/"},"modified":"2026-05-21T01:51:00","modified_gmt":"2026-05-21T01:51:00","slug":"effortless-timeline-posts","status":"publish","type":"plugin","link":"https:\/\/wol.wordpress.org\/plugins\/effortless-timeline-posts\/","author":23148025,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.0.32","stable_tag":"1.0.32","tested":"7.0","requires":"5.0","requires_php":"7.0","requires_plugins":null,"header_name":"EffortLess Timeline Posts","header_author":"domclic","header_description":"Timeline with complete dates, duration and chronological sorting.","assets_banners_color":"","last_updated":"2026-05-21 01:51:00","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"","rating":0,"author_block_rating":0,"active_installs":0,"downloads":37,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","changelog"],"tags":{"1.0.31":{"tag":"1.0.31","author":"domclic","date":"2026-05-21 00:22:13"},"1.0.32":{"tag":"1.0.32","author":"domclic","date":"2026-05-21 01:51:00"}},"upgrade_notice":[],"ratings":[],"assets_icons":[],"assets_banners":[],"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.31","1.0.32"],"block_files":[],"assets_screenshots":[],"screenshots":[]},"plugin_section":[],"plugin_tags":[1584,1794,1433,80,5575],"plugin_category":[43],"plugin_contributors":[241557],"plugin_business_model":[],"class_list":["post-315284","plugin","type-plugin","status-publish","hentry","plugin_tags-chronology","plugin_tags-custom-post-type","plugin_tags-history","plugin_tags-shortcode","plugin_tags-timeline","plugin_category-customization","plugin_contributors-domclic","plugin_committers-domclic"],"banners":[],"icons":{"svg":false,"icon":"https:\/\/s.w.org\/plugins\/geopattern-icon\/effortless-timeline-posts.svg","icon_2x":false,"generated":true},"screenshots":[],"raw_content":"<!--section=description-->\n<p>Creates a custom post type \"Timeline\" with date\/year meta, categories, and shortcode [timeline] for chronological display. Supports full dates, durations, custom labels, year-only mode. Admin columns sortable by date\/year.<\/p>\n\n<h3>Usage<\/h3>\n\n<ul>\n<li>Full Date: Set start\/end, optional custom display.<\/li>\n<li>Year Only: Large year display.<\/li>\n<li>Sorted automatically by <code>_sort_timestamp<\/code>.<\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Upload plugin folder to <code>\/wp-content\/plugins\/<\/code>.<\/li>\n<li>Activate via Plugins menu.<\/li>\n<li>Add entries under \"Timeline\" post type.<\/li>\n<li>Use <code>[timeline]<\/code> shortcode in pages\/posts.<\/li>\n<\/ol>\n\n<p>Attributes: <code>limit<\/code> (default -1), <code>category<\/code> (slug), <code>order<\/code> (ASC\/DESC).<\/p>\n\n<!--section=changelog-->\n<h4>1.0.32<\/h4>\n\n<ul>\n<li>WordPress 7.0 update<\/li>\n<\/ul>\n\n<h4>1.0.31<\/h4>\n\n<ul>\n<li>Fix: completed eltlp_ prefix rename \u2014 settings page HTML form attributes (id, name, for) and color-picker CSS class were still using etp_ prefix; all updated to eltlp_.<\/li>\n<\/ul>\n\n<h4>1.0.30<\/h4>\n\n<ul>\n<li>Security: replaced $_GET['post'] in admin_notices() with global $post object \u2014 no nonce required for a read-only post ID lookup.<\/li>\n<li>Fix: renamed CPT to eltlp_timeline, taxonomy to eltlp_timeline_cat, shortcode to [eltlp_timeline], all option\/transient keys to eltlp_ prefix, class to ELTLP_Timeline_Posts, constant to ELTLP_VERSION.<\/li>\n<\/ul>\n\n<h4>1.0.29<\/h4>\n\n<ul>\n<li>Fix: added inline phpcs:ignore on the constant and class declaration so Plugin Check suppresses PrefixAllGlobals warnings regardless of its prefix configuration.<\/li>\n<\/ul>\n\n<h4>1.0.28<\/h4>\n\n<ul>\n<li>Fix: constant renamed to EFFORTLESS_TIMELINE_POSTS_VERSION and class to Effortless_Timeline_Posts to match the slug-derived prefix that Plugin Check enforces.<\/li>\n<\/ul>\n\n<h4>1.0.27<\/h4>\n\n<ul>\n<li>Fix: renamed class to EffortLess_TimeLine_Posts; updated phpcs.xml to declare ELTLP_ and EffortLess_TimeLine_Posts_ as valid prefixes.<\/li>\n<\/ul>\n\n<h4>1.0.26<\/h4>\n\n<ul>\n<li>Fix: renamed version constant to ELTLP_VERSION and updated phpcs.xml to declare eltlp_\/ELTLP_ as the canonical plugin prefix.<\/li>\n<\/ul>\n\n<h4>1.0.25<\/h4>\n\n<ul>\n<li>Fix: renamed constant ETP_VERSION \u2192 EFFORTLESS_TIMELINE_POSTS_VERSION and class EffortLess_Timeline_Posts \u2192 Effortless_Timeline_Posts to satisfy WordPress.NamingConventions.PrefixAllGlobals.<\/li>\n<li>Code: added phpcs.xml with explicit prefix configuration so local PHPCS enforces the same rule.<\/li>\n<\/ul>\n\n<h4>1.0.24<\/h4>\n\n<ul>\n<li>Code: rewrote timeline-script.js to pass WordPress PHPCS standard (tabs, multi-line call formatting, @package tag, period-terminated inline comments).<\/li>\n<\/ul>\n\n<h4>1.0.23<\/h4>\n\n<ul>\n<li>Improvement: \"Show Era Boundary\" toggle \u2014 displays a styled divider line between BC and AD entries on the timeline.<\/li>\n<li>Improvement: \"Era Terminology\" radio \u2014 choose BC\/AD (traditional) or BCE\/CE (modern). Applies to year labels and the divider.<\/li>\n<\/ul>\n\n<h4>1.0.22<\/h4>\n\n<ul>\n<li>Improvement: Settings &gt; \"Show Year Labels\" toggle \u2014 uncheck to hide the year column and display a compact full-width timeline.<\/li>\n<li>Improvement: any change to a plugin setting now automatically busts the shortcode transient cache.<\/li>\n<\/ul>\n\n<h4>1.0.21<\/h4>\n\n<ul>\n<li>Improvement: year field now accepts BC dates (-9999 to 9999). Enter -2580 for 2580 BC.<\/li>\n<li>Improvement: BC years display as \"2580 BC\" on the timeline and in admin columns.<\/li>\n<li>Fix: negative years were stripped to positive by absint(); now uses intval() to preserve sign.<\/li>\n<li>Fix: sort timestamp falls back to year \u00d7 31 557 600 when strtotime() cannot parse ancient dates.<\/li>\n<\/ul>\n\n<h4>1.0.20<\/h4>\n\n<ul>\n<li>Improvement: \"Show Today\" toggle in Settings \u2014 displays a hollow marker at today's date position, sorted correctly among all entries. Works even with no real entries. Bypasses transient cache while active.<\/li>\n<\/ul>\n\n<h4>1.0.19<\/h4>\n\n<ul>\n<li>Fix: entries dated exactly 1970 (Unix epoch, timestamp = 0) were incorrectly filtered out and never displayed.<\/li>\n<\/ul>\n\n<h4>1.0.18<\/h4>\n\n<ul>\n<li>Improvement: added Settings page under Timeline menu with shortcode reference (all attributes, defaults, examples) and existing categories with ready-to-use shortcodes.<\/li>\n<li>Improvement: color pickers on Settings page let admins change the timeline line color and dot color without editing CSS.<\/li>\n<\/ul>\n\n<h4>1.0.17<\/h4>\n\n<ul>\n<li>Fix: replace named global function in uninstall.php with call_user_func closure to eliminate global namespace warnings.<\/li>\n<\/ul>\n\n<h4>1.0.16<\/h4>\n\n<ul>\n<li>Fix: wrap uninstall logic in a prefixed function to avoid global variable scope warnings.<\/li>\n<\/ul>\n\n<h4>1.0.15<\/h4>\n\n<ul>\n<li>Fix: removed load_plugin_textdomain() \u2014 WordPress auto-loads translations since 4.6.<\/li>\n<li>Fix: prefixed global variables in uninstall.php to avoid namespace collisions.<\/li>\n<li>Fix: added phpcs:ignore for the_content core hook (not a custom hook).<\/li>\n<li>Fix: updated \"Tested up to\" to WordPress 6.9.<\/li>\n<\/ul>\n\n<h4>1.0.14<\/h4>\n\n<ul>\n<li>Improvement: CSS and JS now load only on pages that use the [timeline] shortcode.<\/li>\n<li>Improvement: activation and deactivation hooks flush rewrite rules so CPT slugs work immediately.<\/li>\n<li>Improvement: added uninstall.php to clean up plugin meta keys and transients on deletion.<\/li>\n<li>Improvement: meta fields registered via register_post_meta() for REST API and block editor access.<\/li>\n<li>Improvement: shortcode output cached with transients; cache busts automatically on save or delete.<\/li>\n<li>Improvement: recursion guard prevents infinite loop if [timeline] appears in an entry's content.<\/li>\n<li>Improvement: new heading shortcode attribute (h2\u2013h6) for correct document outline control.<\/li>\n<li>Improvement: timeline wrapper gets role=\"region\" and aria-label; marker gets aria-hidden; articles get aria-label.<\/li>\n<li>Improvement: admin notices shown when date\/year fields are silently cleared by validation.<\/li>\n<li>Improvement: featured image (thumbnail) added to CPT supports.<\/li>\n<li>Improvement: menu_position changed from 5 (conflicts with Posts) to 20.<\/li>\n<li>Improvement: generated languages\/effortless-timeline-posts.pot for translators.<\/li>\n<\/ul>\n\n<h4>1.0.13<\/h4>\n\n<ul>\n<li>Security: validate year_only as integer clamped to 1900\u20132100 (server-side).<\/li>\n<li>Security: reject full_date\/end_date that don't match YYYY-MM-DD format.<\/li>\n<li>Fix: format_date() returns empty string instead of \"January 1, 1970\" for invalid dates.<\/li>\n<li>Fix: correct phpcs:ignore sniff name on virtual stylesheet handle.<\/li>\n<\/ul>\n\n<h4>1.0.12<\/h4>\n\n<ul>\n<li>Fix: allowlist <code>_date_type<\/code> values to prevent arbitrary meta storage.<\/li>\n<li>Fix: guard <code>strtotime()<\/code> return value before writing timestamp\/year meta.<\/li>\n<li>Fix: apply category filter before limit so <code>limit<\/code> counts filtered results.<\/li>\n<li>Fix: admin sort direction now respects the URL <code>order<\/code> parameter.<\/li>\n<li>Fix: shortcode output wrapped in <code>.timeline-dotcom<\/code> container (CSS max-width was broken).<\/li>\n<li>Fix: prime post meta cache before loop (single DB query instead of N\u00d76).<\/li>\n<li>Fix: load plugin textdomain so translations work.<\/li>\n<li>Fix: move meta box inline CSS and JS to properly enqueued handles.<\/li>\n<li>Fix: use <code>ETP_VERSION<\/code> constant for asset versioning.<\/li>\n<\/ul>\n\n<h4>1.0.11<\/h4>\n\n<ul>\n<li>Code: fix all PHPCS WordPress standard violations (tabs, alignment, short ternary, globals, comment style).<\/li>\n<\/ul>\n\n<h4>1.0.10<\/h4>\n\n<ul>\n<li>Initial release.<\/li>\n<\/ul>","raw_excerpt":"Timeline with complete dates, duration and chronological sorting.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wol.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/315284","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wol.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wol.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wol.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=315284"}],"author":[{"embeddable":true,"href":"https:\/\/wol.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/domclic"}],"wp:attachment":[{"href":"https:\/\/wol.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=315284"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wol.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=315284"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wol.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=315284"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wol.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=315284"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wol.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=315284"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wol.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=315284"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}