Sort posts in wordpress (custom way)
In 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:
- Make different queries for the post types and loop them in independent blocks..
- 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.