Query Custom Post Types & Order By Custom Post Typ

2019-07-30 19:49发布

问题:

Is it possible to query multiple CPTs and then order in a preset way?

For example, I have 2 CPTs & 1 being the WP default 'post' and would like the loop to return 6 results, ordering as below.

  • CPT-1
  • CPT-2
  • POST
  • CPT-1
  • CPT-2
  • POST

Is this possible without splitting the loop?

I did have a quick search, but could only find one article relating to this, the solutions from which don't appear to work any more...

Wordpress order posts by post type

回答1:

Here is a shortened version of Sephsekla's code:

$my_post_types = array( 'CPT-1', 'CPT-2', 'post', 'CPT-1', 'CPT-2', 'post' );
$posts_shown = array();
$args = array(
    'post_type' => array( 'CPT-1', 'CPT-2', 'post' ),
    'post_status' => 'publish',
    'posts_per_page' => -1
);
$my_query = new WP_Query( $args );
foreach ( $my_post_types as $post_type ):
    while ( $my_query->have_posts() ): $my_query->the_post();
        if ( $post_type == get_post_type() && ! in_array( get_the_ID(), $posts_shown ) ) {
            echo '<pre>' . get_post_type() .': '. get_the_title() . '</pre>';
            $posts_shown[] = get_the_id();
            break;
        }
    endwhile;
    $my_query->rewind_posts();
endforeach;
wp_reset_postdata();


回答2:

This is something I've done before a while ago, and while it is doable with just one query it's a bit of a long-winded setup.

The gist of it is that you can use one query, then loop through the query until you find the first post you're after. Then exit the loop and use WP_Query->rewind_posts() to put the query back to the start.

Then you can run a second loop with a different condition. And then a third.

For the fourth, fifth and sixth loops you also need to check that you're not repeating the first set.

See below for the code in all its glory.


<?php

$my_query = new WP_Query(
    array(
        'post_status' => 'publish',
    )
);

$post_1 = $post_2 = $post_3 = $post_4 = $post_5 = $post_6 = 0;

if ( $my_query->have_posts() ) {
    /*First loop through posts*/
    while ( $my_query->have_posts() ) {
        $my_query->the_post();
        /**
         * Find the first post
        */

        if ( 'CPT-1' == get_post_type() && $post_1 == 0 ) {
            do_something_with_the_post();
            $post_1 = get_the_id();
            break;
        }
    }

    $my_query->rewind_posts();

    /*Second loop through posts*/
    while ( $my_query->have_posts() ) {
        $my_query->the_post();

        /**
         * Find the second post
        */
        if ( 'CPT-2' == get_post_type() && $post_2 == 0 ) {
            do_something_with_the_post();
            $post_2 = get_the_id();
            break;
        }
    }
    $my_query->rewind_posts();

    /*Third loop through posts*/
    while ( $my_query->have_posts() ) {
        $my_query->the_post();

        /**
         * Find the third post
        */
        if ( 'post' == get_post_type() && $post_3 == 0 ) {
            do_something_with_the_post();
            $post_3 = get_the_id();
            break;
        }
    }

    $my_query->rewind_posts();

    /**
     * Then we repeat this process but also check we don't use the same post twice
     */

    /*Fourth loop through posts*/
    while ( $my_query->have_posts() ) {
        $my_query->the_post();

        /**
         * Find the fourth post
        */
        if ( 'CPT-1' == get_post_type() && $post_4 == 0 && get_the_id() !== $post_1 ) {
            do_something_with_the_post();
            $post_1 = get_the_id();
            break;
        }
    }

    $my_query->rewind_posts();

    /*Fifth loop through posts*/
    while ( $my_query->have_posts() ) {
        $my_query->the_post();

        /**
         * Find the fifth post
        */

        if ( 'CPT-2' == get_post_type() && $post_5 == 0 && get_the_id() !== $post_2 ) {
            do_something_with_the_post();
            $post_5 = get_the_id();
            break;
        }
    }

    $my_query->rewind_posts();

    /*Sixth loop through posts*/
    while ( $my_query->have_posts() ) {
        $my_query->the_post();

        /**
         * Find the sixth post
        */
        if ( 'post' == get_post_type() && $post_6 == 0 && get_the_id() !== $post_3 ) {
            do_something_with_the_post();
            $post_6 = get_the_id();
            break;
        }
    }

    /**
     * And we're finished
     */
}