最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

customization - Search results ordered by custom post types are not grouped

programmeradmin2浏览0评论

For a WordPress website I have a couple of custom post types, named cities and books, and also the regular blog posts. I have customized the search results (only search in the post title) page so that the results are to be ordered by custom post type.

The problem is that the search results within a custom post type are not really grouped.

Example:

When I search for the letters am, I get the following results in the search results page:

BOOKS
-----
Book 1

CITIES
------
City 1

BOOKS
-----
Book 2
Book 3

CITIES
------
City 2
City 3
City 4

BLOGPOSTS
---------
Post 1
Post 2
Post 3
etc.

What I would like:

BOOKS
-----
Book 1
Book 2
Book 3

CITIES
------
City 1
City 2
City 3
City 4

BLOGPOSTS
---------
Post 1
Post 2
Post 3
etc.

This is my loop:

<?php if(have_posts()) : ?>

    <?php   
        $last_type = "";
        $typecount = 0;
        while ( have_posts() ) : the_post();
    ?>

        <?php
            if ($last_type != $post->post_type){
                $typecount = $typecount + 1;
                if ($typecount > 1){
                    echo '</div><!-- close type-container -->'; //close type container
                }

                // save the post type.
                $last_type = $post->post_type;

                //open type container
                switch ($post->post_type) {
                    case 'books':
                        echo "<div class=\"books-container\"><h2>";
                        _e('Books', 'qode');
                        echo "</h2>";
                    break;

                    case 'cities':
                        echo "<div class=\"cities-container\"><h2>";
                        _e('Destinations', 'qode');
                        echo "</h2>";
                    break;

                    case 'post':
                        echo "<div class=\"blog-container\"><h2>";
                        _e('Blogposts', 'qode');
                        echo "</h2>";
                    break;
                }
            }
        ?>

        <?php if('books' == get_post_type()) : ?>

             <?php get_template_part('templates/books_search', 'loop'); ?>

        <?php elseif('cities' == get_post_type()) : ?>

            <?php get_template_part('templates/cities_search', 'loop'); ?>

        <?php elseif('post' == get_post_type()) : ?>

            <?php get_template_part('templates/blog_search', 'loop'); ?>

        <?php endif; ?>                     

    <?php endwhile; // endwhile have_posts ?>

    <?php // Pagination ?>
    <?php if($qode_options_proya['pagination'] != "0") : ?>
        <?php pagination($wp_query->max_num_pages, $blog_page_range, $paged); ?>
    <?php endif; ?>

    <?php else: //If no posts are present ?>
        <div class="entry nothing-found">                        
            <h3><?php _e('Sorry, there is no 100% ', 'qode') . " " . the_search_query() . " " . _e(' yet.') ?></h3>
            <p><?php _e('But there are loads of other 100% destinations available. Try again in the searchfield below.', 'qode'); ?> 
        </div>
<?php endif; // endif have_posts ?>

And this is an example of the template file for a CPT that is being included:

<div <?php post_class('vc_span4 wpb_column column_container'); ?> style="padding-bottom: 60px;">

<div class="wpb_wrapper book">

    <?php // Get the post thumbnail ?>
    <div class="wpb_single_image wpb_content_element element_from_fade element_from_fade_on">
        <div class="wpb_wrapper">
            <?php 
                if ( has_post_thumbnail() ) {
                    echo '<a href="' . get_permalink( $thumbnail->ID ) . '" title="' . the_title_attribute( 'echo=0' ) . '" class="book-holder" ><span class="book-thumb">';
                    echo get_the_post_thumbnail( $post->ID, 'book-thumbnail' ); 
                    echo '</span></a>';
                }
            ?>
        </div> 
    </div>

</div>

<div class="wpb_text_column wpb_content_element text-align-center" style="margin: 20px 0px 0px 0px; ">

    <div class="wpb_wrapper">
        <h5><?php the_title(); ?></h5>
    </div>
    <a href="<?php the_permalink(); ?>" target="_blank" class="qbutton  small" style="margin: 20px 0px 0px 0px; "><?php _e('More Info', 'qode'); ?></a>

</div>
</div>

I must be doing something wrong here, but I just can't figure out what.

Can someone suggest me where I am going wrong here?

For a WordPress website I have a couple of custom post types, named cities and books, and also the regular blog posts. I have customized the search results (only search in the post title) page so that the results are to be ordered by custom post type.

The problem is that the search results within a custom post type are not really grouped.

Example:

When I search for the letters am, I get the following results in the search results page:

BOOKS
-----
Book 1

CITIES
------
City 1

BOOKS
-----
Book 2
Book 3

CITIES
------
City 2
City 3
City 4

BLOGPOSTS
---------
Post 1
Post 2
Post 3
etc.

What I would like:

BOOKS
-----
Book 1
Book 2
Book 3

CITIES
------
City 1
City 2
City 3
City 4

BLOGPOSTS
---------
Post 1
Post 2
Post 3
etc.

This is my loop:

<?php if(have_posts()) : ?>

    <?php   
        $last_type = "";
        $typecount = 0;
        while ( have_posts() ) : the_post();
    ?>

        <?php
            if ($last_type != $post->post_type){
                $typecount = $typecount + 1;
                if ($typecount > 1){
                    echo '</div><!-- close type-container -->'; //close type container
                }

                // save the post type.
                $last_type = $post->post_type;

                //open type container
                switch ($post->post_type) {
                    case 'books':
                        echo "<div class=\"books-container\"><h2>";
                        _e('Books', 'qode');
                        echo "</h2>";
                    break;

                    case 'cities':
                        echo "<div class=\"cities-container\"><h2>";
                        _e('Destinations', 'qode');
                        echo "</h2>";
                    break;

                    case 'post':
                        echo "<div class=\"blog-container\"><h2>";
                        _e('Blogposts', 'qode');
                        echo "</h2>";
                    break;
                }
            }
        ?>

        <?php if('books' == get_post_type()) : ?>

             <?php get_template_part('templates/books_search', 'loop'); ?>

        <?php elseif('cities' == get_post_type()) : ?>

            <?php get_template_part('templates/cities_search', 'loop'); ?>

        <?php elseif('post' == get_post_type()) : ?>

            <?php get_template_part('templates/blog_search', 'loop'); ?>

        <?php endif; ?>                     

    <?php endwhile; // endwhile have_posts ?>

    <?php // Pagination ?>
    <?php if($qode_options_proya['pagination'] != "0") : ?>
        <?php pagination($wp_query->max_num_pages, $blog_page_range, $paged); ?>
    <?php endif; ?>

    <?php else: //If no posts are present ?>
        <div class="entry nothing-found">                        
            <h3><?php _e('Sorry, there is no 100% ', 'qode') . " " . the_search_query() . " " . _e(' yet.') ?></h3>
            <p><?php _e('But there are loads of other 100% destinations available. Try again in the searchfield below.', 'qode'); ?> 
        </div>
<?php endif; // endif have_posts ?>

And this is an example of the template file for a CPT that is being included:

<div <?php post_class('vc_span4 wpb_column column_container'); ?> style="padding-bottom: 60px;">

<div class="wpb_wrapper book">

    <?php // Get the post thumbnail ?>
    <div class="wpb_single_image wpb_content_element element_from_fade element_from_fade_on">
        <div class="wpb_wrapper">
            <?php 
                if ( has_post_thumbnail() ) {
                    echo '<a href="' . get_permalink( $thumbnail->ID ) . '" title="' . the_title_attribute( 'echo=0' ) . '" class="book-holder" ><span class="book-thumb">';
                    echo get_the_post_thumbnail( $post->ID, 'book-thumbnail' ); 
                    echo '</span></a>';
                }
            ?>
        </div> 
    </div>

</div>

<div class="wpb_text_column wpb_content_element text-align-center" style="margin: 20px 0px 0px 0px; ">

    <div class="wpb_wrapper">
        <h5><?php the_title(); ?></h5>
    </div>
    <a href="<?php the_permalink(); ?>" target="_blank" class="qbutton  small" style="margin: 20px 0px 0px 0px; "><?php _e('More Info', 'qode'); ?></a>

</div>
</div>

I must be doing something wrong here, but I just can't figure out what.

Can someone suggest me where I am going wrong here?

Share Improve this question edited Jun 23, 2015 at 12:11 Pieter Goosen 55.4k23 gold badges116 silver badges210 bronze badges asked Jun 22, 2015 at 9:20 JustinJustin 4511 bronze badges 0
Add a comment  | 

1 Answer 1

Reset to default 3

This type of ordering is not available by default. You however have two basic options here

  • rewind_posts() -> Rerun the loop multiple times and use rewind_posts() to rewind the loop so you can rerun it again

EXAMPLE

if ( have_posts() ) {
    while( have_posts() ) {
        the_post();

        if ( $post->post_type == 'books' ) {
            // Output books posts
        }

    } // end first while loop

    rewind_posts(); // rewind loop so we can rerun it

    while( have_posts() ) { // Start second while loop
        the_post();

        if ( $post->post_type == 'cities' ) {
            // Output cities posts
        }

    } // end second while loop

    rewind_posts(); // rewind loop so we can rerun it

    // Run your third while loop for blog posts

} // End your if statement
  • The second method is to use usort and the the_posts filter to sort your posts accordingle before the loop is run.

EXAMPLE

(This goes into your functions.php)

add_filter( 'the_posts', function( $posts, $q ) 
{
    if(     $q->is_main_query()  // Targets the main query only
         && $q->is_search() // Only targets the search page
    ) {

        usort( $posts, function( $a, $b )
      {
            $post_types = array ( // Set your post type order here
                'books' => 1,
                'cities' => 2,
                'post' => 3
            );

            $posts = $post_types[$a->post_type] - $post_types[$b->post_type];

            if ($posts === 0) {
                //same post_type, compare by post_date.
                return $a->post_date < $b->post_date;
            }else{
                //different post_type, save to ignore the post_date.
                return $posts;
            }
        } );
    } 
    return $posts;  
}, 
10, 2 );
发布评论

评论列表(0)

  1. 暂无评论