6

My site has 3 unique post types:

  • Default Blog posts ("post")
  • custom type "lesson"
  • custom type "series"

When the user searches the site, I would like pertinent results from all 3 post types to show up on the search results page. The "posts" results are in one container, "lesson" results in a separate container, etc. How can I modify the search page to accomplish this?

Here is my current loop:

<?php get_header(); ?>
<div class="row">
    <div class="small-12 large-8 columns" role="main">

        <?php do_action('foundationPress_before_content'); ?>

        <h2><?php _e('Search Results for', 'FoundationPress'); ?> "<?php echo get_search_query(); ?>"</h2>

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

        <?php while ( have_posts() ) : the_post(); ?>
            <?php if( get_post_type() == 'lesson' ) {
                    get_template_part('content', 'lesson');
                } else if ( get_post_type() == 'post' ) {
                    get_template_part('content', get_post_format());
                }
            ?>
        <?php endwhile; ?>

        <?php else : ?>
            <?php get_template_part( 'content', 'none' ); ?>

    <?php endif;?>

    <?php do_action('foundationPress_before_pagination'); ?>

    <?php if ( function_exists('FoundationPress_pagination') ) { FoundationPress_pagination(); } else if ( is_paged() ) { ?>

        <nav id="post-nav">
            <div class="post-previous"><?php next_posts_link( __( '&larr; Older posts', 'FoundationPress' ) ); ?></div>
            <div class="post-next"><?php previous_posts_link( __( 'Newer posts &rarr;', 'FoundationPress' ) ); ?></div>
        </nav>
    <?php } ?>

    <?php do_action('foundationPress_after_content'); ?>

    </div>
    <?php get_sidebar(); ?>

<?php get_footer(); ?>
  • Don't use elseif, use only if. This way, all the templates will be displayed. – Ciprian Mar 20 '15 at 16:52
  • I don't think if vs. elseif will make a difference here. – s_ha_dum Mar 25 '15 at 16:04
13

You can run the same loop multiple times by using rewind_posts() to output each type separately.

if( have_posts() ){
    $types = array('post', 'lesson', 'series');
    foreach( $types as $type ){
        echo 'your container opens here for ' . $type;
        while( have_posts() ){
            the_post();
            if( $type == get_post_type() ){
                get_template_part('content', $type);
            }
        }
        rewind_posts();
        echo 'your container closes here for ' . $type;
    }
}
  • Hi -- the problem is I need to store each post type into its own container (I'm using a tabbed interface, so if they hit the "lesson" tab they get all the "lesson" videos that match their search, etc.) Not sure how to adapt your method to that – Prefix Mar 21 '15 at 1:01
  • yes, that's what I assumed, and that's what this example is for. you put whatever container markup you want between the foreach and the while loops. – Milo Mar 21 '15 at 1:54
  • Ah I see with the edited post, thanks. Do you know if this will work properly with pagination as well? – Prefix Mar 23 '15 at 13:55
  • 1
    this will just sort posts on a per-page basis, and pagination will work the same as without this code. if the goal is to sort the posts together across all pages, you'll have to alter the query directly with a filter. – Milo Mar 23 '15 at 15:36
  • That's more in line with what I'm trying to do. Basically I just need a clean way for people to sort through search results by post type. Optimally I wouldn't even bother with pagination and just have all matching results spit out into each container but I'm not sure how heavy an impact that could have on site performance – Prefix Mar 23 '15 at 15:41

protected by Community Mar 29 '18 at 16:55

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

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