How do I create a custom WordPress search form with specific filters?

Sarah T. Dec 19, 2024 Custom Search Functionality
How can I make a search box for my website that only shows certain types of content?
What is the best method to create a custom WordPress search form that includes specific filters for custom post types and taxonomies?
Andy answered Dec 19, 2024

Creating a Custom WordPress Search Form with Filters

Basic Approach

To create a custom search form with specific filters, you'll need to:

  1. Create a custom search form template
  2. Add filter options (dropdowns, checkboxes, etc.)
  3. Handle the search query
  4. 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

  1. Always sanitize user input
  2. Use nonces for AJAX requests
  3. Validate and escape output
  4. Limit search results for performance
  5. 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

  1. FacetWP (facewp.com)

    • Creates advanced filtering systems
    • Works with any post type or custom field
  2. Search & Filter Pro (searchandfilter.com)

    • Easy to use interface
    • AJAX-powered results
  3. Relevanssi (relevanssi.com)

    • Better search results than WordPress default
    • Supports custom fields and taxonomies

Best Practices

  1. Cache search results when possible
  2. Use proper indexing on your database
  3. Implement progressive loading for large result sets
  4. Add clear filters button
  5. Show loading states during AJAX requests
  6. Maintain mobile-friendly layout
  7. Include search analytics

These solutions can be customized further based on your specific needs and website requirements.