
I think I had similar but found you can alter the API output. For me, I needed to customise the API response for WooCommerce, here’s the code I used which may help:
// Custom API Data
function product_compact_post( $data, $post, $request ) {
$categories = get_the_term_list( $data->data['id'], 'product_cat' );
$categories = strip_tags( $categories );
$product = wc_get_product( $data->data['id'] );
$image_id = $product->get_image_id();
$image_url = wp_get_attachment_image_url( $image_id, 'full' );
$brands = get_the_term_list( $data->data['id'], 'product_brand' );
$brands = strip_tags( $brands );
$model = get_field('model', $data->data['id']);
$sku = str_replace( array(' ', '&', '/'), array('_', '', ''), $model );
return [
'id' => $data->data['id'],
'sku' => $data->sku = $sku,
'name' => $data->data['title']['rendered'],
'link' => $data->data['link'],
'categories'=> $data->categories = $categories,
'image' => $data->image = $image_url,
'manufacturer' => $data->manufacturer = $brands,
'model' => $data->model = $model,
'mpn' => $data->mpn = $model,
'ean' => $data->ean = get_field('ean', $data->data['id'])
];
return $data;
}
add_filter( 'rest_prepare_product', 'product_compact_post', 10, 3 );
You may be able to edit for your needs.
Hope that helps!
Thanks @jarvis for your help.
I am using Divi theme.
And yes I am talking about WooCommerce variations for a product.
But I guest the frontend of teh product page is linked to Woocommerce not Divi ?…

Hi @pat0726
I’m assuming you’re referring to the output of the field on the frontend?
When you mention variations form, is this WooCommerce or something else?
From what I can gather, you need to review your template where the code to output the ACF field is being displayed. Then locate the code for the variations form output and move your ACF code below.
Maybe say which theme you’re using, include screenshots. The more info here, the more people can help.

Hi @johndoea
To show the field, you would need to use something like:
<?php
$field_name = get_field('field_name');
if( $field_name ):
echo $field_name;
endif;
As for the position, you would need to locate the correct template in WooCommerce, usually, you then copy this to your theme and amend it OR use a WooCommerce hook to output the field.
Given what you’ve said about product tags, you should read this as it may help with where to place the code

I wonder if you need to use the woo product TAB callback.
So something like:
<?php
########################
# Add Custom Product Page TAB
########################
add_filter( 'woocommerce_product_tabs', 'acf_woo_new_product_tab' );
function acf_woo_new_product_tab( $tabs ) {
global $product;
$product_id = $product->get_id();
if( have_rows('details_repeater',$product_id ) ):
while( have_rows('details_repeater',$product_id ) ) : the_row();
if (get_sub_field('title') == 'Characteristics') :
// Adds the new tab
$tabs['product_details_tab'] = array(
'title' => __( 'Characteristics', 'woocommerce' ),
'priority' => 10,
'callback' => 'acf_product_details_tab_content'
);
endif;
endwhile;
endif;
return $tabs;
}
function acf_product_details_tab_content() {
global $product;
$product_id = $product->get_id();
// Check rows exists.
if( have_rows('details_repeater',$product_id ) ):
echo '<h2>Characteristics</h2>';
// Loop through rows.
while( have_rows('details_repeater',$product_id ) ) : the_row();
// Load sub field value.
$content = get_sub_field('content');
echo $content;
// End loop.
endwhile;
// No value.
else :
// Do something...
endif;
}
Code is untested but hopefully, you can see what’s happening.

Is it Woocommerce?
If so, I’ve had similar! I ended up creating ACF fields and as long as the field name matches (you may need to check the database), you should then be able to edit that info via the ACF field
No that didn’t work either. I’ll just use the CSS option for now. Like I said, PHP is new to me so it could be that I have implemented the code wrong. My entire code is:
// ACF SPECIFICATION FIELDS
add_action('woocommerce_short_description', 'speaker_specification_fields', 4 );
function speaker_specification_fields() { ?>
<ul>
<li><?php
$field = get_field_object('field_6155c03d20d5c');
?>
<?php echo $field['label']; ?>: <?php echo $field['value']; ?></li>
<li><?php
$field = get_field_object('field_61715110d855c');
?>
<?php echo $field['label']; ?>: <?php echo $field['value']; ?></li>
<li><?php
$field = get_field_object('field_6155bf1660b3c');
?>
<?php echo $field['label']; ?>: <?php echo $field['value']; ?></li>
<li><?php
$field = get_field_object('field_60d47fd0711ca');
?>
<?php echo $field['label']; ?>: <?php echo $field['value']; ?></li>
<li><?php
$field = get_field_object('field_60d47ffb711cb');
?>
<?php echo $field['label']; ?>: <?php echo $field['value']; ?></li>
<li><?php
$field = get_field_object('field_6155bed832b78');
?>
<?php echo $field['label']; ?>: <?php echo $field['value']; ?></li>
</ul>
<?php
if( is_product_category() ):
return $description;
else:
return $description.$text;
endif; ?>
<?php } ?>
Hi @jarvis thanks for this. Unfortunately it didn’t seem to work. However, (and this probably isn’t the best solution) I was able to hide it on the product overview page using this css:
/*-- HIDE HEADER PRODUCT OVERVIEW --*/
header.woocommerce-products-header {
display: none;
}
So for now it is hidden and appears correctly on the product page when in and out of stock.
Thanks.

Hmm, what if you add a conditional to the function:
<?php
add_filter('woocommerce_short_description','add_content_after_short_description');
function add_content_after_short_description($description){
$field = get_field_object('field_6155c03d20d5c');
$text = $field['label'].': '.$field['value'].'<br/>'; #first $text doesn't need a . before the =
$field = get_field_object('field_61712d2256ff2');
$text .= $field['label'].': '.$field['value'].'<br/>'; #note the . before the = as we wish to join/concate them
$field = get_field_object('field_6155bf1660b3c');
$text .= $field['label'].': '.$field['value'].'<br/>';
# etc.
if( is_product() ):
return $description.$text;
else:
return $description;
endif;
}
Does that work?

Hi @websteem
Looking at your video, it seems you’re using a child theme (Handmade Child Theme) but then update Handmade: functions.php not Handmade Child Theme: functions.php
So that could be the first issue.
Try adding the code there instead. If it still doesn’t work, switch to the default twenty-twentyone theme and add the below to functions.php:
add_action( 'woocommerce_after_main_content', 'my_extra_description' );
function my_extra_description() {
global $wp_query;
# get the query object
$category = $wp_query->get_queried_object();
#get the cat ID
$category_ID = $category->term_id;
echo '<p>Can we see this? Is '.$category_ID.' the right ID for this category?</p>'; #remove after debug
#get the field
$contenu_categorie = get_field( 'contenu_categorie', 'category_'.$category_ID );
#if we have data, show it
if( $contenu_categorie ){
echo $contenu_categorie;
}
}
At the very least, when you go to your shop category page, it should show ‘Can we see this? Is…’
Then perhaps you have an issue with your theme!

Just tried this and confirm it’s the hook you’re using.
If you switch to the below hook, you should see the message displayed whether an item is in or out of stock:
add_filter('woocommerce_short_description','add_content_after_short_description');
function add_content_after_short_description($description){
$text = "This will be displayed after the short des but before the add to basket";
return $description.$text;
}
So in theory, you can then start to add your fields back in:
add_filter('woocommerce_short_description','add_content_after_short_description');
function add_content_after_short_description($description){
#$text = "This will be displayed after the short des but before the add to basket"; #debug so remove
$field = get_field_object('field_6155c03d20d5c');
$text = $field['label'].': '.$field['value'].'<br/>'; #first $text doesn't need a . before the =
$field = get_field_object('field_61712d2256ff2');
$text .= $field['label'].': '.$field['value'].'<br/>'; #note the . before the = as we wish to join/concate them
$field = get_field_object('field_6155bf1660b3c');
$text .= $field['label'].': '.$field['value'].'<br/>';
# etc.
return $description.$text;
}
Not tested with the fields but definitely works with the correct hook!

I suspect it’s to do with the filter on your function ‘woocommerce_before_add_to_cart_form’
At a guess, if your product is out of stock, perhaps this isn’t triggered as the add to cart form won’t be displayed.
Could be wrong!
If you add the below to your function file, then check the message shows on both an instock and out of stock item:
function custom_woocommerce_before_add_to_cart_form(){
echo 'woocommerce_before_add_to_cart_form function is being called';
}
add_action('woocommerce_before_add_to_cart_form', 'custom_woocommerce_before_add_to_cart_form');
Worth trying to rule it out
Hi @kipmyk I was able to get the values to display with that command so thank you! it’s not pretty and I am sure there are better ways to do it but it works:
add_action('woocommerce_before_add_to_cart_form', 'speaker_specification_fields', 4 );
function speaker_specification_fields() { ?>
<?php
$field = get_field_object('field_6155c03d20d5c');
?>
<?php echo $field['label']; ?>: <?php echo $field['value']; ?>
<?php
$field = get_field_object('field_61712d2256ff2');
?>
<?php echo $field['label']; ?>: <?php echo $field['value']; ?>
<?php
$field = get_field_object('field_6155bf1660b3c');
?>
<?php echo $field['label']; ?>: <?php echo $field['value']; ?>
<?php
$field = get_field_object('field_60d47fd0711ca');
?>
<?php echo $field['label']; ?>: <?php echo $field['value']; ?>
<?php
$field = get_field_object('field_60d47ffb711cb');
?>
<?php echo $field['label']; ?>: <?php echo $field['value']; ?>
<?php
$field = get_field_object('field_6155bed832b78');
?>
<?php echo $field['label']; ?>: <?php echo $field['value'];
}
?>
I just call on every field individually.

@websteem that’s pretty much the same code I gave you!
Are you adding the code to your functions file?
You can add code to the archive-product.php template, it won’t be the code supplied though as you asked to use the woocommerce hooks.
If you want to add direct to the template, just use:
global $wp_query;
# get the query object
$category = $wp_query->get_queried_object();
#get the cat ID
$category_ID = $category->term_id;
echo '<p>Can we see this? Is '.$category_ID.' the right ID for this category?</p>'; #remove after debug
#get the field
$contenu_categorie = get_field( 'contenu_categorie', 'category_'.$category_ID );
#if we have data, show it
if( $contenu_categorie ){
echo $contenu_categorie;
}
Hello everybody
Here is the answer I received this morning (French time) of Said, from the official ACF support:
With the field’s Location rule set as Taxonomy is equal to product_cat, the field should appear on your individual product category edit page. With the code below added in functions.php, the field value displays just fine on the individual category archive in the frontend as shown in this recording: https://www.awesomescreenshot.com/video/5711245?key=aa4a06a3a6ab345566493738b7aad9d5
add_action( ‘woocommerce_after_main_content’, ‘extra_description’ );
function extra_description() {
global $wp_query;
$product_cat = $wp_query->get_queried_object();
$cat_ID = $product_cat->term_id;
$extra_info = get_field( ‘product_extra’, ‘category_’ . $cat_ID );
if( $extra_info ){
echo $extra_info;
}
}
So i will try it out and let you know how it goes.
Still nothing…
The code is there, but nothing is displayed under the products grid (https://fleursdemontagne.com/categorie-cbd/huile-cbd/ for example)
I thought that some code should be integrated in the archive-product.php (https://woocommerce.github.io/code-reference/files/woocommerce-templates-archive-product.html). Wrong track?

Hi @websteem
Odd, if you use the below, what do you see?
add_action( 'woocommerce_after_main_content', 'my_extra_description' );
function my_extra_description() {
global $wp_query;
# get the query object
$category = $wp_query->get_queried_object();
#get the cat ID
$category_ID = $category->term_id;
echo '<p>Can we see this? Is '.$category_ID.' the right ID for this category?</p>'; #remove after debug
#get the field
$contenu_categorie = get_field( 'contenu_categorie', 'category_'.$category_ID );
#if we have data, show it
if( $contenu_categorie ){
echo $contenu_categorie;
}
}
I’ve just tested the above with your field name on the twenty-twentyone theme and worked

As a quick after thought, you *may* need to access the product ID to get the data from the field, if so, try:
add_action( 'woocommerce_before_add_to_cart_form', 'my_pdf_field' );
function my_pdf_field() {
global $product;
$product_id = $product->get_id();
$pdf = get_field( 'pdf', $product_id );
#if we have data, show it
if( $pdf ){
echo '<a href="'.$pdf['url'].'">link</a>';
}
}

Hi @danis44
You can try something like:
add_action( 'woocommerce_before_add_to_cart_form', 'my_pdf_field' );
function my_pdf_field() {
$pdf = get_field( 'pdf' );
#if we have data, show it
if( $pdf ){
echo '<a href="'.$pdf['url'].'">link</a>';
}
}
I’ve assumed the PDF field you’ve added is called pdf, it’s a file type and returns an array (not a URL)
Code is untested and goes in your functions.php file

Does something like the below work:
add_action( 'woocommerce_after_main_content', 'my_extra_description' );
function my_extra_description() {
global $wp_query;
# get the query object
$category = $wp_query->get_queried_object();
#get the cat ID
$category_ID = $category->term_id;
#get the field
$extra_description = get_field( 'extra_description', 'category_'.$category_ID );
#if we have data, show it
if( $extra_description ){
echo $extra_description;
}
}
Code untested and goes in your functions file
Hello everybody
I had the same question. Do I have to add this code into the woocommerce/archive-product.php file? If so, between which lines?
Thank you for your help.

The have rows loop must be inside of the product post loop
if ( wc_get_loop_prop( 'total' ) ) {
while ( have_posts() ) {
the_post();
/**
* Hook: woocommerce_shop_loop.
*/
do_action( 'woocommerce_shop_loop' );
wc_get_template_part( 'content', 'product' );
}
}
or in the template part loaded by this
wc_get_template_part( 'content', 'product' );

Can you provide more info?
How is the data being added to the contents being added to lc_photos_list in the first instance?
If you then add info to lc_registration, does it matter what the post ID will be?
Based on your code, something like:
add_action( 'woocommerce_payment_complete_order_status_completed', 'lc_complete_for_status' );
function lc_complete_for_status( $order_id ){
if( have_rows('lc_photos_list', 579) ):
while( have_rows('lc_photos_list', 579) ) : the_row();
$sub_value = get_sub_field('sub_field');
$post_id = 576;
$row = array(
'field_61645b916cbd7' => $sub_value #this is your repeater field key
);
$i = add_row('field_61645b866cbd6', $row, $post_id); #this is the key for the main repeater
endwhile;
endif;
#update_field("lc_photos_list", $copyPhotosObject, 576);
}
I don’t know the repeater field info or how you get the post IDs (579/576)
Should hopefully get you underway.
Code is untested!

You need to loop the product data and add it to the repeater. Something like:
<?php
function create_post_after_order( $order_id ) {
if ($order_id instanceof WC_Order ){
return;
}
$order = wc_get_order( $order_id );
$order_items = $order->get_items();
$products = array();
foreach ( $order_items as $item_id => $item_data ) {
$product = $item_data->get_product();
$qty .= $item_data->get_quantity();
$name .= $product->get_name();
$products[] = array(
'product' => $product,
'qty' => $qty
);
}
$new_post = array(
'post_title' => "Order {$order_id}",
'post_content' => $content,
'post_status' => 'private',
'post_date' => date('Y-m-d H:i:s'),
'post_author' => $user_ID,
'post_type' => 'groeiproces',
'post_status' => 'publish',
);
$post_id = wp_insert_post($new_post);
/*
$class_field_key = 'field_61645b866cbd6';
$class_subfield_name = 'field_61645b916cbd7';
$class_subfield_colour = 'field_6165450699ffa';
$class_names = array($name,$name);
$class_colours = array($qty,$qty);
foreach ($class_names as $index => $class_names) {
$class_value[] = array($class_subfield_name => $class_names, $class_subfield_colour => $class_colours[$index]);
update_field( $class_field_key, $class_value, $post_id );
}
*/
echo '<pre>';
print_r($products); #check the data in the array.
echo '</pre>';
if( $products ):
foreach( $products as $product ):
$row = array(
'field_61645b916cbd7' => $product[0], #product field key
'field_6165450699ffa' => $product[1], #qty field key
);
$i = add_row('field_61645b866cbd6', $row, $post_id); #this is the key for the main repeater
endforeach;
endif;
}
add_action( 'woocommerce_thankyou', 'create_post_after_order', 10, 1 );
You need to check/change the key values. The code is also untested but hopefully will get you on the right lines.
Basically, add the product data to a new array. Then loop that data into your repeater.
Thanks John, I was able to upgrade my code using an array eventually.
function create_post_after_order( $order_id ) {
if ( $order_id instanceof WC_Order ){
return;
}
$order = wc_get_order( $order_id );
$order_items = $order->get_items();
foreach ( $order_items as $item_id => $item_data ) {
$product = $item_data->get_product();
$qty.= $item_data->get_quantity();
$name.= $product->get_name();
}
$new_post = array(
'post_title' => "Order {$order_id}",
'post_content' => $content,
'post_status' => 'private',
'post_date' => date('Y-m-d H:i:s'),
'post_author' => $user_ID,
'post_type' => 'groeiproces',
'post_status' => 'publish',
);
$post_id = wp_insert_post($new_post);
// repeater field with multiple subfields
$class_field_key = 'field_61645b866cbd6';
$class_subfield_name = 'field_61645b916cbd7';
$class_subfield_colour = 'field_6165450699ffa';
$class_names = array($name,$name);
$class_colours = array($qty,$qty);
foreach ($class_names as $index => $class_names) {
$class_value[] = array($class_subfield_name => $class_names, $class_subfield_colour => $class_colours[$index]);
update_field( $class_field_key, $class_value, $post_id );
}
}
add_action( 'woocommerce_thankyou', 'create_post_after_order', 10, 1 );
Right now the only problem is that this combines the values in one field. e.g.
Name
Product1Product2
Quantity
11
Does anyone know how to split those values and save them separated. e.g.
Product1 1
Product2 1
Thanks in advance!
Welcome to the Advanced Custom Fields community forum.
Browse through ideas, snippets of code, questions and answers between fellow ACF users
Helping others is a great way to earn karma, gain badges and help ACF development!
We use cookies to offer you a better browsing experience, analyze site traffic and personalize content. Read about how we use cookies and how you can control them in our Privacy Policy. If you continue to use this site, you consent to our use of cookies.