If you’d like to limit the search form on WordPress site to specific post types globally, there’s and easy way to do that:
// Change search function globally to search only post, page and portfolio post types
function prefix_limit_post_types_in_search( $query ) {
if ( $query->is_search ) {
$query->set( 'post_type', array( 'post','page', 'portfolio' ) );
}
return $query;
}
add_filter( 'pre_get_posts', 'prefix_limit_post_types_in_search' );
But let’s say you want to have a specific search form search limited to one post type, but allow other search forms to search all post types?
Most tutorials I’ve run across suggest that you re-create all the search form markup and then add a hidden input to the form like this:
/* Hidden input field that can be added to search form */
<input type="hidden" name="post_type" value="portfolio">
You can then conditionally load that hidden field on the specific templates where where it is needed.
However, if you’re using get_search_form() and don’t want to completely replace all the search form markup, an alternative would be to do a string replace before outputting the form:
<?php
// Output a search for that only searches portfolio post types
$search = get_search_form( false );
$find = '</form>';
$replace = '<input type="hidden" name="post_type" value="portfolio">' . $find;
$search = str_replace( $find, $replace, $search );
echo $search;
?>
For more reading on how this filter works, you can read the great inline docs in the WordPress codebase itself.