I have a search field for the blog posts, but I need an other for a custom post type. How can I create this custom search form with a different search result layout?

Here is what I've tried and got a solution with 3 steps. Let's say your custom post type is "products"

1 . Add Function Code here you can specify the archive-search.php

function template_chooser($template)   
{    
  global $wp_query;   
  $post_type = get_query_var('post_type');   
  if( $wp_query->is_search && $post_type == 'products' )   
  {
    return locate_template('archive-search.php');  //  redirect to archive-search.php
  }   
  return $template;   
}
add_filter('template_include', 'template_chooser');    

2 . Create search result template for custom post type ( archive-search.php )

        <?php
        /* Template Name: Custom Search */        
        get_header(); ?>             
        <div class="contentarea">
            <div id="content" class="content_right">  
                     <h3>Search Result for : <?php echo "$s"; ?> </h3>       
                     <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>    
                <div id="post-<?php the_ID(); ?>" class="posts">        
                     <article>        
                    <h4><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a></h4>        
                    <p><?php the_exerpt(); ?></p>        
                    <p align="right"><a href="<?php the_permalink(); ?>">Read     More</a></p>    
                    <span class="post-meta"> Post By <?php the_author(); ?>    
                     | Date : <?php echo date('j F Y'); ?></span>    

                    </article><!-- #post -->    
                </div>
        <?php endwhile; ?>
    <?php endif; ?>




           </div><!-- content -->    
        </div><!-- contentarea -->   
        <?php get_sidebar(); ?>
        <?php get_footer(); ?>
  1. Build Search Form
    In this Search Form, the value "products" is hidden and it will search only product posts.

     <div>   
        <h3>Search Products</h3>
        <form role="search" action="<?php echo site_url('/'); ?>" method="get" id="searchform">
        <input type="text" name="s" placeholder="Search Products"/>
        <input type="hidden" name="post_type" value="products" /> <!-- // hidden 'products' value -->
        <input type="submit" alt="Search" value="Search" />
      </form>
     </div>
    

for more, I would like to link you to here
http://www.wpbeginner.com/wp-tutorials/how-to-create-advanced-search-form-in-wordpress-for-custom-post-types/

  • Tip: when registering the post type, the publicly_queryable argument must be set to true. If not, the get_query_var('post_type') will never return the post_type value given in the url argument. codex.wordpress.org/Function_Reference/… – Gustavo May 21 '15 at 17:46
  • Another tip/suggested edit: get_query_var('post_type') returned an array (rather than a string) so couldn't be compared directly. Since I'm only searching one post type at a time, I simply changed my $post_type var to $post_type[0]. – indextwo Apr 8 '16 at 15:51
  • is there a way to rewrite the url from http://localhost:3000/?s=cloud%27&post_type=product to http://localhost:3000/search/cloud/product – YarGnawh Nov 6 '17 at 16:33
  • @YarGnawh Sorry for late response, check this out wordpress.stackexchange.com/questions/15418/…. There is a plugin called rewrite too wordpress.org/plugins/rewrite – Ronald Nov 13 '17 at 11:20
  • the search_template filter seems to be a more appropriate alternative to template_include – Alexey Kosov Jul 19 at 13:02

Here is what works for me. Not as clean but I couldn't get any of these other answers to work.

Search form for Custom Post Type:

<form role="search" method="get" class="search-form" action="<?php echo home_url( '/' ); ?>">
    <label>
        <span class="screen-reader-text"><?php echo _x( 'Search for:', 'label' ) ?></span>
        <input type="search" class="search-field" placeholder="<?php echo esc_attr_x( 'Search …', 'placeholder' ) ?>" value="<?php echo get_search_query() ?>" name="s" title="<?php echo esc_attr_x( 'Search for:', 'label' ) ?>" />
        <input type="hidden" name="post_type" value="book" />
    </label>
    <input type="submit" class="search-submit" value="<?php echo esc_attr_x( 'Search', 'submit button' ) ?>" />
</form>

In functions.php:

function searchfilter($query) {
    if ($query->is_search && !is_admin() ) {
        if(isset($_GET['post_type'])) {
            $type = $_GET['post_type'];
                if($type == 'book') {
                    $query->set('post_type',array('book'));
                }
        }       
    }
return $query;
}
add_filter('pre_get_posts','searchfilter');

In search.php:

<?php if (have_posts()) : ?>
<?php while (have_posts()) : the_post(); ?>
    <?php if(isset($_GET['post_type'])) {
        $type = $_GET['post_type'];
           if($type == 'book') {?>

               /* Format for "book" custom post type */

           <?php } else { ?>

               /* Format for custom post types that are not "book,"
               or you can use elseif to specify a second post type the
               same way as above. Copy the default format here if you
               only have one custom post type. */

           <?php } ?>
    <?php } else { ?>

              /* Format to display when the post_type parameter
              is not set (i.e. default format) */
<?php } ?>
<?php endwhile; else: ?>

/* What to display if there are no results. */

<?php endif; ?>

Naturally in all three places you'll need to replace "book" with your custom post type.

Hope this helps someone!

A short code more actualized

 function template_chooser($template)   
{    
  global $wp_query; 
  $post_type = $wp_query->query_vars["pagename"];   
  if( isset($_GET['s']) && $post_type == 'products' )   
  {

    return locate_template('archive-search.php');  //  redirect to archive-search.php
  }   
  return $template;   
}
add_filter('template_include', 'template_chooser'); 

I was looking to use two different forms for my normal searches and my searches on a custom post type.

My custom post type uses a different header than normal pages, on my normal page, the call to my search form is:

<?php get_search_form(true); ?>

And the call to my search form in the custom post type header is:

<?php get_template_part('search','library'); ?>

Which has an additional field:

<input type="hidden" name="post_type" value="library" /> //Where "library" is my custom post type.

In the functions file I have the following code that you have provided.

/** Custom Search for Library */
function search_library($template)   
{    
  global $wp_query;   
  $post_type = get_query_var('post_type');   
  if( $wp_query->is_search && $post_type == 'library' )   
  {
    return locate_template('search-library.php');  //  redirect to archive-search.php
  }   
  return $template;   
}
add_filter('template_include', 'search_library');

Which detects if the search form is doing a search within custom fields, thus showing the search in a custom template, otherwise use the normal template.

Edit: fixed the get_search_form() function call which would have returned true no matter what.

  • 1
    Worth noting, but get_search_form('true') should be get_search_form(true). get_search_form is looking for a boolean input, so either true or false. By wrapping it in quotes you are feeding it a string, not a boolean parameter. The way that function is set up, both 'true' and 'false' would return the same result, because they are both non-empty strings (which causes the function to return true in both cases). – Mike Feb 22 at 1:29

To fix the empty input search issue you can substitute the function code with this:

function template_chooser($template)   
{    
 global $wp_query;   
 $post_type = get_query_var('post_type');   
 if( isset($_GET['s']) && $post_type == 'products' )   
 {
  return locate_template('archive-search.php');  //  redirect to archive-search.php
 }   
 return $template;   
}
add_filter('template_include', 'template_chooser');
  • 3
    Would be great if you explain how your code works, an reveal your source of the code – Pieter Goosen Sep 16 '14 at 11:00

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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