In WooCommerce, I would like to add custom global product tab just like additional info when a new product is created.
I am able to create new tab but cannot update anything on create new product page.
I can see it on display page but how to add info through product edit page. I know I can use custom fields but I am looking to have it on product page to allow shop manager or others to fill this additional shipping tab.
My Code is
add_filter( 'woocommerce_product_tabs', 'woo_new_product_tab' );
function woo_new_product_tab( $tabs ) {
// Adds the new tab
$tabs['test_tab'] = array(
'title' => __( 'Shipping', 'woocommerce' ),
'priority' => 50,
'callback' => 'woo_new_product_tab_content'
);
return $tabs;
}
function woo_new_product_tab_content() {
// The new tab content
$prod_id = get_the_ID();
echo'<p>'.get_post_meta($prod_id,'Shipping',true).'</p>';
}
You can add a custom Metabox in Admin Product pages that will allow Shop Managers to add content for your custom product tab. You will get this:
Here is the code:
// Adding a custom Meta container to admin products pages
add_action( 'add_meta_boxes', 'create_custom_meta_box' );
if ( ! function_exists( 'create_custom_meta_box' ) )
{
function create_custom_meta_box()
{
add_meta_box(
'custom_product_shipping_field',
__( 'Custom Shipping Tab information', 'woocommerce' ),
'add_custom_content_meta_box',
'product',
'normal',
'high'
);
}
}
// Custom metabox content in admin product pages
if ( ! function_exists( 'add_custom_content_meta_box' ) )
{
function add_custom_content_meta_box( $post )
{
$value = get_post_meta( $post->ID, '_shipping_tab', true ) ? get_post_meta( $post->ID, '_shipping_tab', true ) : '';
wp_editor( $value, 'custom_shipping_tab', array( 'editor_height' => 100 ) );
echo '<input type="hidden" name="custom_product_field_nonce" value="' . wp_create_nonce() . '">';
}
}
//Save the data of the Meta field
add_action( 'save_post', 'save_custom_content_meta_box', 10, 1 );
if ( ! function_exists( 'save_custom_content_meta_box' ) )
{
function save_custom_content_meta_box( $post_id ) {
// We need to verify this with the proper authorization (security stuff).
// Check if our nonce is set.
if ( ! isset( $_POST[ 'custom_product_field_nonce' ] ) ) {
return $post_id;
}
$nonce = $_REQUEST[ 'custom_product_field_nonce' ];
//Verify that the nonce is valid.
if ( ! wp_verify_nonce( $nonce ) ) {
return $post_id;
}
// If this is an autosave, our form has not been submitted, so we don't want to do anything.
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return $post_id;
}
// Check the user's permissions.
if ( 'page' == $_POST[ 'post_type' ] ) {
if ( ! current_user_can( 'edit_page', $post_id ) ) {
return $post_id;
}
} else {
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return $post_id;
}
}
// --- Its safe for us to save the data ! --- //
// Sanitize user input and update the meta field in the database.
update_post_meta( $post_id, '_shipping_tab', wp_kses_post($_POST[ 'custom_shipping_tab' ]) );
}
}
Then your own code will be:
// Add product custom "Shipping" tab
add_filter( 'woocommerce_product_tabs', 'woo_new_product_tab' );
function woo_new_product_tab( $tabs ) {
$tabs['test_tab'] = array(
'title' => __( 'Shipping', 'woocommerce' ),
'priority' => 50,
'callback' => 'shipping_product_tab_content'
);
return $tabs;
}
// The Shipping tab content
function shipping_product_tab_content() {
// The new tab content
$prod_id = get_the_ID();
echo'<div><p>'.get_post_meta( get_the_ID(), '_shipping_tab' ,true ).'</p></div>';
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Tested and works.
Related
I use code that displays custom WooCommerce product tabs. This code is based on "Custom metabox content displayed in single product additional tabs on Woocommerce"
// Add a custom metabox
add_action( 'add_meta_boxes', 'additional_product_tabs_metabox' );
function additional_product_tabs_metabox()
{
add_meta_box(
'add_product_metabox_additional_tabs',
__( 'Specifications Product Tabs', 'woocommerce' ),
'additional_product_tabs_metabox_content',
'product',
'normal'
);
}
// Add custom metabox content
function additional_product_tabs_metabox_content( $post )
{
// Technical Specification
echo '<h4>' . __( 'Technical Specification', 'woocommerce' ) . '</h4>';
$value = get_post_meta( $post->ID, '_technical_specification', true );
wp_editor( $value, '_technical_specification', array( 'editor_height' => 150 ) );
// Nonce field (for security)
echo '<input type="hidden" name="additional_product_tabs_nonce" value="' . wp_create_nonce() . '">';
}
// Save product data
add_action( 'save_post_product', 'save_additional_product_tabs', 10, 1 );
function save_additional_product_tabs( $post_id ) {
// Security check
if ( ! isset( $_POST[ 'additional_product_tabs_nonce' ] ) ) {
return $post_id;
}
//Verify that the nonce is valid.
if ( ! wp_verify_nonce( $_POST[ 'additional_product_tabs_nonce' ] ) ) {
return $post_id;
}
// If this is an autosave, our form has not been submitted, so we don't want to do anything.
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return $post_id;
}
if ( ! current_user_can( 'edit_product', $post_id ) ) {
return $post_id;
}
// Sanitize user input and save the post meta fields values.
if( isset($_POST[ '_technical_specification' ]) )
update_post_meta( $post_id, '_technical_specification', wp_kses_post($_POST[ '_technical_specification' ]) );
}
add_filter( 'woocommerce_product_tabs', 'woo_custom_product_tabs' );
function woo_custom_product_tabs( $tabs ) {
global $product;
// Technical Specification Tab
if ( ! empty($product) ) {
$tabs['technical_specification_tab'] = array(
'title' => __( 'Technical Specification', 'woocommerce' ),
'priority' => 60,
'callback' => 'woo_technical_specification_tab_content'
);
}
return $tabs;
}
function woo_technical_specification_tab_content() {
global $product;
echo'<p class="specification-text">'. $product->get_meta( '_technical_specification' ) . '</p>';
}
add_action('wp_footer', 'woo_activate_pdf_script');
function woo_activate_pdf_script(){
?>
<script>
var i, links = document.getElementsByTagName('a');
for(i=0; i<links.length; i++) {
if (links[i].href.match(/.pdf/ig)) links[i].className = 'pdf-icon';
}
</script>
<?php
}
Can you also check this code to see if it is correct? Tab visibility doesn't work here if there's no content in it.
And the speed of saving the product page when editing has increased.
I would be glad to have your help!
Try This
There is most likely a better way of doing this, but I've achieved this in the past with the following
if( get_field('directions') )
{
echo the_field('directions');
}
else
{
echo "<style>.direction_tab_tab { display:none !important; }</style>";
}
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
I've a problem with adding a new field in WooCommerce, before short description.
I used script in functions.php and my new custom field is displayed correctly but:
Short description disappear when use script, a new field is display fine.
I can edit the content of a field on a product page, but I can't delete it. It is always the last value.
How can I display this custom field without removing the product short description?
How can I reset this custom field content?
Here is my code:
// Add a custom Field
add_action( 'woocommerce_product_options_general_product_data', 'woo_add_custom_general_fields' );
function woo_add_custom_general_fields() {
global $woocommerce, $post;
woocommerce_wp_text_input(
array(
'id' => '_text_field',
'label' => __( 'Termin dostawy', 'woocommerce' ),
'placeholder' => 'np: 7 dni',
'desc_tip' => 'true',
'description' => __( 'Wpisz przewidywany termin dostawy, np: 7 dni.', 'woocommerce' )
)
);
}
// Save the custom field
add_action( 'woocommerce_process_product_meta', 'woo_add_custom_general_fields_save' );
function woo_add_custom_general_fields_save( $post_id ){
$woocommerce_text_field = $_POST['_text_field'];
if( ! empty( $woocommerce_text_field ) )
update_post_meta( $post_id, '_text_field', esc_attr( $woocommerce_text_field ) );
}
// Display the custom field
add_action('woocommerce_short_description', 'magik_custom_text', 10, 1);
function magik_custom_text()
{
global $product;
global $woocommerce, $post;
echo "Termin dostawy: ".get_post_meta( $post->ID, '_text_field', true );
}
Function responsible for display:
add_action('woocommerce_short_description', 'magik_custom_text', 10, 1);
function magik_custom_text()
{
Update 2:
1) You should add it to short description instead of replacing it…
The correct way is to hook your custom function in woocommerce_single_product_summary cation hook before the short description (using a priority between 11 to 19):
add_action('woocommerce_single_product_summary', 'magik_custom_text', 18);
function magik_custom_text()
{
global $post;
$field_value = get_post_meta( $post->ID, '_text_field', true );
// Displaying the custom field only when is set with a value
if( ! empty( $field_value ) )
echo '<p>' . __('Termin dostawy: ', 'woocommerce') . $field_value . '</p>';
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Tested and works. So you will get this:
2) To be able to delete the content of your product custom field you need to replace:
if( ! empty( $woocommerce_text_field ) )
by:
if( isset( $woocommerce_text_field ) )
in this hooked function:
add_action( 'woocommerce_process_product_meta', 'woo_add_custom_general_fields_save' );
function woo_add_custom_general_fields_save( $post_id ){
$woocommerce_text_field = $_POST['_text_field'];
if( isset( $woocommerce_text_field ) )
update_post_meta( $post_id, '_text_field', esc_attr( $woocommerce_text_field ) );
}
I'm using Wordpress together with WooCommerce for my shop.
I want to output the value of my custom field in my cart and in the email order confirmation.
I have created a custom field in my functions.php:
// Display Fields
add_action( 'woocommerce_product_options_general_product_data', 'woo_add_custom_general_fields' );
// Save Fields
add_action( 'woocommerce_process_product_meta', 'woo_add_custom_general_fields_save' );
function woo_add_custom_general_fields() {
global $woocommerce, $post;
echo '<div class="options_group">';
// Input
woocommerce_wp_text_input(
array(
'id' => '_gram',
'label' => __( 'somelabel', 'woocommerce' ),
'placeholder' => '',
'description' => __( 'sometext', 'woocommerce' ),
'type' => 'number',
'custom_attributes' => array(
'step' => 'any',
'min' => '0'
)
)
);
echo '</div>';
}
function woo_add_custom_general_fields_save( $post_id ){
// Number Field
$woocommerce_number_field = $_POST['_gram'];
if( !empty( $woocommerce_number_field ) )
update_post_meta( $post_id, '_gram', esc_attr( $woocommerce_number_field ) );
}
On my pages I'm using:
get_post_meta( get_the_ID(), '_gram', true );
To show the value and that work perfect.
Now I want to show this same value under the product name in my cart and in the email confirmations.
But I cant figure out how to do this.
Does anyone knows how to do this?
Well it's a long process, you have to implement two filters & one action to accomplish this.
Also there is a plugin for this exact purpose along with lot of other options related to woocommerce custom fields.
Here is the direct solution for your question.
/**
* Here we are trying to add your custom data as Cart Line Item
* SO that we can add this custom data on your cart, checkout, order and email later
*/
function save_custom_data( $cart_item_data, $product_id ) {
$custom_data = get_post_meta( $product_id, '_gram', true );
if( $custom_data != null && $custom_data != "" ) {
$cart_item_data["gram"] = $custom_data;
}
return $cart_item_data;
}
add_filter( 'woocommerce_add_cart_item_data', 'save_custom_data', 10, 2 );
/**
* Here we are trying to display that custom data on Cart Table & Checkout Order Review Table
*/
function render_custom_data_on_cart_checkout( $cart_data, $cart_item = null ) {
$custom_items = array();
/* Woo 2.4.2 updates */
if( !empty( $cart_data ) ) {
$custom_items = $cart_data;
}
if( isset( $cart_item["gram"] ) ) {
$custom_items[] = array( "name" => "Gram", "value" => $cart_item["gram"] );
}
return $custom_items;
}
add_filter( 'woocommerce_get_item_data', 'render_custom_data_on_cart_checkout', 10, 2 );
/**
* We are adding that custom data ( gram ) as Order Item Meta,
* which will be carried over to EMail as well
*/
function save_custom_order_meta( $item_id, $values, $cart_item_key ) {
if( isset( $values["gram"] ) ) {
wc_add_order_item_meta( $item_id, "Gram", $values["gram"] );
}
}
add_action( 'woocommerce_add_order_item_meta', 'save_custom_order_meta', 10, 3 );