Introduction
In this tutorial, you’ll learn how to order your Elementor loop grid based on an ACF meta field. This is quite useful when showcasing upcoming events, ensuring that only current events are displayed in ascending order, starting with those closest to the current date.
Steps
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.

Apply the custom query filter
By default, Elementor does not have an option to order by meta field. But fortunately for us, elementor has provided a way to apply a custom query filter. You can learn more about it from the Elementor Developer Docs.
Using your favourite method for applying custom PHP code snippets, such as using a script organiser plugin like Code Snippets Pro or WPCodeBox, or using your child theme (my preferred method), apply the code snippet provided in the next section.
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' );


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()
{
error_log("DD Schedule Event Check function called");
if (!wp_next_scheduled("event_check_daily")) {
try {
wp_schedule_event(time(), "daily", "event_check_daily");
error_log("Event check scheduled successfully");
} catch (Exception $e) {
error_log("Error scheduling event check: " . $e->getMessage());
wp_clear_scheduled_hook("event_check_daily");
}
} else {
error_log("Event check already scheduled");
}
}
// Hook to run the event check daily
add_action("event_check_daily", "check_and_update_events");
function check_and_update_events()
{
error_log("Check and Update Events function called");
// Get all published posts of the custom post type 'event'
$events = get_posts(array(
'post_type' => 'event',
'post_status' => 'publish',
'posts_per_page' => -1,
));
if (empty($events)) {
error_log("No published events found");
return;
}
error_log("Found " . count($events) . " published events");
foreach ($events as $event) {
$start_date = '';
// Check if we're using ACF
if (function_exists('get_field')) {
$start_date = get_field('start_date', $event->ID);
} else {
// Fallback to regular post meta if ACF is not available
$start_date = get_post_meta($event->ID, 'start_date', true);
}
if (empty($start_date)) {
error_log("Event " . $event->ID . " missing required 'start_date' field.");
continue;
}
$today = current_time('Y-m-d');
if ($start_date < $today) {
// Update post status to 'draft'
$update_args = array(
'ID' => $event->ID,
'post_status' => 'draft',
);
$result = wp_update_post($update_args);
if (is_wp_error($result)) {
error_log("Error updating event " . $event->ID . ": " . $result->get_error_message());
} else {
error_log("Event " . $event->ID . " successfully drafted.");
}
} else {
error_log("Event " . $event->ID . " start date is not in the past. No action taken.");
}
}
}
14 comments
Oreva
This tutorial was such a life saver. Thank you so much.
Kimberly Watters
When I copy and paste your code I get yellow and red errors all over it. I’m setting it up for concerts and using the exact setup you did with ACFs.
David Denedo
Hi Kimberly
May I know where you’re adding the code? Is it a code snippet plugin or your child theme? You can share a link via the contact form or by email and I’d be happy to take a look.
Hammad-ur-Rehman
Hi sir !
i saw your tutorial today Order by Date
Replace the start_date with your own ACF meta field key.
set( ‘orderby’, ‘meta_value’ );
$query->set( ‘meta_key’, ‘start_date’ );
}
add_action( ‘elementor/query/dd_event_date’, ‘dd_query_by_event_date’ );
my question is that i want to sort my loop grid according to last name and my acf field is last_name according to your code i did it but its not work can you help howb can i do it that ???
David Denedo
You can try this code instead. In Elementor, use the query id “dd_last_name”.
Hammad-ur-Rehman
hi i want to sort it according to last name my field name is last_name according to your code i placed it but its not working . So what i can do know ??? Any idea??
William Cox
THANK YOU! THANK YOU! THANK YOU!
If I wanted a post to be un-published on the day AFTER an event, how would that code change?
David Denedo
You can change the ‘today’ in the strtotime() function to ‘tomorrow’ and see if that suits your needs (assuming it is a one-day event).
William Cox
Awesome! Thanks again!
Tomagiro
Perfect! Thanks David!
MikeB
Magic – thanks so much for this, I was wondering how to achieve this in Elementor. Every day is a learning day!
MPDigital
Great tutorial! This is exactly what I needed. Thank you and keep it up.
Channing Krendler
How old is this post, please? There’s no date on this post, so it’s unclear if this info is potentially out of date with Elementor’s versions / updates.
David Denedo
Apologies! I’ve now included the publish/update date.
The tutorial is still working fine with the latest version of Elementor.