I need to add custom text element after the add to cart button in WooCommerce.
I try with this code, that I insert in functions.php
add_action( 'woocommerce_after_add_to_cart_button', 'inserisce_testo_dopobottone' );
function inserisce_testo_dopobottone() {
echo '<div class="second_content">New text</div>';
}
That's works, but now i need that text is customizable for every page.
Is that possible?
You can add a custom field via the woocommerce_product_options_general_product_data action hook which will add a new field to the general tab of product data metabox
Based on this, you can show a different message per product, or a default message
So you get:
// Add to general_product_data tab
function action_woocommerce_product_options_general_product_data() {
// Text field
woocommerce_wp_text_input( array(
'id' => '_my_custom_text',
'label' => __( 'My custom text', 'woocommerce' ),
'placeholder' => '',
'description' => __( 'Add your custom text', 'woocommerce' ),
'desc_tip' => true,
));
}
add_action( 'woocommerce_product_options_general_product_data', 'action_woocommerce_product_options_general_product_data', 10, 0 );
// Save custom field
function action_woocommerce_admin_process_product_object( $product ) {
// Isset
if ( isset( $_POST['_my_custom_text'] ) ) {
// Update
$product->update_meta_data( '_my_custom_text', sanitize_text_field( $_POST['_my_custom_text'] ) );
}
}
add_action( 'woocommerce_admin_process_product_object', 'action_woocommerce_admin_process_product_object', 10, 1 );
// Display after add to cart button
function action_woocommerce_after_add_to_cart_button() {
global $product;
// Is a WC product
if ( is_a( $product, 'WC_Product' ) ) {
// Get meta
$message = $product->get_meta( '_my_custom_text' );
// When Empty, use default message
if ( empty ( $message ) ) {
$message = __( 'Default text', 'woocommerce' );
}
echo '<div class="second_content">' . $message . '</div>';
}
}
add_action( 'woocommerce_after_add_to_cart_button', 'action_woocommerce_after_add_to_cart_button' );
Related
I recently created a custom field in functions.php to display a custom meta field in the Inventory tab for each product called barcode. What I now want to do is display the data onto my single product template using a PHP call. Here's first of all, the function to create the barcode data (which works):
function add_barcode(){
woocommerce_wp_text_input(
array(
'id' => '_barcode',
'label' => __( 'Barcode', 'your-plugin' ),
'placeholder' => 'Scan Barcode',
'desc_tip' => 'true',
'description' => __( "Scan the product's barcode.", "your-plugin" )
)
);
}
add_action('woocommerce_product_options_inventory_product_data','add_barcode');
function add_barcode_save( $product ){
if( isset( $_POST['_barcode'] ) ) {
$product->update_meta_data( '_barcode', sanitize_text_field( $_POST['_barcode'] ) );
} else {
$product->delete_meta_data( '_barcode' );
}
}
add_action( 'woocommerce_admin_process_product_object', 'add_barcode_save' );
Here's the PHP I'm trying to generate that data onto the page:
$product = wc_get_product();
echo '<strong>Barcode: </strong>' .$product->get_attribute( 'barcode' );
All I get here is a blank area after the HTML portion. So what function will allow me to display the barcode text?
Using the Remi Coulson tutorial, a custom field has been added for product variations.
This works, however the custom field is positioned by the add-to-cart button. I wish to position it within Additional Information tab. I have tried adding the front end code to the additional-information.php but it does not display.
<div class="woocommerce-variation-custom-text-field">
{{{ data.variation.text_field }}}
</div>
Added to functions.php to display variation
// Add Variation Settings
add_action( 'woocommerce_product_after_variable_attributes', 'variation_settings_fields', 10, 3 );
// Save Variation Settings
add_action( 'woocommerce_save_product_variation', 'save_variation_settings_fields', 10, 2 );
/**
* Create new fields for variations
*
*/
function variation_settings_fields( $loop, $variation_data, $variation ) {
// Text Field
woocommerce_wp_text_input(
array(
'id' => '_text_field[' . $variation->ID . ']',
'label' => __( 'My Text Field', 'woocommerce' ),
'placeholder' => 'http://',
'desc_tip' => 'true',
'description' => __( 'Enter the custom value here.', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_text_field', true )
)
);
}
/**
* Save new fields for variations
*
*/
function save_variation_settings_fields( $post_id ) {
// Text Field
$text_field = $_POST['_text_field'][ $post_id ];
if( ! empty( $text_field ) ) {
update_post_meta( $post_id, '_text_field', esc_attr( $text_field ) );
}
}
<?php
// Add New Variation Settings
add_filter( 'woocommerce_available_variation', 'load_variation_settings_fields' );
/**
* Add custom fields for variations
*
*/
function load_variation_settings_fields( $variations ) {
// duplicate the line for each field
$variations['text_field'] = get_post_meta( $variations[ 'variation_id' ], '_text_field', true );
return $variations;
}
Note that your code is a bit outdated since WooCommerce 3.
jQuery and some other changes are required to display the selected variation custom field value anywhere in a specific location on single product pages, specially outside the variation form.
In the example below the selected variation custom field value will be displayed on "Additional information" product tab after product attributes table.
Here is the complete revisited code:
// Add a custom field to variation settings
add_action( 'woocommerce_product_after_variable_attributes', 'variation_settings_fields', 10, 3 );
function variation_settings_fields( $loop, $variation_data, $variation ) {
woocommerce_wp_text_input( array(
'id' => '_text_field[' . $loop . ']',
'label' => __( 'My Text Field', 'woocommerce' ),
'placeholder' => 'http://',
'desc_tip' => 'true',
'description' => __( 'Enter the custom value here.', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_text_field', true ),
) );
}
// Save custom field value from variation settings
add_action( 'woocommerce_admin_process_variation_object', 'save_variation_settings_fields', 10, 2 );
function save_variation_settings_fields( $variation, $loop ) {
if( isset($_POST['_text_field'][$loop]) ) {
$variation->update_meta_data( '_text_field', sanitize_text_field($_POST['_text_field'][$loop]) );
}
}
// Add variation custom field to single variable product form
add_filter( 'woocommerce_available_variation', 'add_variation_custom_field_to_variable_form', 10, 3 );
function add_variation_custom_field_to_variable_form( $variation_data, $product, $variation ) {
$variation_data['text_field'] = $variation->get_meta('_text_field');
return $variation_data;
}
add_action( 'woocommerce_product_additional_information', 'add_html_container_to_display_selected_variation_custom_field' );
function add_html_container_to_display_selected_variation_custom_field( $product ){
echo '<div class="custom_variation-text-field"></div>';
}
// Display selected variation custom field value to product the tab
add_action( 'woocommerce_after_variations_form', 'display_selected_variation_custom_field_js' );
function display_selected_variation_custom_field_js(){
?>
<script type="text/javascript">
(function($){
$('form.cart').on('show_variation', function(event, data) {
$('.custom_variation-text-field').text(data.text_field);
}).on('hide_variation', function(event) {
$('.custom_variation-text-field').text('');
});
})(jQuery);
</script>
<?php
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
Im looking to find some php code that will allow me to extract information (Name, address etc) from the checkout fields and add it to the order meta data.
Looking for this to be a simple as possible
Ive previously found this code which allows a custom box to be added to the checkout page, and I sort of understand how it works, however I want to capture their name when they type it into the billing first name box. I can seem to grasp how to capture this data and put it into the order meta data, Ive tried shortening the code and editing it a few times but I dont seem to be winning
// Our hooked in function - $fields is passed via the filter!
function custom_override_checkout_fields( $fields ) {
$fields['shipping']['shipping_phone'] = array(
'label' => __('Phone', 'woocommerce'),
'placeholder' => _x('Phone', 'placeholder', 'woocommerce'),
'required' => false,
'class' => array('form-row-wide'),
'clear' => true
);
return $fields;
}
/**
* Display field value on the order edit page
*/
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('Phone From Checkout Form').':</strong> ' . get_post_meta( $order->get_id(), '_shipping_phone', true ) . '</p>';
}
/**
* Add the field to the checkout
*/
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );
function my_custom_checkout_field( $checkout ) {
echo '<div id="my_custom_checkout_field"><h2>' . __('My Field') . '</h2>';
woocommerce_form_field( 'my_field_name', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('Fill in this field'),
'placeholder' => __('Enter something'),
), $checkout->get_value( 'my_field_name' ));
echo '</div>';
}
/**
* Process the checkout
*/
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');
function my_custom_checkout_field_process() {
// Check if set, if its not set add an error.
if ( ! $_POST['my_field_name'] )
wc_add_notice( __( 'Please enter something into this new shiny field.' ), 'error' );
}
/**
* Update the order meta with field value
*/
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta' );
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['my_field_name'] ) ) {
update_post_meta( $order_id, 'My Field', sanitize_text_field( $_POST['my_field_name'] ) );
}
}
I like this and it does work but just not in the way i need it to work. thanks for any and all help
There are some mistakes and missing things in your code… Try the following replacement code instead:
// Add shipping phone (in checkout and My account edit shipping address) and save field value
add_action( 'woocommerce_shipping_fields', 'add_shipping_phone_field' );
function add_shipping_phone_field( $fields ) {
$fields['shipping_phone'] = array(
'label' => __('Phone', 'woocommerce'),
'placeholder' => _x('Phone', 'placeholder', 'woocommerce'),
'required' => false,
'class' => array('form-row-wide'),
'clear' => true
);
return $fields;
}
// Display shipping phone value on the order edit pages under shipping section
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'display_shipping_phone_in_admin_orders' );
function display_shipping_phone_in_admin_orders( $order ){
$phone_value = $order->get_meta('_shipping_phone');
if ( ! empty($phone_value) ) {
echo '<p><strong>'.__('Shipping phone').':</strong> ' . $phone_value . '</p>';
}
}
// Add a custom checkout field
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );
function my_custom_checkout_field( $checkout ) {
echo '<div id="my_custom_checkout_field"><h2>' . __('My Field') . '</h2>';
woocommerce_form_field( 'my_field_slug', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('My custom field'),
'placeholder' => __('Enter something… '),
'required' => true,
), $checkout->get_value( 'my_field_slug' ) );
echo '</div>';
}
// Validate required checkout fields
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');
function my_custom_checkout_field_process() {
// Check if set, if its not set add an error.
if ( isset($_POST['my_field_slug']) && empty($_POST['my_field_slug']) ) {
wc_add_notice( __( '"My custom field" is a required field.' ), 'error' );
}
}
// Add custom checkout field value as custom order meta data
add_action( 'woocommerce_checkout_create_order', 'my_custom_checkout_field_update_order_meta' );
function my_custom_checkout_field_update_order_meta( $order ) {
if ( isset($_POST['my_field_slug']) && ! empty($_POST['my_field_slug']) ) {
$order->update_meta_data( 'My Field', sanitize_text_field( $_POST['my_field_slug'] ) );
}
}
// Display "My field" value on the order edit pages under billing section
add_action( 'woocommerce_admin_order_data_after_billing_address', 'display_my_custom_checkout_field_in_admin_orders', 10, 1 );
function display_my_custom_checkout_field_in_admin_orders($order){
$my_field_value = $order->get_meta('My Field');
if ( ! empty($my_field_value) ) {
echo '<p><strong>'.__('My field').':</strong> ' . $my_field_value . '</p>';
}
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
Now If you need to extract some data from Woocommerce existing checkout fields and combine it in a custom way to save it as custom order meta data, try to be more explicit:
What fields?
How you want to combine it?
What is the custom field slug to be used to save that data combination?
We managed to put a custom field for variation products following Remi Corson guide here
At this point, we are able to show the custom text field in the single product page when users select the variation, but this is not enough in the purchase process since we need to:
A) Display this text in Cart and Checkout
B) Save this information so it shows in Thank You Page, Emails and Admin Order Edit Page
Something similar to Save and display product custom meta on WooCommerce orders and emails, but with product variations instead of simple products.
This is the code we added to our functions.php to add the custom field to the product variations
// Add Variation Settings
add_action( 'woocommerce_product_after_variable_attributes', 'variation_settings_fields', 10, 3 );
// Save Variation Settings
add_action( 'woocommerce_save_product_variation', 'save_variation_settings_fields', 10, 2 );
/**
* Create new fields for variations
*
*/
function variation_settings_fields( $loop, $variation_data, $variation ) {
// Text Field
woocommerce_wp_text_input(
array(
'id' => '_text_field[' . $variation->ID . ']',
'label' => __( 'My Text Field', 'woocommerce' ),
'placeholder' => 'http://',
'desc_tip' => 'true',
'description' => __( 'Enter the custom value here.', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_text_field', true )
)
);
// Hidden field
woocommerce_wp_hidden_input(
array(
'id' => '_hidden_field[' . $variation->ID . ']',
'value' => 'hidden_value'
)
);
}
/**
* Save new fields for variations
*
*/
function save_variation_settings_fields( $post_id ) {
// Text Field
$text_field = $_POST['_text_field'][ $post_id ];
if( ! empty( $text_field ) ) {
update_post_meta( $post_id, '_text_field', esc_attr( $text_field ) );
}
// Hidden field
$hidden = $_POST['_hidden_field'][ $post_id ];
if( ! empty( $hidden ) ) {
update_post_meta( $post_id, '_hidden_field', esc_attr( $hidden ) );
}
}
// Add New Variation Settings
add_filter( 'woocommerce_available_variation', 'load_variation_settings_fields' );
/**
* Add custom fields for variations
*
*/
function load_variation_settings_fields( $variations ) {
// duplicate the line for each field
$variations['text_field'] = get_post_meta( $variations[ 'variation_id' ], '_text_field', true );
return $variations;
}
So the goal here is how can we show this custom field for each variation in the Cart and Checkout below the items (Something like the image below - Look at the Shipping delay notice)
And to save that custom field info that each variation has to the Thank You Page, Emails and Order Page (We did it for simple products with this code, but this doesn't work for variable ones)
// Save and display "Custom Field for Simple Products" on order items everywhere
add_filter( 'woocommerce_checkout_create_order_line_item', 'action_wc_checkout_create_order_line_item', 10, 4 );
function action_wc_checkout_create_order_line_item( $item, $cart_item_key, $values, $order ) {
// Get the Custom Field
$value = $values['data']->get_meta( 'custom_field_for_simple_products' );
if( ! empty( $value ) ) {
// Save it and display it
$item->update_meta_data( __( 'Custom Fields', 'woocommerce' ), $value );
}
}
Please help!!
Updated
There are some mistakes in your code… The following revisited code will solve your issue:
// Display Variation custom fields (admin)
add_action( 'woocommerce_product_after_variable_attributes', 'display_variation_setting_custom_fields', 10, 3 );
function display_variation_setting_custom_fields( $loop, $variation_data, $variation ) {
echo '<div>';
woocommerce_wp_text_input( array( // Text Field
'id' => "_text_field[$loop]",
'label' => __("My Text Field", "woocommerce"),
'placeholder' => "http://",
'desc_tip' => true,
'description' => __("Enter the custom value here.", "woocommerce"),
'wrapper_class' => 'form-row form-row-full',
'value' => get_post_meta( $variation->ID, '_text_field', true ),
) );
woocommerce_wp_hidden_input( array( // Hidden field
'id' => "_hidden_field[$loop]",
'value' => 'hidden_value',
) );
echo '</div>';
}
// Save Variation custom fields
add_action( 'woocommerce_save_product_variation', 'save_variation_custom_fields', 10, 2 );
function save_variation_custom_fields( $variation_id, $i ) {
// Save Text Field
if( isset( $_POST['_text_field'][$i] ) && ! empty( $_POST['_text_field'][$i] ) )
update_post_meta( $variation_id, '_text_field', sanitize_text_field( $_POST['_text_field'][$i] ) );
// Save Hidden Field
if( isset( $_POST['_hidden_field'][$i] ) && ! empty( $_POST['_hidden_field'][$i] ) )
update_post_meta( $variation_id, '_hidden_field', esc_attr( $_POST['_hidden_field'][$i] ) );
}
// Include our variation custom field
add_filter( 'woocommerce_available_variation', 'include_variation_custom_field', 10, 3) ;
function include_variation_custom_field( $data, $product, $variation ) {
$data['text_field'] = $variation->get_meta( '_text_field' );
return $data;
}
// Save and display "Custom Field for Simple Products" on order items everywhere
add_filter( 'woocommerce_checkout_create_order_line_item', 'action_wc_checkout_create_order_line_item_2', 10, 4 );
function action_wc_checkout_create_order_line_item_2( $item, $cart_item_key, $values, $order ) {
// Get the Custom Field
$value = $values['data']->get_meta( '_text_field' );
if( ! empty( $value ) ) {
// Save it and display it
$item->update_meta_data( __( 'Custom Field', 'woocommerce' ), $value );
}
}
Code goes in functions.php file of your active child theme (or active theme) . Tested and works.
Related: Save and display product custom meta on WooCommerce orders and emails
Somme screenshots
On admin product variations settings:
On order received page (thankyou):
On admin edit orders pages:
I have one issue that dont know how to resolve myself, so need your help. I have inserted Custom Field into my WooCommerce site product page. I have used this code to show my custom field bellow "Add to Cart" page, and also bellow product into cart page.
// Display Product settings Fields
add_action( 'woocommerce_product_options_general_product_data',
'woo_add_custom_general_fields' );
function woo_add_custom_general_fields() {
woocommerce_wp_text_input( array(
'id' => '_pd_number',
'label' => __( 'Delivery Time', 'woocommerce' ),
'placeholder' => 'Some text here',
'desc_tip' => 'true',
'description' => __( 'Enter some text', 'woocommerce' )
));
}
// Save Product settings Fields
add_action( 'woocommerce_process_product_meta',
'woo_add_custom_general_fields_save' );
function woo_add_custom_general_fields_save( $post_id ){
$pd_number = $_POST['_pd_number'];
if( !empty( $pd_number ) )
update_post_meta( $post_id, '_pd_number', esc_attr( $pd_number ) );
}
// Show text in Product Page
add_action( 'woocommerce_after_add_to_cart_button',
'add_cf_before_addtocart_in_single_products', 1, 0 );
function add_cf_before_addtocart_in_single_products()
{
global $product;
$pd_number = get_post_meta( $product->get_id(), '_pd_number', true );
if( !empty( $pd_number ) )
echo '<div class="pd-number">'. $pd_number .'</div><br>';
}
// Displaying the product custom field in the Cart items
add_filter( 'woocommerce_cart_item_name', 'add_cf_after_cart_item_name', 10,
3 );
function add_cf_after_cart_item_name( $name_html, $cart_item, $cart_item_key
)
{
$product_id = $cart_item['product_id'];
if( $cart_item['variation_id'] > 0 )
$product_id = $cart_item['variation_id'];
$pd_number = get_post_meta( $product_id, '_pd_number', true );;
if( !empty( $pd_number ) )
$name_html .= '<br><span class="pd-number">'.$pd_number .'</span>';
return $name_html;
}
but show only on my default site language Dansk. If choise English from top bar, custom field is not shown. I use WPML as language plugin. Any help ?
In this image, if you put the blank custom field in other languages then it does not appear in front end