Order Elementor loop by ACF date field

David Denedo

Updated on June 20, 2024.

Table of Content

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.

Elementor Loop Template ordered by date created
Elementor loop grid ordered by post date created

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

Add query ID to elementor loop grid

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' );
php code snippet to order loop grid by acf field
Elementor Loop Template ordered by ACF date field
Elementor loop grid ordered by ACF date field

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.");
        }
    }
}
0 0 votes
Article Rating
Subscribe
Notify of
guest
11 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Channing Krendler
Channing Krendler
29 March 2024 10:17 pm

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.

MPDigital
MPDigital
12 May 2024 2:21 am

Great tutorial! This is exactly what I needed. Thank you and keep it up.

MikeB
MikeB
14 May 2024 6:01 pm

Magic – thanks so much for this, I was wondering how to achieve this in Elementor. Every day is a learning day!

Tomagiro
4 June 2024 9:29 pm

Perfect! Thanks David!

William Cox
7 June 2024 8:12 pm

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?

William Cox
7 June 2024 8:31 pm
Reply to  David Denedo

Awesome! Thanks again!

Hammad-ur-Rehman
Hammad-ur-Rehman
11 June 2024 6:56 am

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??

Hammad-ur-Rehman
Hammad-ur-Rehman
11 June 2024 7:07 am

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 ???