Add a Category Select Dropdown Box to Search Form
One of the most popular ways to integrate search is to allow visitors to control the results pool on their own. This usually comes in the form of allowing them to choose a specific Category from a dropdown (select box) to go along with their search.
This article will explain how you can accomplish three different approaches to adding a Category dropdown to your search form.
- Build your own search form with a Categories dropdown
- Customize the Shortcodes Extension to include a Categories dropdown
- Customize the default search form to include a Categories select dropdown
Building your own search form
Building your own search form involves editing your theme files to include the input fields and buttons we want to include. At a most basic level you can add the following to your theme template file where you would like the form to appear:
<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="Search..." value="<?php echo esc_attr( get_search_query() ); ?>" name="s" title="<?php echo esc_attr_x( 'Search for:', 'label' ); ?>" /> | |
</label> | |
<?php | |
// output all of our Categories | |
// for more information see http://codex.wordpress.org/Function_Reference/wp_dropdown_categories | |
$swp_cat_dropdown_args = array( | |
'show_option_all' => __( 'Any Category' ), | |
'name' => 'swp_category_limiter', | |
); | |
wp_dropdown_categories( $swp_cat_dropdown_args ); | |
?> | |
<input type="submit" class="search-submit" value="Search" /> | |
</form> |
Based on the default search form provided by WordPress, this form outputs a field for the search query, a select box containing all of your Categories, and a button to trigger the search. Note the arguments passed to wp_dropdown_categories()
that define the ‘Any Category’ label and set the name
of the dropdown as swp_category_limiter
.
With your form in place, the last step is to tell SearchWP to take the submitted dropdown value into consideration when performing searches. To do that we’re going to use a Mod
. We’re going to use the category ID submitted in the dropdown to limit our search results pool to the chosen category.
Note: notice that the variable we’re looking for was the one we used to set the name
of the select
which was output by wp_dropdown_categories()
All hooks should be added to your custom SearchWP Customizations Plugin.
<?php | |
// Limit SearchWP results to chosen Category from dropdown. | |
// @link https://searchwp.com/documentation/knowledge-base/category-select-dropdown/ | |
add_filter( 'searchwp\query\mods', function( $mods, $query ) { | |
global $wpdb; | |
// Only proceed if a Category was chosen from the dropdown. | |
if ( ! isset( $_GET['swp_category_limiter'] ) || empty( intval( $_GET['swp_category_limiter'] ) ) ) { | |
return $mods; | |
} | |
// Optional: only proceed if we're using a specific Engine. | |
// if ( 'default' !== $query->get_engine()->get_name() ) { | |
// return $mods; | |
// } | |
$alias = 'swpkbcat'; | |
$tax_query = new WP_Tax_Query( [ [ | |
'taxonomy' => 'category', | |
'field' => 'term_id', | |
'terms' => absint( $_GET['swp_category_limiter'] ), | |
] ] ); | |
$tq_sql = $tax_query->get_sql( $alias, 'ID' ); | |
$mod = new \SearchWP\Mod(); | |
// If the JOIN is empty, WP_Tax_Query assumes we have a JOIN with wp_posts, so let's make that. | |
if ( ! empty( $tq_sql['join'] ) ) { | |
// Queue the assumed wp_posts JOIN using our alias. | |
$mod->raw_join_sql( function( $runtime ) use ( $wpdb, $alias ) { | |
return "LEFT JOIN {$wpdb->posts} {$alias} ON {$alias}.ID = {$runtime->get_foreign_alias()}.id"; | |
} ); | |
// Queue the WP_Tax_Query JOIN which already has our alias. | |
$mod->raw_join_sql( $tq_sql['join'] ); | |
// Queue the WP_Tax_Query WHERE which already has our alias. | |
$mod->raw_where_sql( '1=1 ' . $tq_sql['where'] ); | |
} else { | |
// There's no JOIN here because WP_Tax_Query assumes a JOIN with wp_posts already | |
// exists. We need to rebuild the tax_query SQL to use a functioning alias. The Mod | |
// will ensure the JOIN, and we can use that Mod's alias to rebuild our tax_query. | |
$mod->set_local_table( $wpdb->posts ); | |
$mod->on( 'ID', [ 'column' => 'id' ] ); | |
$mod->raw_where_sql( function( $runtime ) use ( $tax_query ) { | |
$tq_sql = $tax_query->get_sql( $runtime->get_local_table_alias(), 'ID' ); | |
return '1=1 ' . $tq_sql['where']; | |
} ); | |
} | |
$mods[] = $mod; | |
return $mods; | |
}, 20, 2 ); |
This snippet checks to make sure that a non-empty value was chosen from the dropdown. If so, our Mod
is built and added to the Query
.
Use SearchWP’s Shortcodes Extension
SearchWP’s Shortcodes Extension allows you to easily output search forms and control search results pages using WordPress Shortcodes. Here is an example search form that includes a Categories dropdown to choose from:
All hooks should be added to your custom SearchWP Customizations Plugin.
<?php | |
// UNCOMMENT THIS IF YOU WANT TO USE SHORTCODES IN WIDGETS | |
// add_filter( 'widget_text', 'do_shortcode' ); | |
// output the categories dropdown | |
function my_searchwp_shortcodes_inject_categories() { | |
echo '<p class="searchwp-shortcodes-categories">'; | |
// for more information see http://codex.wordpress.org/Function_Reference/wp_dropdown_categories | |
$swp_cat_dropdown_args = array( | |
'show_option_all' => __( 'Any Category' ), | |
'name' => 'swp_category_limiter', | |
); | |
wp_dropdown_categories( $swp_cat_dropdown_args ); | |
echo '</p>'; | |
} | |
add_action( 'searchwp_shortcodes_after_input', 'my_searchwp_shortcodes_inject_categories' ); |
That takes care of our search form, it will automatically include a dropdown of our Categories between the search field and the submit button. Note that in this snippet we have customized the name
of the dropdown to be swp_category_limiter
, which we will be using next.
So far we have only set up the form to output a dropdown that will let the visitor define a category for results restriction, we still need to grab that information when the form is submitted and tell SearchWP about it.
To do that we’re going to use a Mod
. We’re going to use the category ID submitted in the dropdown to limit our search results pool to the chosen category.
Note: notice that the variable we’re looking for was the one we used to set the name
of the select
which was output by wp_dropdown_categories()
All hooks should be added to your custom SearchWP Customizations Plugin.
<?php | |
// Limit SearchWP results to chosen Category from dropdown. | |
// @link https://searchwp.com/documentation/knowledge-base/category-select-dropdown/ | |
add_filter( 'searchwp\query\mods', function( $mods, $query ) { | |
global $wpdb; | |
// Only proceed if a Category was chosen from the dropdown. | |
if ( ! isset( $_GET['swp_category_limiter'] ) || empty( intval( $_GET['swp_category_limiter'] ) ) ) { | |
return $mods; | |
} | |
// Optional: only proceed if we're using a specific Engine. | |
// if ( 'default' !== $query->get_engine()->get_name() ) { | |
// return $mods; | |
// } | |
$alias = 'swpkbcat'; | |
$tax_query = new WP_Tax_Query( [ [ | |
'taxonomy' => 'category', | |
'field' => 'term_id', | |
'terms' => absint( $_GET['swp_category_limiter'] ), | |
] ] ); | |
$tq_sql = $tax_query->get_sql( $alias, 'ID' ); | |
$mod = new \SearchWP\Mod(); | |
// If the JOIN is empty, WP_Tax_Query assumes we have a JOIN with wp_posts, so let's make that. | |
if ( ! empty( $tq_sql['join'] ) ) { | |
// Queue the assumed wp_posts JOIN using our alias. | |
$mod->raw_join_sql( function( $runtime ) use ( $wpdb, $alias ) { | |
return "LEFT JOIN {$wpdb->posts} {$alias} ON {$alias}.ID = {$runtime->get_foreign_alias()}.id"; | |
} ); | |
// Queue the WP_Tax_Query JOIN which already has our alias. | |
$mod->raw_join_sql( $tq_sql['join'] ); | |
// Queue the WP_Tax_Query WHERE which already has our alias. | |
$mod->raw_where_sql( '1=1 ' . $tq_sql['where'] ); | |
} else { | |
// There's no JOIN here because WP_Tax_Query assumes a JOIN with wp_posts already | |
// exists. We need to rebuild the tax_query SQL to use a functioning alias. The Mod | |
// will ensure the JOIN, and we can use that Mod's alias to rebuild our tax_query. | |
$mod->set_local_table( $wpdb->posts ); | |
$mod->on( 'ID', [ 'column' => 'id' ] ); | |
$mod->raw_where_sql( function( $runtime ) use ( $tax_query ) { | |
$tq_sql = $tax_query->get_sql( $runtime->get_local_table_alias(), 'ID' ); | |
return '1=1 ' . $tq_sql['where']; | |
} ); | |
} | |
$mods[] = $mod; | |
return $mods; | |
}, 20, 2 ); |
This snippet checks to make sure that a non-empty value was chosen from the dropdown. If so, our Mod
is built and added to the Query
.
Modify the default search form to include a Categories dropdown
WordPress allows us to filter the default search form found in many themes. It’s generated by a call to get_search_form()
which can be completely customized either by including a file named searchform.php
in your theme directory, or via the get_search_form
filter. For this example we will be using the get_search_form
filter. To use this filter you will be working in your theme’s functions.php
file.
To include a Categories dropdown in your site’s default search form, use the following snippet:
All hooks should be added to your custom SearchWP Customizations Plugin.
<?php | |
// adds a Categories dropdown to the search form | |
function my_searchwp_get_search_form_with_categories_dropdown( $form ) { | |
ob_start(); ?> | |
<form role="search" method="get" class="search-form" action="<?php echo home_url( '/' ); ?>"> | |
<label> | |
<span class="screen-reader-text">Search For</span> | |
<input type="search" class="search-field" placeholder="Search..." value="<?php echo esc_attr( get_search_query() ); ?>" name="s" title="Search for:" /> | |
</label> | |
<?php | |
// for more information see http://codex.wordpress.org/Function_Reference/wp_dropdown_categories | |
$swp_cat_dropdown_args = array( | |
'show_option_all' => __( 'Any Category' ), | |
'name' => 'swp_category_limiter', | |
); | |
wp_dropdown_categories( $swp_cat_dropdown_args ); | |
?> | |
<input type="submit" class="search-submit" value="Search" /> | |
</form> | |
<?php return ob_get_clean(); | |
} | |
add_filter( 'get_search_form', 'my_searchwp_get_search_form_with_categories_dropdown' ); |
The form code used here is based on the default search form that ships with WordPress. There is a chance your theme previously customized the form, and you simply want to add the dropdown to it. You can simply modify the form code to match what shipped with your theme and adding lines 11-18
from that code sample where you want your Categories dropdown to appear.
This snippet only modifies the search form, we still need to capture the value from the dropdown and tell SearchWP to limit results to a specific Category.
To do that we’re going to use a Mod
. We’re going to use the category ID submitted in the dropdown to limit our search results pool to the chosen category.
Note: notice that the variable we’re looking for was the one we used to set the name
of the select
which was output by wp_dropdown_categories()
All hooks should be added to your custom SearchWP Customizations Plugin.
<?php | |
// Limit SearchWP results to chosen Category from dropdown. | |
// @link https://searchwp.com/documentation/knowledge-base/category-select-dropdown/ | |
add_filter( 'searchwp\query\mods', function( $mods, $query ) { | |
global $wpdb; | |
// Only proceed if a Category was chosen from the dropdown. | |
if ( ! isset( $_GET['swp_category_limiter'] ) || empty( intval( $_GET['swp_category_limiter'] ) ) ) { | |
return $mods; | |
} | |
// Optional: only proceed if we're using a specific Engine. | |
// if ( 'default' !== $query->get_engine()->get_name() ) { | |
// return $mods; | |
// } | |
$alias = 'swpkbcat'; | |
$tax_query = new WP_Tax_Query( [ [ | |
'taxonomy' => 'category', | |
'field' => 'term_id', | |
'terms' => absint( $_GET['swp_category_limiter'] ), | |
] ] ); | |
$tq_sql = $tax_query->get_sql( $alias, 'ID' ); | |
$mod = new \SearchWP\Mod(); | |
// If the JOIN is empty, WP_Tax_Query assumes we have a JOIN with wp_posts, so let's make that. | |
if ( ! empty( $tq_sql['join'] ) ) { | |
// Queue the assumed wp_posts JOIN using our alias. | |
$mod->raw_join_sql( function( $runtime ) use ( $wpdb, $alias ) { | |
return "LEFT JOIN {$wpdb->posts} {$alias} ON {$alias}.ID = {$runtime->get_foreign_alias()}.id"; | |
} ); | |
// Queue the WP_Tax_Query JOIN which already has our alias. | |
$mod->raw_join_sql( $tq_sql['join'] ); | |
// Queue the WP_Tax_Query WHERE which already has our alias. | |
$mod->raw_where_sql( '1=1 ' . $tq_sql['where'] ); | |
} else { | |
// There's no JOIN here because WP_Tax_Query assumes a JOIN with wp_posts already | |
// exists. We need to rebuild the tax_query SQL to use a functioning alias. The Mod | |
// will ensure the JOIN, and we can use that Mod's alias to rebuild our tax_query. | |
$mod->set_local_table( $wpdb->posts ); | |
$mod->on( 'ID', [ 'column' => 'id' ] ); | |
$mod->raw_where_sql( function( $runtime ) use ( $tax_query ) { | |
$tq_sql = $tax_query->get_sql( $runtime->get_local_table_alias(), 'ID' ); | |
return '1=1 ' . $tq_sql['where']; | |
} ); | |
} | |
$mods[] = $mod; | |
return $mods; | |
}, 20, 2 ); |
This snippet checks to make sure that a non-empty value was chosen from the dropdown. If so, our Mod
is built and added to the Query
.