Puddinq.com sharing knowledge

Sort posts in wordpress (custom way)

Sort posts in wordpress (custom way)

wp-logo-smallIn wordpress you sometimes want to sort posts in a way that is not possible with the standard core. The first thing you have to investigate is: is it possible to do it in the standard way.

Sort posts by custom post type

The problem I had: Search results came back for different custom post types and I wanted them ordered by post type, in a non alphabetical way.

Two approaches: I thought of two ways to do so:

  1. Make different queries for the post types and loop them in independent blocks..
  2. Grap the result just before it is rendered, reorder and render (loop) thru ..

1. Different queries

The default arguments for get_posts() gives the option to set post_type. You could run multiple queries for each post type.

<?php $args = array(
	'posts_per_page'   => 5,
	'offset'           => 0,
	'category'         => '',
	'category_name'    => '',
	'orderby'          => 'date',
	'order'            => 'DESC',
	'include'          => '',
	'exclude'          => '',
	'meta_key'         => '',
	'meta_value'       => '',
	'post_type'        => 'post',
	'post_mime_type'   => '',
	'post_parent'      => '',
	'author'	   => '',
	'post_status'      => 'publish',
	'suppress_filters' => true 
);
$posts_array = get_posts( $args ); ?>

Then loop thru as following:

<ul>
<?php

foreach ( $posts_array as $post ) : setup_postdata( $post ); ?>
	<li>
		<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
	</li>
<?php endforeach; 
wp_reset_postdata();?>

</ul>

 

2. Reorder the results

The approach I picked was number 2. When the search query has run, wordpress usually selects the search.php template en loops true the results. If I could place the bit of code at the top of the page this would be most convenient for me.

<?php $posts_list = $wp_query->posts;
 
    function compareByType($a, $b) {
        $order = ['custom-type-1', 'custom-type-2', 'custom-type-3', 'custom-type-4', 'page', 'post'];
        $first = array_search($a->post_type, $order);
        $second = array_search($b->post_type, $order);
        if ($first == $second) {
            return 0;
        }
        return $first < $second ? -1 : 1;
 
    }
 
    usort($posts_list, 'compareByType');
    $wp_query->posts = $posts_list;
?>

At the top of the page I grap $wp_query->posts and then sort them by $order. Once it has been done I set $wp_query->posts to be that order. WordPress runs thru as normal.

Limitations (cons):

  • Every possible post type must be the $order array.
  • Comparing every post type to another is not efficient.

Possibilities (pros)

  • You can do anything with the $wp_query->posts array this way.
  • This solution effects only one file.