filters
John Reed

Written by John Reed

Share

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

Tags
Advanced Custom FieldsPHP