1

Original question: Seperating Custom Post Search Results

I've tried to implement this code to my website, but i have some problem with it. What i've changed is i've added another switch for third post type, as follows:

<?php if (have_posts()) : ?>
    <?php
    $last_type = "";
    $typecount = 0;
    while (have_posts()) :
        the_post();
        if ($last_type != $post->post_type) {
            $typecount = $typecount + 1;
            if ($typecount > 1) {
                echo '</div><!-- close container -->'; //close type container
            }
            // save the post type.
            $last_type = $post->post_type;
            //open type container
            switch ($post->post_type) {
                case 'post':
                    echo "<div class=\"postsearch container\"><h2>Blog Results</h2>";
                    break;
                case 'partner':
                    echo "<div class=\"partnersearch container\"><h2>Partner Search Results</h2>";
                    break;
                case 'fiches_pratiques':
                    echo "<div class=\"lessonsearch container\"><h2>lesson Search Results</h2>";
                    break;
            }
        }
        ?>

        <?php if ('post' == get_post_type()) : ?>
            <li class="post"><?php the_title(); ?></li>
        <?php endif; ?>

        <?php if ('partner' == get_post_type()) : ?>
            <li class="partner"><?php the_title(); ?></li>
        <?php endif; ?>

        <?php if ('lesson' == get_post_type()) : ?>
            <li class="lesson"><?php the_title(); ?></li>
        <?php endif; ?>


    <?php endwhile; ?>

<?php else : ?>
    <div class="open-a-div">
        <p>No results found.</p>    

    <?php endif; ?>       

This code results in following:

Lessons Search Results

Lesson 1 Lesson 4 Lesson 3

Blog Results

Test sub

Partner Search Results

Fourth partner

Blog Results

Lorem ipsum Wave 2.0 Web & Tech Cloud Open Container Project

As you can notice, the blog results section is doubled. Any suggestions on what might be the problem?

Installed search plugins: Relevanssi

NOTE: without Relevanssi (but with Search Everything plugin) it shows it in a proper way, but Search Everything plugin doesn't allow multiple terms search, which is a must have in my case.

Latest Wordpress version.

Thank you in advance.

5

Here is an idea, sort your your loop before it executes. Your current issue is just this. You will see that the type of sorting (if I'm correct where I believe your order is not alphabetical according to post type) is not possible natively, so we need a work-around (even if you just need post types sorted alphabetically, the native way still lack proper functionality). This is where usort() comes in, we can sort the post type post in any order we want. This will be done inside the the_posts filter

I can show you both examples. NOTE: The code sample requires at least PHP 5.4+, which should be your minimum version now. All versions before 5.4 is EOL'ed, not supported and therefor a huge security risk if you are still using those versions.

SORT BY CUSTOM POST TYPE ORDER

add_filter( 'the_posts', function( $posts, $q ) 
{
    if( $q->is_main_query() && $q->is_search() ) 
    {
        usort( $posts, function( $a, $b ){
            /**
             * Sort by post type. If the post type between two posts are the same
             * sort by post date. Make sure you change your post types according to 
             * your specific post types. This is my post types on my test site
             */
            $post_types = [
                'event_type' => 1,
                'post'       => 2,
                'cameras'    => 3
            ];              
            if ( $post_types[$a->post_type] != $post_types[$b->post_type] ) {
                return $post_types[$a->post_type] - $post_types[$b->post_type];
            } else {
                return $a->post_date < $b->post_date; // Change to > if you need oldest posts first
            }
        });
    }
    return $posts;
}, 10, 2 );

SORT BY POST TYPE ALPHABETICAL ORDER

add_filter( 'the_posts', function( $posts, $q ) 
{
    if( $q->is_main_query() && $q->is_search() ) 
    {
        usort( $posts, function( $a, $b ){
            /**
             * Sort by post type. If the post type between two posts are the same
             * sort by post date. Be sure to change this accordingly
             */

            if ( $a->post_type != $b->post_type ) {
                return strcasecmp( 
                    $a->post_type, // Change these two values around to sort descending
                    $b->post_type 
                );
            } else {
                return $a->post_date < $b->post_date; // Change to > if you need oldest posts first
            }
        });
    }
    return $posts;
}, 10, 2 );

Your posts should now be sorted by post type on your search page, that is, if you are not using a custom query in place of your main query. As for your code above, keep it as is, not necessary to make any adjustments to it

  • Hello, first code does exactly what i need. It's more or less equivalent to the original Relevanssi function (but works even without it of course), posted by a very kind person below :) Thank you. Now i need to figure out how to deal with multiple search terms without the plugin. – semibur Jul 9 '15 at 7:28
2

You are getting your post results in the order that the Relevanssi plugin thinks is correct. That is, you are getting the results in the most relevant order according to the plugin's logic (I don't know what that is exactly) which is the point of the plugin.

Generally speaking, ordering by post type isn't that hard:

function orderby_type($orderby) {
  remove_filter('posts_orderby','orderby_type');
  global $wpdb;
  return $wpdb->posts.'.post_type';
}
add_filter('posts_orderby','orderby_type');
$args = array(
  'post_type' => array('post','page','book'),
  'orderby' => 'post_type'
);
$w = new WP_Query($args);

However, I'd expect that to break the "relevant" ordering the plugin is providing. In fact, anything you do is likely to break the "relevance" calculation to some extent. Something like the following should be about the best you can do:

function resort_posts($posts) {
  $sorted = $ret = array();
  foreach ($posts as $p) {
    $sorted[$p->post_type][] = $p;
  }
  foreach ($sorted as $s) {
    $ret = array_merge($ret,$s);
  }
  // verify
//   $pid = wp_list_pluck($posts,'ID');
//   $sid = wp_list_pluck($ret,'ID');
//   var_dump(array_diff($pid,$sid));
  return $ret;
}
add_filter('the_posts','resort_posts');

You will need to figure out how to make that work with Relevanssi without also messing with all queries on the site (which it will do as written). I have never used that plugin so I can't say (plugin specific question are off topic as well, by the way)

1

Did you search the endless expanses of the internet ?

Because the first entry on the SERP is an article at the relvanssi knowledge base, with the title »Separating posts by post type«, sounds fitting to me. Below is the code for the proposed approach:

add_filter('relevanssi_hits_filter', 'separate_result_types');
function separate_result_types($hits) {
    $types = array();

    // Split the post types in array $types
    if (!empty($hits)) {
        foreach ($hits[0] as $hit) {
            if (!is_array($types[$hit->post_type])) $types[$hit->post_type] = array();                        
            array_push($types[$hit->post_type], $hit);
        }
    }

    // Merge back to $hits in the desired order
    $hits[0] = array_merge(
        $types['mycustomtypethatgoesfirst'], 
        $types['thesecondmostimportanttype'], 
        $types['post'], $types['pages']
    );
    return $hits;
}


Notes:

  • I did not do anything, but copying the code.
  • I could not link the search with LMGTFY, apparently it is not considered to be nice (any more at least). Ok, I kind of - maybe even completely - get that, but seriously, do your research - pretty please :)
  • I've tried this solution - works partly, but i still can't get it to work the way i need it to. I don't really want to use Relevanssi, but without it i don't have any results. The other plugin i'd prefer to use is not doing well with multiple terms, so meanwhile i do use this function together with a slightly changed code that is listed in the original question. – semibur Jul 9 '15 at 7:16
  • 1
    Do I understand you correctly, you have been using this from the start? If so, then it should really have been part of your question, because only with full - relevant - information you get answers specific enough to your individual problem. @user3756959 – Nicolai Jul 9 '15 at 8:54
  • yes, at some point, i've started using it, because it was the only thing to do what i need with Relevanssi. I guess i was not to precise when posting a question. I need this thing to work without Relevanssi. Now, the code given by Pieter Goosen works even without the Relevanssi, but then i can't get any results for multiple term query. The most important thing for me is to be able to search through few custom post types and sort the results by custom post type. I need to find the term and list all the posts that have this term assigned.. I don't really about the content search. – semibur Jul 9 '15 at 12:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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