Related Posts in Bricks using Post Object in a ACF Repeater

In the Bricks forum a user asks:

Hello,

I have an ACF repeater field with name book_translations. Inside that I have a Post Object field where I select a related woocommerce product for a post and has name book_for_selected_language. In the front end I’m trying to output the featured image of the selected product using an image element and the dynamic shortcode {acf_book_translations_book_for_selected_language} but nothing is rendering.

How can I get the featured image from the post object that lies inside a repeater field? Do I need to write a custom function and call it using echo?

This Pro tutorial for Bricks users provides the steps to output posts of another post type related to the current single post via ACF Post Object sub field inside a Repeater.

If the multiple posts selection setting is enabled for the Post Object-type sub field, follow Related Posts using ACF Post Object in Bricks tutorial instead.

In this example, we shall output products related to the current single post being viewed.

ACF field group:

Set the Post Object field’s Return Format to Post ID.

When a post is being edited:

Output on the front end after implementing the tutorial:

The Section will be set to output conditionally only if there is at least 1 related product.

We shall also ensure that ‘s’ gets added to the ‘Related Product’ heading text if the number of matching or related products for the current post is more than 1.

Both Products element (screenshot) and query loop methods are covered.

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 IDs of related products
function bl_get_related_products_ids(): array {
    $product_ids = [];

    // check if the repeater field has rows of data.
    if ( have_rows( 'related_products' ) ) {
        // loop through the rows of data.
        while ( have_rows( 'related_products' ) ) : the_row();
            $product_ids[] = get_sub_field( 'related_product' );
        endwhile;
    } else {
        // no rows found.
    }

    return [
        'ids' => $product_ids,
        'count' => count( $product_ids )
    ];
}

// Set Product element's posts
add_filter( 'bricks/posts/query_vars', function( $query_vars, $settings, $element_id ) {
    if ( $element_id === 'avtkjd' ) {
        $query_vars['posts_per_page'] = 100; // a large number
        $query_vars['no_found_rows'] = true;
        $query_vars['post__in'] = bl_get_related_products_ids()['ids'];
        $query_vars['orderby'] = 'post__in';
    }

    return $query_vars;
}, 10, 3 );

// Add "s" at the end of a specific heading element's text if there is more than 1 related product
add_filter( 'bricks/element/settings', function( $settings, $element ) {
	if ( $element->id === 'eepsxd' && bl_get_related_products_ids()['count'] > 1 ) {
		$settings['text'] .= 's';
	}

	return $settings;
}, 10, 3 );

Replace related_products in

if ( have_rows( 'related_products' ) ) {

and

while ( have_rows( 'related_products' ) ) : the_row();

with the field name of your Repeater.

Replace related_product in

$product_ids[] = get_sub_field( 'related_product' );

with the field name of the Post Object type field.

Step 2

Edit your single post template with Bricks.

Add a “Related Product” Heading inside a Section’s Container.

Note its element ID and replace eepsxd in the code from Step 1 with it.

Add a Products element.

Note its element ID and replace avtkjd in the code from Step 1 with it.

If you want to use a query loop instead, paste this in its PHP query editor:

return [
	'post_type' => 'product',
	'posts_per_page' => 100, // a large number
	'no_found_rows' => true,
	'post__in' => bl_get_related_products_ids()['ids'],
	'orderby' => 'post__in',
];