Skip to main content
FolksSpeakersPluginsThemesEventsSnippetsShippedCommunityResources
Login Join
Snippet · PHP

Sort Events by Upcoming First (Elementor)

Shared by Darshan Chauhan · May 4, 2026

2 views
Back to Snippets

Step 1: Add the code (correct place)

Paste this inside your theme’s functions.php or a custom plugin:

Step 2: Set Query ID in Elementor

Go to your Loop Grid / Posts widget:

👉 Without this, your code will NOT run.

Step 3: Make sure ACF field is correct

If your format is like d/m/Y → sorting will break.

Step 4: Clear cache

After adding code:

/**
 * Order Elementor query by upcoming events first, then past events.
 * Upcoming events sorted ascending (soonest first).
 * Past events sorted descending (most recent first).
 *
 * Usage: Add query ID "event_upcoming" to your Elementor Posts widget.
 */
add_action( 'elementor/query/event_upcoming', function( $query ) {
    global $wpdb;

    $today    = current_time( 'Y-m-d' ); // Use WordPress time, not PHP date()
    $callback = null;

    $callback = function( $clauses, $wp_query ) use ( $today, $wpdb, $query, &$callback ) {
        // Only apply to this specific query
        if ( $wp_query !== $query ) {
            return $clauses;
        }

        // Remove filter immediately after it runs — don't affect other queries
        remove_filter( 'posts_clauses', $callback, 10 );

        // Add JOIN only if not already joined
        if ( strpos( $clauses['join'], 'meta_key_start_date' ) === false ) {
            $clauses['join'] .= $wpdb->prepare(
                " LEFT JOIN {$wpdb->postmeta} AS meta_key_start_date
                  ON {$wpdb->posts}.ID = meta_key_start_date.post_id
                  AND meta_key_start_date.meta_key = %s ",
                'start_date'
            );
        }

        $clauses['orderby'] = $wpdb->prepare(
            "CASE WHEN meta_key_start_date.meta_value >= %s THEN 0 ELSE 1 END,
             CASE WHEN meta_key_start_date.meta_value >= %s
                  THEN meta_key_start_date.meta_value END ASC,
             CASE WHEN meta_key_start_date.meta_value < %s
                  THEN meta_key_start_date.meta_value END DESC",
            $today,
            $today,
            $today
        );

        return $clauses;
    };

    add_filter( 'posts_clauses', $callback, 10, 2 );
} );