Written by John Reed
We have a client with a custom WordPress theme that deploys to multiple websites, each with slightly different search requirements—particularly regarding pricing filters. Rather than hard-coding form elements specific to each web property, we needed to give site admins the power to modify their own pricing tiers.
Here’s a breakdown of a solution we developed for making these filters dynamic using an Advanced Custom Fields Repeater element in their theme’s site options.
Assume we have a repeater that returns an array of pricing filters, each with a label
, min
and max
property:
$filters = get_field( 'prices', 'option' ) ?? [ [ 'label' => __( 'Under $7k' ), 'min' => 0, 'max' => 6999, ], [ 'label' => __( '$7k - $15k' ), 'min' => 7000, 'max' => 14999, ], [ 'label' => __( '$15k - $25k' ), 'min' => 15000, 'max' => 24999, ], [ 'label' => __( 'Over $25k' ), 'min' => 25000, 'max' => null, ], ];
Now, we can use this array to build a select element:
<select name="price"> <?php foreach( $filters as $filter ): ?> <option value="<?php printf( '%s-%s', $filter['min'], $filter['max'] ?? '' ); ?>"><?php echo $filter['label']; ?></option> <?php endforeach; ?> </select>
And on the backend, a pre_get_posts hook to filter our meta_query
by our price
parameter.
<?php add_action( 'pre_get_posts', function( $query ) { // limit filter to our `custom-post-type` if `price` is in the request string if( 'custom-post-type' !== $query->get('post_type') || empty( $_GET['price'] ?? '' ) ) return; // separate our prices into an array with - as a delimiter $value = explode( '-', $_GET['price'] ); // use 'BETWEEN' comparison for two prices if( count( $value ) === 2 ) { $query->set( 'meta_query', [ 'relation' => 'AND', [ 'key' => 'price', 'value' => $value, 'compare' => 'BETWEEN', 'type' => 'DECIMAL(10,3)', ], ] ); } // use > comparison if no max is defined else { $query->set( 'meta_query', [ 'relation' => 'AND', [ 'key' => 'price', 'value' => $value[0], 'compare' => '>', 'type' => 'DECIMAL(10,3)', ], ] ); } }, 10 );
Adding our simple ACF repeater to site options, which ties into a form element and, ultimately, our theme’s meta_query filter, allowed us to keep our client’s custom WordPress theme lightweight while flexible enough to deploy to multiple environments.
Photo by Andrew Haimerl on Unsplash