Create And Apply Loop Grid Template
Begin by designing your loop grid template within your Elementor page, and apply the loop grid widget to the page. The loop grid widget is a very powerful and easy to use widget but Elementor Pro is required to use this feature.

Add Query ID To Loop Grid
Finally, return back to your loop grid widget and apply the query ID “dd_event_date” under Content > Query > Query ID
PHP Code Snippet
Order By Date
Replace the start_date with your own ACF meta field key.
<?php
function dd_query_by_event_date( $query ) {
$query->set( 'orderby', 'meta_value' );
$query->set( 'meta_key', 'start_date' );
}
add_action( 'elementor/query/dd_event_date', 'dd_query_by_event_date' );
Limit The Earliest Date To Today’s Date
Replace the start_date with your own ACF meta field key.
<?php
function dd_query_by_event_date( $query ) {
$query->set( 'orderby', 'meta_value' );
$query->set( 'meta_key', 'start_date' );
$query->set( 'meta_query', array(
array(
'key' => 'start_date',
'value' => date( 'Y-m-d' ),
'compare' => '>=',
'type' => 'DATETIME',
),
) );
}
add_action( 'elementor/query/dd_event_date', 'dd_query_by_event_date' );
Working 100%
Bonus: Expire Past Events
You can set the post status for past events to draft based on the ACF Date Field. Use the following PHP Snippet to expire posts:
<?php
// Schedule the event check daily
add_action("wp", "dd_schedule_event_check");
function dd_schedule_event_check()
{
if (!wp_next_scheduled("event_check_daily")) {
try {
wp_schedule_event(time(), "daily", "event_check_daily");
} catch (Exception $e) {
error_log("Error scheduling event check: " . $e->getMessage());
wp_clear_scheduled_hook("event_check_daily");
}
}
}
// Hook to run the event check daily
add_action("event_check_daily", "check_and_update_events");
function check_and_update_events()
{
// Get all published posts of the custom post type 'event'
$events = get_posts(array(
'post_type' => 'event',
'post_status' => 'publish',
'posts_per_page' => -1,
));
foreach ($events as $event) {
// Check if ACF field exists before accessing it
if(get_field('start_date', $event->ID)) {
$start_date = get_field('start_date', $event->ID);
// Check if start_date is older than today
if (!empty($start_date) && strtotime($start_date) < strtotime('today')) {
// Update post status to 'draft'
$result = wp_update_post(array(
'ID' => $event->ID,
'post_status' => 'draft',
));
// Log update result (success or failure)
if ($result) {
error_log("Event " . $event->ID . " successfully drafted.");
} else {
error_log("Error updating event " . $event->ID . ".");
}
}
} else {
// Log missing ACF field
error_log("Event " . $event->ID . " missing required 'start_date' field.");
}
}
}
