Sitemap

Create Custom Post Type Search Result Page In WordPress

3 min readDec 22, 2021

In this blog, we will learn about how to create a custom post-type search result page in WordPress.

We need to take the following steps:

  1. Create a custom search page template ( {custom-post-type}-search.php )
  2. Load your template using ‘template_include’ filter
  3. Create a custom search form template ( {custom-post-type}-searchform.php )

Step One — Custom Search Page Template

Create a Custom search page template custom-post-type-search.php

<?php
/**
* Custom Post Type Search result page.
*
*
@package Aquila
*/
get_header();
global $wp_query;

?>
<div id="primary">
<main id="main" class="site-main mt-5 mb-14" role="main">
<div class="container">
<header class="mb-5">
<h1 class="page-title">
<?php _e( 'Search results for', 'text-domain' ); ?>: "<?php the_search_query(); ?>"
</h1>
</header>

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

<div class="grid md:grid-cols-3 border-1 border-brand-bright-grey">

<?php while ( have_posts() ) {
the_post();

get_template_part( 'template-parts/common/article' );

} ?>

</div>

<div class="search-results-post-navigation my-5">
<?php
the_posts_navigation();
?>
</div>
<?php } else {
get_template_part( 'template-parts/content', 'none' );
} ?>

</div>
</main>
</div>
<?php get_footer(); ?>

Step 2 — Load your template using ‘template_include’ filter

Inside your functions.php

namespace YourNameSpace;

function render_search_template( $template ) {
global $wp_query;
$post_type = get_query_var( 'post_type' );

if ( ! empty( $wp_query->is_search ) && $post_type == 'custom-post-type-slug') {
return locate_template( 'custom-post-type-search.php' ); // redirect to custom-post-type-search.php
}

return $template;
}

add_filter( 'template_include', __NAMESPACE__ . '\\render_search_template' );

Step 3 — Custom Search Form Template

Create a Custom search form template template-parts/custom-post-type-searchform.php

<?php
/**
* Custom Post Type Search form
*
*
@package Aquila
*/

?>

<form role="search" method="get" id="searchform block" class="search-form" action="<?php echo esc_url( home_url( '/' ) ); ?>" >
<div class="relative">
<label class="screen-reader-text" for="s"><?php esc_html_e( 'Search for:', 'text-domain' ); ?></label>
<input id="search-field" type="search" class="search-field outline-none" placeholder="<?php esc_html_e( 'Search ...', 'text-domain' ); ?>" value="<?php echo esc_html( get_search_query() ); ?>" name="s" />
<input type="hidden" name="post_type" value="custom-post-type-slug" />
<button class="search-button cursor-pointer absolute right-0 top-0 bottom-0 m-auto py-5 px-4 ml-4" type="submit" id="searchsubmit">
<span class="sr-only"><?php esc_html_e( 'Search', 'text-domain' ); ?></span>
<svg class="w-18px h-18px cursor-pointer">
<svg id="search-icon-grey" xmlns="http://www.w3.org/2000/svg" width="17.766" height="17.738" viewBox="0 0 17.766 17.738">
<path id="Path_166" data-name="Path 166" d="M17.63,10.986A6.631,6.631,0,1,0,22.161,22.46l5.7,5.7a.222.222,0,0,0,.318-.311l-5.7-5.7A6.632,6.632,0,0,0,17.63,10.986Zm0,.442a6.189,6.189,0,1,1-6.188,6.189A6.185,6.185,0,0,1,17.63,11.428Z" transform="translate(-10.75 -10.736)" stroke="#000" stroke-miterlimit="10" stroke-width="0.5"/>
</svg>
</svg>
</button>
</div>
</form>

The mainline to note in the above code is <input type=”hidden” name=”post_type” value=”your-custom-post-type-slug” /> This will add a query params post_type in the URL, when the user clicks on the submit button like so : https://example.com/?s=nov&post_type=custom-post-type-slug

So when you print the $wpquery ( from global $wpquery ) in your custom search page template, it will set the post_typevalue in the query object and automatically fetch the results from that post type.

Press enter or click to view image in full size

Now wherever you need the search form, you can include this template using get_template_part()

Bonus Tip

If you want to exclude this custom post type from the search result of the default post type ‘post’. Add the following in your `searchform.php`

<input type="hidden" name="post_type" value="post" />

This will ensure it only shows the result of the post type post

That’s all folks!

--

--

Imran Sayed
Imran Sayed

Written by Imran Sayed

👤 Full Stack Developer at rtCamp, Speaker, Blogger, YouTuber, Wordpress, React, Node, Laravel Developer http://youtube.com/ImranSayedDev https://codeytek.org

No responses yet