In this tutorial, we’ll learn how to apply a PHP filter to modify the query var of multiple query loops in a single function
Table of Contents
Introduction
In my last project, I needed to create multiple query loops with a custom query var that couldn’t be achieved within the builder: I needed to order the query loop by multiple dynamic values. So, instead of creating a filter for each element, I shared the same custom query var option with multiple elements.
Let’s see how to achieve it.
The code
In my case, I wanted to order the query loops by two different custom fields value: one called featured and the other one called order. In bricks, you are only able to order your loop by one single dynamic data inside the builder. So, I needed to use the bricks/posts/query_vars filter (here is the documentation) to achieve my goal.
Target ID’s
First of all, I created an array with all the IDs of the query loop elements that I wanted to modify.
Then I checked if the $element_id
is part of the array, else the function stops.
And finally, I applied my custom meta_query
and orderby
options to the query var.
Now all the query loops listed in my array inherit from my custom query var in a single function.
add_filter( 'bricks/posts/query_vars', function( $query_vars, $settings, $element_id ) {
// list all the elements' IDs here
$elements = array(
'ovkyjc',
'flmjqp',
'wyxffa',
'almdys',
);
// Check if the element_id is inside the array
if ( !in_array($element_id, $elements)) {
return $query_vars;
}
// Apply the custom query var
$query_vars['meta_query'] = array(
'relation' => 'AND',
'featured_clause' => array(
'key' => 'featured',
'compare' => 'EXISTS',
'type' => 'numeric',
),
'order_clause' => array(
'key' => 'order',
'compare' => 'EXISTS',
'type' => 'numeric',
),
);
$query_vars['orderby'] = array(
'featured_clause' => 'DESC',
'order_clause' => 'DESC',
);
// return the modified query var
return $query_vars;
}, 10, 3 );
Target a class
We can also target classes instead of IDs.
Update for Bricks v1.8+
It looks like the _cssClasses is no longer included in the $settings, so is no longer possible to use classes like this to identify elements as in the code below. Use $element_id as shown above – David.
Set a class on the query loop element. In this example we use the class my-special-class
.
Then we set the variable $class
with our class in the following code:
add_filter( 'bricks/posts/query_vars', function( $query_vars, $settings, $element_id ) {
// Set your class here
$class = 'my-special-class';
// Check if the element has the correct class set
if ( !isset( $settings['_cssClasses'] ) || !$settings['_cssClasses'] === $class ) {
return $query_vars;
}
// Apply the custom query var
$query_vars['meta_query'] = array(
'relation' => 'AND',
'featured_clause' => array(
'key' => 'featured',
'compare' => 'EXISTS',
'type' => 'numeric',
),
'order_clause' => array(
'key' => 'order',
'compare' => 'EXISTS',
'type' => 'numeric',
),
);
$query_vars['orderby'] = array(
'featured_clause' => 'DESC',
'order_clause' => 'DESC',
);
// return the modified query var
return $query_vars;
}, 10, 3 );
And then we’re done.
2 comments
Ian
Looks like this code doesn't work for Bricks 1.8. It might need an update, unless I'm doing something wrong.
I logged the $settings variable and it doesn't have the class. I wanted to leave a comment with code but Patchstack blocked it.
David Browne
Can confirm, looks like we can't target elements by class. Tested with Bricks v1.8.1. The internal ID of the class is there, but not the actual class name that we add.
Targeting by the $element_id is the way to go.