A user asks:
I need help please, with querying an ACF relationship field on a single CPT template.
Here’s the scenario:
I have two Custom Post Types (CPTs) – “Branches” and “Services”. These two CPTs are linked by an ACF relationship field, allowing me to choose which services are related to a branch and vice versa.
The “Services” CPT has a taxonomy called “Service Category”, which includes categories like Massages, Facials, Nail Care, etc. This structure allows me to group the service posts.
I’ve created a single template for the “Branches” post type. On this template, I aim to display the “Service Category” taxonomy and list the related services linked to a branch under the taxonomy.
This Pro tutorial provides the steps for displaying related CPT 2 posts grouped by a CPT 2’s taxonomy on CPT 1 post page in Bricks.
Scenario:
CPT 1 = Branch
CPT 2 = Service
CPT 2 taxonomy = Service Category
Objective: On single branches, show related services grouped by service categories.

We shall
- Get unique service category IDs for related services of the current branch post
- Set up a Terms query with include param set to the above
- Set up an inner Posts query with service-category set to the current looping term and restrict the posts to related services
Single Tutorial Purchase Option
Lifetime access to this single tutorial can be purchased for $39 here.
Step 1
Register your Branch and Service CPTs and Service Category Taxonomy using ACF.
Register Branch Fields and Service Fields field groups having Related Services and Related Branches Relationship type fields respectively.
Edit each field and enable Bidirectional relationship.


Step 2
Create posts for both CPTs.
Edit posts of any one CPT and populate the Relationship field.

Step 3
Let’s add a custom function to get unique service category IDs for related services of the current branch post.
Add the following in child theme‘s functions.php (w/o the opening PHP tag) or a code snippets plugin:
<?php
/**
* Get unique service category IDs for related services of the current branch post.
*
* @return int[] Array of unique service category term IDs.
*/
function bl_get_related_services_categories() : array {
// Ensure we're on a single 'branch' post
if ( ! is_singular( 'branch' ) ) {
return [];
}
$related_services = get_field( 'related_services' );
// Check if related_services field exists and is not empty
if ( empty( $related_services ) || ! is_array( $related_services ) ) {
return [];
}
$service_ids = wp_list_pluck( $related_services, 'ID' );
// Use wp_get_object_terms() for better performance when fetching multiple terms
$categories = wp_get_object_terms( $service_ids, 'service-category', [
'fields' => 'ids', // Only get term IDs
] );
// Check for WP_Error and return an empty array if there's an error
if ( is_wp_error( $categories ) ) {
return [];
}
// Use array_unique() to remove duplicates
return array_values( array_unique( $categories ) );
}
Step 4
Whitelist the bl_get_related_services_categories function.
Ex.:
<?php
add_filter( 'bricks/code/echo_function_names', function() {
return [
'bl_get_related_services_categories'
];
} );
You should also add other functions (native or custom) being used in your Bricks instance besides bl_get_related_services_categories. This can be checked at Bricks → Settings → Custom code by clicking the Code review button.
More info on whitelisting can be found here.
Step 5
Create a single-type of Template titled, say “Branch”.
Edit it with Bricks.
Apply a template condition like this:

You may want to add a Section that shows the post title and content.
Below that, copy the JSON of a Section for the related services from here and paste.

Outer query loop’s PHP:
if ( bl_get_related_services_categories() ) {
return [
'taxonomy' => 'service-category',
'include' => bl_get_related_services_categories(),
'hide_empty' => false,
'orderby' => 'name',
'order' => 'ASC',
];
} else {
return [
'taxonomy' => 'service-category',
'include' => [ 0 ],
];
}
Inner query loop’s PHP:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| if ( get_field( ‘related_services’ ) ) { | |
| return [ | |
| ‘post_type’ => ‘service’, | |
| ‘post__in’ => wp_list_pluck( get_field( ‘related_services’ ), ‘ID’ ), | |
| ‘orderby’ => ‘post__in’, | |
| ‘tax_query’ => [ | |
| [ | |
| ‘taxonomy’ => ‘service-category’, | |
| ‘terms’ => {term_id}, | |
| ] | |
| ], | |
| ]; | |
| } else { | |
| return [ | |
| ‘post__in’ => [ 0 ], | |
| ]; | |
| } |
Check the front end.