Multi-choice Select Field Based Querying in Bricks

One of our site members asked:

Any chance you guys could create a tutorial for to show us how to be more granular with meta queries?

For example, I have a grid of CPTs queried.

I want to query CPTs that match Manufacturer: 1 or 2 AND Material: stainless steel

Right now I can only do Manufacturer 1 AND 2 AND Stainless Steel (which would only be CPTs tagged as all 3) or Manufacturer 1 OR 2 OR Stainless Steel which would be CPTs that have any of one those.

For example, any way to say Manufacturer: 1, 2 AND Material: Stainless Steel?

Let’s take a scenario where a product post type has a corresponding manufacturer and material custom fields.

Product 1
Manufacturer: Manufacturer 2
Materials: Copper, Iron

Product 2
Manufacturer: Manufacturer 1
Materials: Stainless steel

Product 3
Manufacturer: Manufacturer 3
Materials: Iron, Stainless steel

Product 4
Manufacturer: Manufacturer 2
Materials: Stainless steel

Requirement: Query CPT items that match Manufacturer: 1 or 2 AND Material: Stainless steel
i.e., Product 2 and Product 4.

Custom field group:

Note that “Select multiple values” is on for both the fields.

This Pro tutorial provides the steps for adding a custom meta_query that will filter or limit the posts to match the following:

manufacturer (array) is Manufacturer 1 OR Manufacturer 2
AND
material (array) is Stainless Steel

in Bricks.

Step 1

Edit the Page/template in which you would like to show the CPT items with Bricks.

Inside a Section’s Container, add a Posts element or set up Query Loop on a Container/Block (I typically use a Block element for query loops).

Edit the Query settings.

Post type: Products (change this to your post type, if different)

Posts per page: 100 (a large enough number that the total number of items of this CPT will never exceed in your site)

Do not set a meta query here because it is not possible to do what we want via the query popup controls.

Step 2

Add the following in child theme‘s functions.php or a code snippets plugin:

add_filter( 'bricks/posts/query_vars', function( $query_vars, $settings, $element_id ) {
	if ( $element_id !== 'ledqon' ) {
		return $query_vars;
	}

	// set meta_query that matches the following:
	// manufacturer (array) is Manufacturer 1 OR Manufacturer 2
	// AND
	// material (array) is Stainless Steel
	$query_vars['meta_query'] = [
		'relation' => 'AND',
		'manufacturer_clause' => [
			'relation' => 'OR',
			[
				'key' => 'manufacturer',
				'value' => 'Manufacturer 1',
				'compare' => 'LIKE',
			],
			[
				'key' => 'manufacturer',
				'value' => 'Manufacturer 2',
				'compare' => 'LIKE',
			],
		],
		'material_clause' => [
			'key' => 'material',
			'value' => 'Stainless steel',
			'compare' => 'LIKE',
		],
	];

	$query_vars['no_found_rows'] = true; // useful when pagination is not needed
	$query_vars['update_post_term_cache'] = false; // useful when taxonomy terms will not be utilized

	return $query_vars;
}, 10, 3 );

Replace ledqon with the Bricks ID of the Posts element or the element on which query loop is checked.

The main thing to note in the above code is 'compare' => 'LIKE'. It is needed since our Select-type of post meta stores values in an array (due to us toggling Select multiple values on) and not a string.

Reference

https://wordpress.stackexchange.com/a/55359