Consider the following scenario.
CPT: product (from WooCommerce)
ACF field group for the product post type: A Repeater with a Select sub field and Post Object sub field that’s limited to product CPT.

Repeater field being populated on a sample product edit screen:

So every product will have its own related products (books) in different languages.
The objective is to group these related books by their language (the sub field value) and show them in a slider.
In this Pro tutorial, we shall write a custom function that loops through all the Repeater rows and forms an associative array of languages mapped to the array of corresponding products, register a custom query type of ‘Product Languages’ taken from the function and use this in a Bricks nestable slider.
Step 1
Add the following in child theme‘s functions.php (w/o the opening PHP tag) or a code snippets plugin:
// Function to get current product's related products grouped by languages
function bl_get_related_products(): array {
$lang_prod_arr = [];
// check if the repeater field has rows of data.
if ( have_rows( 'book_translations' ) ) {
// loop through the rows of data.
while ( have_rows( 'book_translations' ) ) : the_row();
$language = get_sub_field( 'books_language_select' );
$product_id = get_sub_field( 'book_for_selected_language' );
// $lang_prod_arr[$language] = $product_id; // this overwrites the language with the last product ID for that language, not good
// Check if the language already exists as a key in the array
if ( ! isset( $lang_prod_arr[$language] ) ) {
// If not, create a new array for this language
$lang_prod_arr[$language] = [];
}
// Append the product ID to the language's array
$lang_prod_arr[$language][] = $product_id;
endwhile;
} else {
// no rows found.
}
return $lang_prod_arr;
}
// Add new "Product Languages" query loop type option in the dropdown.
add_filter( 'bricks/setup/control_options', function( $control_options ): array {
$control_options['queryTypes']['product_languages'] = esc_html__( 'Product Languages' );
return $control_options;
} );
// Run new query if option selected.
add_filter( 'bricks/query/run', function( $results, $query_obj ): array {
if ( $query_obj->object_type !== 'product_languages' ) return $results;
// if option is selected, run our new query
if ( $query_obj->object_type === 'product_languages' ) {
$results = array_keys( bl_get_related_products() );
}
return $results;
}, 10, 2 );
// Function to get the current looping object.
if ( ! function_exists( 'bl_get_loop_object_string' ) ) {
function bl_get_loop_object_string(): string {
$looping_query_id = BricksQuery::is_any_looping();
if ( $looping_query_id ) {
return BricksQuery::get_loop_object( $looping_query_id );
}
// fallback, this won't be the one that's output
return '';
}
}
// Helper function to get looping parent query Id by level. Default is parent of the current loop.
// https://itchycode.com/bricks-builder-useful-functions-and-tips/
function itchy_get_bricks_looping_parent_query_id_by_level( $level = 1 ) {
global $bricks_loop_query;
if ( empty( $bricks_loop_query ) || $level < 1 ) {
return false;
}
$current_query_id = BricksQuery::is_any_looping();
if ( ! $current_query_id ) {
return false;
}
if ( ! isset( $bricks_loop_query[ $current_query_id ] ) ) {
return false;
}
$query_ids = array_reverse( array_keys( $bricks_loop_query ) );
if ( ! isset( $query_ids[ $level ] )) {
return false;
}
if ( $bricks_loop_query[ $query_ids[ $level ] ]->is_looping ) {
return $query_ids[ $level ];
}
return false;
}
// Set Product element's posts
add_filter( 'bricks/posts/query_vars', function( $query_vars, $settings, $element_id ) {
if ( $element_id === 'gfkblz' ) {
$query_vars['posts_per_page'] = 100; // a large number
$query_vars['no_found_rows'] = true;
$query_vars['post__in'] = em_get_related_products()[BricksQuery::get_loop_object( itchy_get_bricks_looping_parent_query_id_by_level() )];
$query_vars['orderby'] = 'post__in';
}
return $query_vars;
}, 10, 3 );
Change field names as needed.
Step 2
Edit single product template with Bricks.
Add a Slider (Nestable) element. Delete all slides other than the first one.

Enable query loop on the first one and set its query type to: Product Languages.
For outputting the language name:
{echo:bl_get_loop_object_string}
Replace gfkblz from the code with the Bricks ID of the Products element.