Creating a Custom WordPress Search Form with Filters
Basic Approach
To create a custom search form with specific filters, you'll need to:
- Create a custom search form template
- Add filter options (dropdowns, checkboxes, etc.)
- Handle the search query
- Display filtered results
Method 1: Custom Search Form Implementation
Create a basic search form template with post type and taxonomy filters:
<form role="search" method="get" class="search-form" action="<?php echo esc_url(home_url('/')); ?>">
<input type="search" name="s" value="<?php echo get_search_query(); ?>" placeholder="Search...">
<select name="post_type">
<option value="post">Posts</option>
<option value="page">Pages</option>
<option value="product">Products</option>
</select>
<?php
$categories = get_categories();
if ($categories) : ?>
<select name="category">
<option value="">All Categories</option>
<?php foreach ($categories as $category) : ?>
<option value="<?php echo esc_attr($category->term_id); ?>">
<?php echo esc_html($category->name); ?>
</option>
<?php endforeach; ?>
</select>
<?php endif; ?>
<button type="submit">Search</button>
</form>
Modify the search query using pre_get_posts:
add_action('pre_get_posts', 'custom_search_filter');
function custom_search_filter($query) {
if (!is_admin() && $query->is_search() && $query->is_main_query()) {
// Filter by post type
if (!empty($_GET['post_type'])) {
$query->set('post_type', sanitize_text_field($_GET['post_type']));
}
// Filter by category
if (!empty($_GET['category'])) {
$query->set('cat', intval($_GET['category']));
}
}
return $query;
}
Method 2: Using AJAX for Dynamic Results
Add AJAX functionality to your search form:
add_action('wp_footer', 'ajax_search_script');
function ajax_search_script() {
?>
<script>
jQuery(document).ready(function($) {
$('.search-form').on('submit', function(e) {
e.preventDefault();
$.ajax({
url: '<?php echo admin_url('admin-ajax.php'); ?>',
data: {
action: 'custom_search',
search: $('input[name="s"]').val(),
post_type: $('select[name="post_type"]').val(),
category: $('select[name="category"]').val()
},
success: function(response) {
$('#search-results').html(response);
}
});
});
});
</script>
<?php
}
Handle the AJAX request:
add_action('wp_ajax_custom_search', 'handle_ajax_search');
add_action('wp_ajax_nopriv_custom_search', 'handle_ajax_search');
function handle_ajax_search() {
$search = sanitize_text_field($_GET['search']);
$post_type = sanitize_text_field($_GET['post_type']);
$category = intval($_GET['category']);
$args = array(
's' => $search,
'post_type' => $post_type,
);
if ($category) {
$args['cat'] = $category;
}
$query = new WP_Query($args);
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
get_template_part('template-parts/content', 'search');
}
} else {
echo 'No results found';
}
wp_die();
}
Security Considerations
- Always sanitize user input
- Use nonces for AJAX requests
- Validate and escape output
- Limit search results for performance
- Use appropriate user capabilities checks
Common Pitfalls
- Not considering performance with large datasets
- Forgetting to sanitize inputs
- Not handling empty results
- Overlooking mobile responsiveness
- Complex SQL queries affecting site speed
Plugin Solutions
-
FacetWP (facewp.com)
- Creates advanced filtering systems
- Works with any post type or custom field
-
Search & Filter Pro (searchandfilter.com)
- Easy to use interface
- AJAX-powered results
-
Relevanssi (relevanssi.com)
- Better search results than WordPress default
- Supports custom fields and taxonomies
Best Practices
- Cache search results when possible
- Use proper indexing on your database
- Implement progressive loading for large result sets
- Add clear filters button
- Show loading states during AJAX requests
- Maintain mobile-friendly layout
- Include search analytics
These solutions can be customized further based on your specific needs and website requirements.