I have three custom post types which I need to retrieve posts for within one wp_query. I am seeking to return the posts in the order of post type, as well as by post title.

Within the question Ordering Custom Post Types with WP_Query @birgire provided a fantastic function which allows me to return the posts in an order as defined by an array within the post_type variable.

But I would also like to ensure that these posts are also ordered by post title. So my return would look something like this...

Cats - British Shorthair
Cats - Maine Coon
Cats - Siamese
Dogs - German Shepherd
Dogs - Labrador
Rabbits - Flemish
Rabbits - Holland Lop
Rabbits - Netherland Dwarf

I am unfamiliar with @birgire 's function and the FIELD part of it. Is it easily extendable to allow for post title sorting also?

  • Glad to see you got it covered by a great answer by Sally.
    – birgire
    Jan 18 at 21:56

1 Answer 1


Yes it is, and to also sort by the post title, you would just need to add , {$wpdb->posts}.post_title <ASC or DESC> after the FIELD(), like so which results in a clause that looks like ORDER BY FIELD(wp_posts.post_type, <types>), wp_posts.post_title ASC:

// Replace this:
return $orderby       = "FIELD( {$wpdb->posts}.post_type," . $post_type__in_string . ' )';

// with this:
return $orderby       = "FIELD( {$wpdb->posts}.post_type," . $post_type__in_string . ' )' . // wrapped
    ", {$wpdb->posts}.post_title ASC";

But as for sorting the posts by the post type, if you do not actually need to sort the posts in the same order you have them in the post_type array, then you could simply use an orderby array like so:

$args = array(
    'post_type' => array( 'post', 'cats', 'dogs', 'rabbits' ),
    'orderby'   => array(
        'post_type'  => 'ASC', // Sort by the post type.
        'post_title' => 'ASC', // Then, by the post title.

$query = new WP_Query( $args );
  • With the above example, the posts would be sorted like so:

    • Cats A
    • Cats B
    • Dogs A
    • Dogs B
    • Post A
    • Post B
    • Rabbits A
    • Rabbits B

    I.e. You would get cats, dogs, post, rabbits instead of post, cats, dogs, rabbits (note the post which is the first item in the post_type array).

  • 1
    Thank you, that worked perfectly. I really appreciate you including a reference link for FIELD(), as I did not realise that was a MySQL reference and was getting hung up on it. I also appreciate your additional bit about how I could extend orderby if custom post type sorting were not strictly required. Jan 17 at 9:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.