This Pro tutorial show how bricks/query/result filter in Bricks builder can be used to sort the results of a ACF (should also work with Meta Box) Relationship query in
- ascending order of post title
- descending order of post title
- ascending order of post date
- descending order of post date
By default the results will be in the order the related posts are arranged (on the right side of the screenshot below) for a post. These can be manually dragged and dropped around in the desired order.

Step 1
Install and activate ACF Pro.
Step 2
Create two CPTs say, service and faq.
Create a field group named Service FAQ Relationship Group.


We have created a single field group that will appear when the entries of either CPTs are edited.
Step 3
This step is not needed in ACF Pro v6.2 and above.
Let’s add some code to make the relationship bidirectional – meaning, if we update/set a Service entry with 1 or more FAQ entries, those FAQ entries will automagically have the corresponding Service entry linked.
Add the following in child theme‘s functions.php or a code snippets plugin:
function bidirectional_acf_update_value( $value, $post_id, $field ) {
// vars
$field_name = $field['name'];
$field_key = $field['key'];
$global_name = 'is_updating_' . $field_name;
// bail early if this filter was triggered from the update_field() function called within the loop below
// - this prevents an inifinte loop
if( !empty($GLOBALS[ $global_name ]) ) return $value;
// set global variable to avoid inifite loop
// - could also remove_filter() then add_filter() again, but this is simpler
$GLOBALS[ $global_name ] = 1;
// loop over selected posts and add this $post_id
if( is_array($value) ) {
foreach( $value as $post_id2 ) {
// load existing related posts
$value2 = get_field($field_name, $post_id2, false);
// allow for selected posts to not contain a value
if( empty($value2) ) {
$value2 = array();
}
// bail early if the current $post_id is already found in selected post's $value2
if( in_array($post_id, $value2) ) continue;
// append the current $post_id to the selected post's 'related_posts' value
$value2[] = $post_id;
// update the selected post's value (use field's key for performance)
update_field($field_key, $value2, $post_id2);
}
}
// find posts which have been removed
$old_value = get_field($field_name, $post_id, false);
if( is_array($old_value) ) {
foreach( $old_value as $post_id2 ) {
// bail early if this value has not been removed
if( is_array($value) && in_array($post_id2, $value) ) continue;
// load existing related posts
$value2 = get_field($field_name, $post_id2, false);
// bail early if no value
if( empty($value2) ) continue;
// find the position of $post_id within $value2 so we can remove it
$pos = array_search($post_id, $value2);
// remove
unset( $value2[ $pos] );
// update the un-selected post's value (use field's key for performance)
update_field($field_key, $value2, $post_id2);
}
}
// reset global varibale to allow this filter to function as per normal
$GLOBALS[ $global_name ] = 0;
// return
return $value;
}
add_filter('acf/update_value/name=service_faq_relationship', 'bidirectional_acf_update_value', 10, 3);
Note how the relationship field’s name, service_faq_relationship is be present in the add_filter() function line.
Step 4
Edit your Service entries and click the corresponding FAQs.
Step 5
Create a Bricks template named say, Service and edit it with Bricks.
In the Template conditions, set it to apply to Services Post type.
Add a Section and inside its Container, Post Title and Post Content elements.
Add another Section and inside its Container, a “Related FAQs” heading.
Add a Container having a Block.
Turn on query loop on the Block, click the query icon and select your ACF relationship as the type.
Add a Basic Text element inside the Block having
{post_title:link}
Save the Template.
Open any Service item that has related FAQs on the front end and you should see the related FAQ items’ titles in the order in which they are present in the WP editor for your Service item.
Step 6
If you’d like to sort the results, use the bricks/query/result filter like so:
Post title ascending
add_filter( 'bricks/query/result', function( $result, $query_obj ) {
if ( $query_obj->object_type !== 'acf_service_faq_relationship' ) {
return $result;
}
if ( ! empty( $result ) ) {
// Sort by post title ascending order
usort( $result, function( $a, $b ) {
return strcmp( $a->post_title, $b->post_title );
} );
}
return $result;
}, 10, 2 );
Post title descending
add_filter( 'bricks/query/result', function( $result, $query_obj ) {
if ( $query_obj->object_type !== 'acf_service_faq_relationship' ) {
return $result;
}
if ( ! empty( $result ) ) {
// Sort by post title descending order
usort( $result, function( $a, $b ) {
return strcmp( $b->post_title, $a->post_title );
} );
}
return $result;
}, 10, 2 );
Post date ascending
add_filter( 'bricks/query/result', function( $result, $query_obj ) {
if ( $query_obj->object_type !== 'acf_service_faq_relationship' ) {
return $result;
}
if ( ! empty( $result ) ) {
// sort by post_date in ascending order
usort( $result, function( $a, $b ) {
return $a->post_date <=> $b->post_date;
} );
}
return $result;
}, 10, 2 );
Post date descending
add_filter( 'bricks/query/result', function( $result, $query_obj ) {
if ( $query_obj->object_type !== 'acf_service_faq_relationship' ) {
return $result;
}
if ( ! empty( $result ) ) {
// sort by post_date in ascending order
usort( $result, function( $a, $b ) {
return $a->post_date <=> $b->post_date;
} );
// then reverse it to sort by post_date in descending order
$result = array_reverse( $result );
}
return $result;
}, 10, 2 );
How does this work?
usort() is a PHP function sorts an array by a user defined comparator function.
The way this gets processed is that all the values in the array that needs sorting are passed to this function 2 at the time (usually you’ll see them as
$aand$b). This is done to determine which one takes precedence over which. The comparator has to return 0 if the 2 values are considered equal, a negative integer if the first value is less than the second value or a positive integer if the second value is less than the first.
In the case of ordering by post titles, we used PHP’s strcmp(), a function that does string comparison.
In the case of ordering by post dates, we used PHP’s “Spaceship operator” which returns -1, 0 or 1 when $a is respectively less than, equal to, or greater than $b.