fbpx
Search
Close this search box.

Home / Blog

 / 
How to sort WordPress posts by custom field (post meta)

How to sort WordPress posts by custom field (post meta)

There are lots of different options for sorting posts available in WP_Query class, sorting by custom fields, or post meta, is one of them. However, sometimes the default sorting mechanism is not enough. Let’s take a look at one of such cases and find the solution.

Here is the case: we have a numeric custom field (post meta) named order. Some posts does not have it filled. Now, we want to use this meta value to sort posts, but we also want to display posts which have a meta value first, followed by all the posts without any value.

First thing which comes to mind is to use meta_query to select posts with and without the meta and then add proper order option to sort by this meta query:

$queryArgs['meta_query'] = [
	'relation' => 'OR',
	[
		'key' => 'order',
		'compare' => 'EXISTS',
		'type' => 'NUMERIC',
	],
	[
		'key' => 'order',
		'compare' => 'NOT EXISTS',
	],
];

$queryArgs['order'] = 'meta_value';

While this approach could be useful in many cases, in our scenario it has a one problem: depending on the sorting order, posts without the meta value will be displayed after (DESC) or before (ASC) the posts with meta value, but we want them to always display at the end.

Here i how to solve it with custom SQL JOIN clause:

1. Add custom JOIN clause instead of meta_query

add_action( 'posts_join_request', function( string $orderby, \WP_Query $query ) {
	if ( $thisIsTheQueryYouWantToAlter ) {
		global $wpdb;

		$metaKey = 'order'; // Use whathever your post meta key is...

		$join .= " LEFT JOIN $wpdb->postmeta as custom_order_meta ON (
			$wpdb->posts.ID = custom_order_meta.post_id AND custom_order_meta.meta_key = '$metaKey'
		) ";
	}

	return $join;
} );

2. Manually add order clauses

Now we need to add two orderby clauses, first to sort posts with any meta value before the ones without meta value and second to sort posts by meta value itself.

add_action( 'posts_orderby_request', function( string $orderby, \WP_Query $query ) {
	if ( ! $thisIsTheQueryYouWantToAlter ) {
		return $orderby;
	}

	$order = 'ASC'; // or 'DESC';

	return join(
		', ',
		[
			'custom_order_meta.meta_value IS NOT NULL DESC', // use `ASC` to show posts without any value first.
			"custom_order_meta.meta_value {$order}",
			ltrim($orderby, ', '),
		]
	);
} );

Share This Article:

Picture of Wojtek Szałkiewicz

Wojtek Szałkiewicz

Share This Article:

Picture of Wojtek Szałkiewicz

Wojtek Szałkiewicz

Share This Article:

Latest updates, discounts and more!

Get the most recent updates on WordPress automation, fresh plugins, new features and price cuts.

Related articles

In this post, we show how to write an email that removes you from the noise with a Beautiful Email showcasing your latest blog posts and top-of-mind content in case...

Notification : Conditionals is one of the most frequently downloaded extensions for Notification. If you are a website owner, administrator, or content manager, you likely want to manage notifications effectively...

Marketers and business owners are always on the lookout for the best ways to reach their audience. One of the most effective methods is email marketing. However, a mass approach...

WordPress Plugins that get the job done

With years of experience creating client websites, we bring our experience to functional WordPress plugins.

Easy to use for everyone

Regardless of experience level, you can easily use our products.

Top-notch Support included

We treat our clients seriously and focus heavily on support. Reviews backs this up!

Extensible and developer friendly

You're the same developer as we are. Our code is clean and extensible, just the way you like.