Need help setting up a looper of products that have an ACF Post Object selected

Hi I’m trying to set up a looper provider to select specific products and I can’t figure it out.

I have set up a custom post type for Board Games and have a page template set up for them.
I also have WooCommerce products that have an ACF field group with a field called “compatible_games” of type Post Object (With return format as Post Object and Select Multiple enabled) this lets me select multiple Board Games each product is compatible with. It works great, I use it to display a list of supported Bard Games on the product page, and you can click on any of them to go to the post for that Board Game.

Now jumping over to the single layout for the custom Board Game Posts I’m trying to get a looper set up to display all the products that are compatible with that game. I can’t figure out how to set up the looper provider to only show the products that contain that game in their “compatible_games” field. So this is what I am asking for help with, how to I make the looper provider select only the Products that have that Board Game included in the compatible_games ACF field.

I am assuming I need to somehow select the products post type where the compatible_games field contains post title somewhere in its array of objects.

Hey Jeffrey,

To display only the WooCommerce products that are compatible with the current Board Game post, you need to query the product post type using a meta query that checks if the current Board Game’s Post ID is stored inside the product’s compatible_games field.

Clarification on How ACF Stores Post Objects

Even though your ACF field is set to return a Post Object, ACF actually stores the data in the database as a PHP serialized array of Post IDs (e.g., a:2:{i:0;s:3:"123";i:1;s:3:"456";}). Therefore, you do not query by the post title; instead, you must query by matching the current Board Game’s ID inside that serialized array.

Here are the two ways you can set this up:


Solution 1: Custom Looper Provider (PHP – Highly Recommended but requires custom coding)

Please just note that the following code serves only as a guide. We cannot support issues that might arise from the use of it and we cannot improve the code. You can subscribe to our One service for that.

Because ACF stores the multiple post objects as a serialized array, querying them directly via the builder’s UI can sometimes lead to partial matches (e.g., searching for ID 12 might mistakenly match ID 123).

Using a Custom Looper hook in your child theme allows for a 100% precise query by wrapping the ID in double quotes.

Step 1: Add PHP Filter to functions.php

Open your child theme’s functions.php file (located at wp-content/themes/pro-child/functions.php) and add the following code at the end of the file:

// Custom Looper Provider to query products compatible with the current Board Game
add_filter('cs_looper_custom_compatible_products', function($result, $args = []) {
    // 1. Get the current Board Game's post ID
    $current_game_id = get_the_ID();
    
    if (!$current_game_id) {
        return [];
    }

    // 2. Query WooCommerce products
    $query = new WP_Query([
        'post_type'      => 'product',
        'posts_per_page' => -1, // Retrieve all compatible products
        'meta_query'     => [
            [
                'key'     => 'compatible_games',
                'value'   => '"' . $current_game_id . '"', // Matches the exact ID format in ACF's serialized array
                'compare' => 'LIKE',
            ]
        ]
    ]);

    // 3. Return the posts array to the Looper Provider
    return $query->posts;
}, 10, 2);

Step 2: Configure in Cornerstone Builder

  1. Open the Single Layout for your Board Game custom post type.
  2. Select the element where you want to start the loop (e.g., a Row, Div, or Layout Grid).
  3. Go to the Customize tab, enable Looper Provider, and configure it:
    • Type: Custom
    • Hook: compatible_products
  4. Select the child element that should repeat (e.g., Column or Div), enable Looper Consumer, and style it.
  5. Inside the consumer, use standard dynamic tags like {{dc:post:title}} or {{dc:woocommerce:product_price}} to display the product details.

Solution 2: Query String (Cornerstone UI Only)

If you prefer not to write any PHP, you can use a Query String provider directly inside the Cornerstone builder.

Configure in Cornerstone Builder:

  1. Select the element you want as your Looper Provider.
  2. Go to the Customize tab and enable Looper Provider:
    • Type: Query String
    • Query: post_type=product&posts_per_page=-1&meta_key=compatible_games&meta_value={{dc:post:id}}&meta_compare=LIKE
  3. Enable Looper Consumer on the repeating child element.

Caveat with Solution 2: Because the query string passes the ID dynamically (e.g. 12) without the surrounding serialization quotes ("12"), it uses a standard SQL LIKE %12% search. This may occasionally pull in a product that has game ID 123 or 412 instead of just game ID 12. Solution 1 is recommended for complete accuracy.

Awesome thanks so much for the help I would have never figured that out on my own. Seems to be working nicely with the PHP function you provided.

Also any chance that as a feature request the Cornerstone UI Only features can be made so that it works like the custom PHP one, where you can choose to have the serialization quotes so that 12 doesn’t match 120 or 312.

Hey Jeffrey,

Hello,

Thank you for your feedback! I’m glad to hear that @Christian’s PHP solution is working well for you.

Regarding your feature request: This is an excellent suggestion, and I can definitely see the value in having a UI-based option that properly handles ACF serialized arrays with the necessary quotes.

I’ve documented this as a feature request for our development team to consider for future updates. While I can’t guarantee a specific timeline for implementation, we regularly review customer feedback when planning new features.

In the meantime, here are a couple of workarounds you might consider:

  1. Stick with the Custom PHP Looper (Recommended) - As you’ve already implemented this, it’s the most reliable approach and handles the serialization correctly.

  2. Modify the ACF Field Settings - If you have the flexibility, you could change your compatible_games field’s Return Format to “Post ID” instead of “Post Object”. While this doesn’t solve the quoting issue, it makes the stored value slightly cleaner. However, this would require updating how you display the compatible games on your product pages.

  3. Use a Custom Taxonomy Instead - For better querying performance and simpler UI-based filtering, you could consider converting this relationship to a custom taxonomy. For example, create a “Board Game” taxonomy and assign products to it. This would allow you to use standard taxonomy queries in Cornerstone without the serialization complexity.

Best regards,
RueNel

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.