5 min read

WordPress search filters based on custom fields

WordPress search filters based on custom fields

Last modified

WordPress custom fields are good for adding meta data to posts. These custom fields are not just for displaying data but can be used to sort and filter posts. You may be interested in making a form to filter posts by custom fields.

To create custom fields search filters we use WP_Query and specify a meta_query. For example we have a custom post type ‘vendor’, four custom fields country, state, zip and age and vendors are organized in categories. We may be interested to see vendors from certain category and state with certain age group. How do we do that? WordPress provides a nice way to create such meta data search filters.

Below page template can be applied to any page where you want to display your search filters in right sidebar, on form submission it will show you filtered posts in primary area of the page. This page template can be customized to fit your requirements.


<?php
/**
 * Template Name: Custom Search
 *
 * @author Tahir Yasin
 */

get_header();

$fields = array('country', 'state', 'zip', 'min_age', 'max_age');
foreach ($fields as $field)
{
    if ($_REQUEST[$field] != '')
    {
        if ($field == 'min_age')
        {
            $meta_query[] = array(
                'key' => $field,
                'value' => $_REQUEST[$field], // This is OK, WP_Query will sanitize input!
                'compare' => '>=',
            );
        } elseif ($field == 'max_age')
        {
            $meta_query[] = array(
                'key' => $field,
                'value' => $_REQUEST[$field], // This is OK, WP_Query will sanitize input!
                'compare' => '<=',
            );
        }
        else
        // We have something to match, otherwise ignore the field...
            $meta_query[] = array(
                'key' => $field,
                'value' => $_REQUEST[$field], // This is OK, WP_Query will sanitize input!
                'compare' => '=',
            );
    }
}
$args = array(
    'post_type' => 'vendor',
    'category__in' => $_REQUEST['category'],
    'posts_per_page' => -1, // -1 to display all results at once
    'order' => 'ASC',
    'meta_query' => $meta_query,
);
$query = new WP_Query($args);
?>
<div id="primary">
    <div id="content" role="main">
        <?php if ($query->have_posts()) : while ($query->have_posts()) : $query->the_post();
                ?>
                <div class="post">
                    <?php the_title(); ?>
                </div>
                <?php
            endwhile; //end of the loop
        endif;
        ?>
    </div><!-- #content -->
</div><!-- #primary -->

<div id="secondary" class="widget-area" role="complementary">
    <form method="get">

        <label for="country">Country:</label>
        <input type="text" name="country" value="" />

        <label for="state">State: </label>
        <input type="text" name="state" value="" />

        <label for="zip">Zip: </label>
        <input type="text" name="zip" value="" />

        <label for="min_age">Min Age:</label>
        <input type="text" name="min_age" value="" />


        <label for="max_age">Max Age: </label>
        <input type="text" name="max_age" value="" />

        <label for="category">Category:</label><br />
        Category 1<input type="checkbox" value="5" name="category[]" /><br />
        Category 2<input type="checkbox" value="6" name="category[]" /><br />
        Category 3<input type="checkbox" value="7" name="category[]" /><br />
        Category 4<input type="checkbox" value="8" name="category[]" /><br />
        <input type="submit" value="Search" />
    </form>
</div>

<?php get_footer(); ?>