How to Sort WordPress Posts by ACF Date Field Values

Last week, I published the portfolio section of the Purple Turtle Creative website.

The portfolio page is simply a custom post type archive registered in my WordPress theme’s code. The custom post type is called ptc-portfolio and the posts use Advanced Custom Fields for metadata. Notably, there is an ACF group named ptc_project_dates which contains two ACF date fields: the project’s start and end dates.

When displaying the portfolio project posts on the frontend, I wanted to sort them by project start date. That way, the archive features my latest projects at the top while older projects fall deeper into the archives.

Changing the WordPress query’s sorting takes just one action hook. Also, Advanced Custom Fields stores the Date Picker field values in a way that makes sorting easy and reliable. Let me show you!

Defining the ACF Date Field

Before we change the sorting of the WordPress posts, we need to first define the ACF date field, of course.

I made two related date fields, so I decided to group them in an ACF group field definition. The schema for my fields is essentially the following in PHP:

...
'label' => 'Project Dates',
'name' => 'ptc_project_dates',
'type' => 'group',
'sub_fields' => array(
	array(
		'label' => 'From',
		'name' => 'ptc_project_from',
		'type' => 'date_picker',
		'instructions' => 'When you started working on the project.',
		...
	),
	array(
		'label' => 'To',
		'name' => 'ptc_project_to',
		'type' => 'date_picker',
		'instructions' => 'When you stopped working on the project. (Leave blank if project is still ongoing.)',
		...
	),
...

Sorting WordPress Posts by an ACF Date Field Value

Now that the date data is defined and stored, we can alter the WP_Query instance to order the posts by that custom field.

Finding the ACF Date Field Values

The date data is stored in the wp_postmeta table for each post. The meta_key is typically just the ACF field’s name, but it might be stored under a different name, depending on your schema. This might require a bit of database investigation to ensure you find the correct meta key.

For example, subfields of an ACF group field will have a different meta key. If you nested your ACF date field in an ACF group field like I did, then the meta key name will be a concatenation of the group field name, an underscore, and then the subfield’s name. For my situation, that means I’d look for a post meta key of ptc_project_dates_ptc_project_from.

Thankfully, Advanced Custom Fields stores the date values as a single numeric value of year, month, and then day. For example, the date March 28th, 2022 would result in a stored value of 20220328. This is super helpful because it means we can use numerical sorting for the date values.

Altering the WordPress Query

To alter the WordPress query to sort the posts by these meta values, we simply hook into the pre_get_posts action hook to modify the query like so:

add_action( 'pre_get_posts', 'ptc_customize_wp_query', 10 );

/**
 * Sorts portfolio project posts by most recent start date.
 *
 * @param \WP_Query $query The WP_Query instance (passed by reference).
 */
function ptc_customize_wp_query( $query ) {
	if ( $query->is_post_type_archive( 'ptc-portfolio' ) ) {
		// Sort portfolio posts by project start date.
		$query->set( 'order', 'DESC' );
		$query->set( 'orderby', 'meta_value_num' );
		// ACF date field value is stored like 20220328 (YYYYMMDD).
		$query->set( 'meta_key', 'ptc_project_dates_ptc_project_from' );
	}
}

Looking at the code, you’ll see that I only change the query when it is for my ptc-portfolio post type archive. It’s important to limit alterations of the WordPress query when hooking into the pre_get_posts action. This is because multiple different queries run per page load and they are not always post queries. For example, this query actually powers each WordPress menu displayed in your theme! So, again, be sure to limit the query modifications to their exact use case.

Also in the code above, you’ll see that I am sorting the query in descending order. That means the query orders results from greatest to least. Since I am sorting by the numerical meta values of my ACF date field’s meta key, then the more recent dates will be toward the top. If you’re needing slightly different sorting, definitely look into the WP_Query class’s post meta parameter documentation.

Michelle Blanchette

Michelle Blanchette

Independent worker dedicated to continuous learning in the web development field. I'm often told my spicy passion for delivering quality solutions is refreshingly contagious. My favorite words are "efficient", "productive", and "simple".