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:
- Create a custom search page template ( {custom-post-type}-search.php )
- Load your template using ‘template_include’ filter
- 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_type
value in the query object and automatically fetch the results from that post type.
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!