* Creates a real-time countdown timer displaying days, hours, minutes, and seconds * until a specified date. Uses WordPress timezone settings and validates date input. * * CONFIGURATION REQUIRED * - CSS: Style classes .countdown-timer, .countdown-segment, .countdown-number, .countdown-label * - WordPress: Ensure timezone is set correctly in Settings > General * - Date Format: Must use dd/mm/yyyy format (e.g., 31/12/2025) * - Time Format: HH:MM:SS or HH:MM (24-hour format) in local timezone. Default: 00:00:00 (midnight) * - End Text: Optional text to display when countdown reaches zero. * * USAGE

* [countdown date="31/12/2025"] * [countdown date="01/01/2026"] * * NOTES * - Supports multiple timers on same page via static counter * - Countdown stops at zero (doesn't go negative) * - Uses site timezone from WordPress settings * - JavaScript updates every second * - Timer starts automatically on page load * - Falls back gracefully with error messages for invalid dates */ add_shortcode( 'countdown', function ( $atts ) { static $count = 0; ++$count; // Register script handle once static $script_enqueued = false; if ( ! $script_enqueued ) { wp_register_script( 'bld-countdown-timer', '', [], false, true ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.NoExplicitVersion wp_enqueue_script( 'bld-countdown-timer' ); $script_enqueued = true; } $atts = shortcode_atts( [ 'date' => '', // expects dd/mm/yyyy, 'end_text' => '', 'time' => '00:00:00', // expects HH:MM:SS or HH:MM in 24-hour format ], $atts, 'countdown' ); if ( empty( $atts['date'] ) ) { return '

Countdown date not set.

'; } // Convert dd/mm/yyyy to yyyy-mm-dd $parts = explode( '/', $atts['date'] ); if ( count( $parts ) !== 3 ) { return '

Invalid date format. Use dd/mm/yyyy.

'; } list($day, $month, $year) = $parts; if ( ! checkdate( $month, $day, $year ) ) { return '

Invalid date. Make sure the day, month, and year are valid.

'; } $time = sanitize_text_field( $atts['time'] ); // Validate time format (HH:MM or HH:MM:SS) if ( ! preg_match( '/^([01]?[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?$/', $time ) ) { return '

Invalid time format. Use HH:MM or HH:MM:SS.

'; } try { $target_datetime = new DateTime( "$year-$month-$day $time", wp_timezone() ); } catch ( Exception $e ) { return '

Invalid timezone or date. Please check site settings.

'; } $iso8601_date = $target_datetime->format( DateTimeInterface::ATOM ); // ISO 8601 format with timezone $timer_id = 'countdown-timer-' . $count; $end_text = ! empty( $atts['end_text'] ) ? wp_kses_post( $atts['end_text'] ) : ''; ob_start(); ?>
0
Days
0
Hours
0
Minutes
0
Seconds