I couldn’t find a clue or a way suggested Dang in the comments. I also thought to filter the search results using the hook posts_where
, but I have no idea how to recognize if the search is being done by our widget or other search form.
I found a fairly simple way to filter the results that is by placing an input field of type:
<input type="hidden" value="portfolio" name="post_type" />
Studying the WP_Widget_Search
I see that there is no way to modify it to include the filter, so the solution is to make a copy of the widget and adapt it. The modification I made was to remove the get_search_form()
and pull/modify the code of that same function.
PS: adapt CPT to your need, here it is being used portfolio
.
<?php
/**
* Plugin Name: (SOPT) Widget Search by CPT
* Plugin URI: /a/17233/201
* Author: brasofilo
*/
add_action( 'widgets_init', 'b5f_sopt_search' );
function b5f_sopt_search() {
register_widget( 'B5F_SOPT_Search_Widget' );
}
class B5F_SOPT_Search_Widget extends WP_Widget {
function __construct() {
$widget_ops = array('classname' => 'widget_search', 'description' => __( "A search form for your site.") );
parent::__construct( 'search', _x( 'Search', 'Search widget' ), $widget_ops );
}
function widget( $args, $instance ) {
extract($args);
/** This filter is documented in wp-includes/default-widgets.php */
$title = apply_filters( 'widget_title', empty( $instance['title'] ) ? '' : $instance['title'], $instance, $this->id_base );
echo $before_widget;
if ( $title )
echo $before_title . $title . $after_title;
$format = current_theme_supports( 'html5', 'search-form' ) ? 'html5' : 'xhtml';
if ( 'html5' == $format ) {
$form = '<form role="search" method="get" class="search-form" action="' . esc_url( home_url( '/' ) ) . '">
<label>
<span class="screen-reader-text">' . _x( 'Search for:', 'label' ) . '</span>
<input type="search" class="search-field" placeholder="' . esc_attr_x( 'Search …', 'placeholder' ) . '" value="' . get_search_query() . '" name="s" title="' . esc_attr_x( 'Search for:', 'label' ) . '" />
</label>
<input type="hidden" value="portfolio" name="post_type" />
<input type="submit" class="search-submit" value="'. esc_attr_x( 'Search', 'submit button' ) .'" />
</form>';
} else {
$form = '<form role="search" method="get" id="searchform" class="searchform" action="' . esc_url( home_url( '/' ) ) . '">
<div>
<label class="screen-reader-text" for="s">' . _x( 'Search for:', 'label' ) . '</label>
<input type="text" value="' . get_search_query() . '" name="s" id="s" />
<input type="hidden" value="portfolio" name="post_type" />
<input type="submit" id="searchsubmit" value="'. esc_attr_x( 'Search', 'submit button' ) .'" />
</div>
</form>';
}
echo $form;
echo $after_widget;
}
function form( $instance ) {
$instance = wp_parse_args( (array) $instance, array( 'title' => '') );
$title = $instance['title'];
?>
<p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?> <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo esc_attr($title); ?>" /></label></p>
<?php
}
function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$new_instance = wp_parse_args((array) $new_instance, array( 'title' => ''));
$instance['title'] = strip_tags($new_instance['title']);
return $instance;
}
}
Finally, modify your code to:
echo the_widget( 'B5F_SOPT_Search_Widget' );
Related: Can’t limit search to only pages
Important: Where do I put the code snippets I found here or Somewhere Else on the web?
From what I understand from documentation of
the_widget
, would be something likethe_widget('WP_Widget_Search', 'post_type=post');
, or maybethe_widget('WP_Widget_Search', '', 'post_type=post')
. I imagine the possible values forpost_type
are those described in post types documentation.– dang