Hi,
I am trying to build a new Grid to manage cross-sells on my Cart page. However, rather than using the standard Woocommerce cross-sells functionality, I am trying to something a little different. I am pretty sure it is achievable, but am unable to get the Looper to display the results.
I have so far set up a basic grid which will eventually display the product image, title and price for each product.
The page structure is:
Section
Row
Column
Text Element containing [woocomerce_cart]
Grid Element (to display the cross-sells)
Cell 1 (Looper Provider & Looper Consumer - details below)
Headline (cross-sell title)
At Woocommerce product level, every product has an ACF field called “bird_animal_name” which is a mandatory field. (All products are bird-related).
What I would like is my Grid to look at the product(s) in the cart, “see” their ACF field data and to then display a grid of products from different categories, which have a product using the same ACF “bird_animal_name” (there will only ever be one of each “bird_animal_name” in each product category.
For example:
IN CART
- Pheasant Notebook
- Curlew Mug
CROSS_SELL COMPONENT DISPLAYS
- Pheasant Print
- Pheasant Mug
- Pheasant Placemats
- Pheasant … (any other products in other categories with products having the Pheasant “bird_animal_name”)
- Curlew Notebook
- Curlew Print
- Curlew … (any other products in other categories with products having the Curlew “bird_animal_name”)
I have the following functions in place:
The first one should be providing the data I need:
function display_related_products_based_on_cart() {
// Get cart items
$cart_items = WC()->cart->get_cart();
$bird_names = array();
foreach ($cart_items as $cart_item_key => $cart_item) {
$product_id = $cart_item['product_id'];
$bird_name = get_field('bird_animal_name', $product_id);
if ($bird_name && !in_array($bird_name, $bird_names)) {
$bird_names[] = $bird_name;
}
}
// If there are no bird names in the cart, exit the function early
if (empty($bird_names)) return;
// Use collected bird names in WP_Query
$args = array(
'post_type' => 'product',
'meta_query' => array(
array(
'key' => 'bird_animal_name',
'value' => $bird_names,
'compare' => 'IN'
)
)
);
$query = new WP_Query($args);
// Store results of WP_Query in a global variable
$related_products = array();
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
// Store the post (or product) data in an array
$related_products[] = array(
'title' => get_the_title(),
'id' => get_the_ID(),
// Add other data as needed
);
}
wp_reset_postdata();
}
// Store the related products array in a global variable
$GLOBALS['related_products_based_on_cart'] = $related_products;
}
add_action('woocommerce_before_cart', 'display_related_products_based_on_cart');
The second one should be giving a Looper Provider output:
function custom_looper_provider($data, $args) {
if (isset($GLOBALS['related_products_based_on_cart']) && !empty($GLOBALS['related_products_based_on_cart'])) {
return $GLOBALS['related_products_based_on_cart'];
}
return array();
}
In my Grid Cell I have enabled a Looper provider type “Custom” with the entry related_products
The Cell also has a Looper Consumer enabled.
Within the Cell is a Headline, which uses dynamic data {{dc:post:title}}
. However, all I get the the cart’s title, not the data from the Looper provider.
I am pretty certain that the above function is working, as it is a modification of the below one, which definitely outputs the data I want to see in the Looper (though the below function displays it on-screen, whereas I want the data to be available in a Looper for use elsewhere):
function display_related_products_based_on_cart() {
// Get cart items
$cart_items = WC()->cart->get_cart();
$bird_names = array();
foreach ($cart_items as $cart_item_key => $cart_item) {
$product_id = $cart_item['product_id'];
$bird_name = get_field('bird_animal_name', $product_id);
if ($bird_name && !in_array($bird_name, $bird_names)) {
$bird_names[] = $bird_name;
}
}
// If there are no bird names in the cart, exit the function early
if (empty($bird_names)) return;
// Use collected bird names in WP_Query
$args = array(
'post_type' => 'product',
'meta_query' => array(
array(
'key' => 'bird_animal_name',
'value' => $bird_names,
'compare' => 'IN'
)
)
);
$query = new WP_Query($args);
// Display results of WP_Query
if ($query->have_posts()) {
echo '<div class="related-products-based-on-cart">';
echo '<h2>Related Products</h2>'; // You can change the title if needed
while ($query->have_posts()) {
$query->the_post();
// Display the post (or product) data here
the_title(); // As an example
echo '<br>'; // Line break for clarity, adjust as needed
}
wp_reset_postdata();
echo '</div>';
}
}
add_action('woocommerce_before_cart', 'display_related_products_based_on_cart');
Do you have any ideas why the content is not displaying as expected?
Thanks,
Christopher