I'm trying to add a custom field just below the price in my Woocommerce theme. I was able to add simple html by using:
add_action( 'woocommerce_before_add_to_cart_form', 'SomeName' );
function SomeName() {
echo '<p>Some Text Here</p>';
}
But what I want to do is add a custom field key instead. I'm using this code for placing custom fields:
<?php
$naslov = get_post_meta($post->ID, 'Naslov', true);
if ($naslov) { ?>
<h2 class="single-naslov-kat"><? echo $naslov; ?></h2>
<?php
} else {
// do nothing;
}
?>
The code works great when I add it to content-single-product.php theme file. But I can't add it below the price through that file. And I have no idea how to incorporate it through functions.php.
If you have any other suggestions on how I might be able to add custom text below the price for each specific product that's ok too.
Any help would be greatly appreciated.
In your themes functions.php add the code,
//create custom field
function cfwc_create_custom_field() {
$args = array(
'id' => 'custom_field',
'label' => __( 'Custom Field', 'cfwc' ),
'class' => 'cfwc-custom-field',
'desc_tip' => true,
'description' => __( 'Enter Custom Field Description.', 'ctwc' ),
);
woocommerce_wp_text_input( $args );
}
add_action( 'woocommerce_product_options_general_product_data', 'cfwc_create_custom_field' );
// save custom field
function cfwc_save_custom_field( $post_id ) {
$link = wc_get_product( $post_id );
$title = isset( $_POST['custom_field'] ) ? $_POST['custom_field'] : '';
$link->update_meta_data( 'custom_field', sanitize_text_field( $title ) );
$link->save();
}
add_action( 'woocommerce_process_product_meta', 'cfwc_save_custom_field' );
// display custom field in single.php page
add_action('woocommerce_before_add_to_cart_form','cmk_additional_button');
function cmk_additional_button() {
global $product;
$custom_field = $product->get_meta('custom_field');
if(!empty($custom_field)) {
echo "<a href='$custom_field' target='_blank'><button type='button' class='button alt'>Custom Field</button></a>";
}
}
Related
I have a problem with the code below. With that code, we can select specific product and give them a different style in the shop archive. This is working.
However, I guess there is a error in the code.
Once I activated the checkbox for a product, it always appears in the new style even when I uncheck the checkbox. I assume that I made a error with the get_post_meta object.
Can someone help me with that?
Code to display the check box in the general product settings and add the class, based on the value in the check box
// Add checkbox
function action_woocommerce_product_general_options_product_style_listing_data() {
// Checkbox
woocommerce_wp_checkbox( array(
'id' => '_special_product_listing_style', // Required, it's the meta_key for storing the value (is checked or not)
'label' => __( 'Special style', 'woocommerce' ), // Text in the editor label
'desc_tip' => false, // true or false, show description directly or as tooltip
'description' => __( 'Promote a product by changing the style of the product card', 'woocommerce' ) // Provide something useful here
) );
}
add_action( 'woocommerce_product_options_general_product_data', 'action_woocommerce_product_general_options_product_style_listing_data', 10, 0 );
// Save Field
function action_woocommerce_product_general_options_product_style_listing_save( $product ) {
// Isset, yes or no
$checkbox = isset( $_POST['_special_product_listing_style'] ) ? 'yes' : 'no';
// Update meta
$product->update_meta_data( '_special_product_listing_style', $checkbox );
}
add_action( 'woocommerce_admin_process_product_object', 'action_woocommerce_product_general_options_product_style_listing_save', 10, 1 );
// Is_special style
function filter_woocommerce_post_class( $classes, $product ) {
if ( get_post_meta( $product->get_id(), '_special_product_listing_style', true ) ) {
$classes[] = 'custom-product-listing-class';
}
return $classes;
}
add_filter( 'woocommerce_post_class', 'filter_woocommerce_post_class', 10, 2 );
CSS to style the specific products:
/* Custom special product listing style */
li.sales-flash-overlay.woocommerce-text-align-left.woocommerce-image-align-center.do-quantity-buttons.product.type-product.post-10800.status-publish.first.instock.product_cat-crafty-beer-club.has-post-thumbnail.featured.sold-individually.taxable.shipping-taxable.product-type-variable.custom-product-listing-class {
border: 2px solid;
border-style: dashed;
}
Replace
// Is_special style
function filter_woocommerce_post_class( $classes, $product ) {
if ( get_post_meta( $product->get_id(), '_special_product_listing_style', true ) ) {
$classes[] = 'custom-product-listing-class';
}
return $classes;
}
add_filter( 'woocommerce_post_class', 'filter_woocommerce_post_class', 10, 2 );
With
// Is_special style
function filter_woocommerce_post_class( $classes, $product ) {
// Get meta
$spls = $product->get_meta( '_special_product_listing_style' );
// Compare
if ( $spls == 'yes' ) {
$classes[] = 'custom-product-listing-class';
}
return $classes;
}
add_filter( 'woocommerce_post_class', 'filter_woocommerce_post_class', 10, 2 );
That should suffice for your code to function fully
I added a custom subtitle field for woo-commerce products. When I fill its field from the dashboard it appears in the product. I can update the text but I can't remove its value it appears again when I update the product.
Here the code. I copied from somewhere
<?php
// Display Fields
add_action('woocommerce_product_options_general_product_data',
'woocommerce_product_custom_fields');
// Save Fields
add_action('woocommerce_process_product_meta', 'woocommerce_product_custom_fields_save');
function woocommerce_product_custom_fields()
{
global $woocommerce, $post;
echo '<div class="product_custom_field">';
// Custom Product Text Field
woocommerce_wp_text_input(
array(
'id' => '_custom_product_subtitle',
'placeholder' => 'Custom Product Subtitle',
'label' => __('Custom Product Subtitle', 'woocommerce'),
'desc_tip' => 'true'
)
);
}
function woocommerce_product_custom_fields_save($post_id)
{
// Custom Product Text Field
$woocommerce_custom_product_text_field = $_POST['_custom_product_subtitle'];
if (!empty($woocommerce_custom_product_text_field))
update_post_meta($post_id, '_custom_product_subtitle',
esc_attr($woocommerce_custom_product_text_field));
}
// To show after the title
add_action( 'woocommerce_after_shop_loop_item_title', 'custom_field_display_below_title', 2 );
function custom_field_display_below_title(){
global $product;
// Get the custom field value
$custom_field = get_post_meta( $product->get_id(), '_custom_product_subtitle', true );
// Display
if( ! empty($custom_field) ){
echo '<p class="custom-product-subtitle">'.$custom_field.'</p>';
}
}
This is the result of the code, it also displays where I want to, but I can't make remove the text it appears again when I update
To be able to reset (empty) this custom field, just replace the code line (from your 2nd function):
if( ! empty($woocommerce_custom_product_text_field) ){
by:
if( isset($woocommerce_custom_product_text_field) ){
So now you can remove the field value and save it.
Now since WooCommerce 3, your code is a bit outdatedā¦ Also, you should use shorter keys and variable names.
Below is your revisited code (changed the field meta key from '_custom_product_subtitle' to simply '_subtitle', replaced a hook and made some other changes).
// Display a text Field (admin single product)
add_action( 'woocommerce_product_options_general_product_data', 'display_admin_product_custom_text_field' );
function woocommerce_product_custom_fields() {
echo '<div class="product_custom_field">';
woocommerce_wp_text_input( array(
'id' => '_subtitle',
'label' => __('Custom subtitle', 'woocommerce'),
'placeholder' => __('You can add optionally a custom subtitle', 'woocommerce'),
'desc_tip' => 'true'
) );
echo '</div>'; // <== missing
}
// Save Text Field value (admin)
add_action( 'woocommerce_admin_process_product_object', 'save_admin_product_custom_text_field_value' );
function save_admin_product_custom_text_field_value( $product ) {
if ( isset($_POST['_subtitle']) ) {
$product->update_meta_data( '_subtitle', sanitize_text_field($_POST['_subtitle']) );
}
}
// Display product subtitle (front end)
add_action( 'woocommerce_after_shop_loop_item_title', 'custom_field_display_below_title', 2 );
function custom_field_display_below_title(){
global $product;
$value = $product->get_meta('_subtitle'); // Get the custom field value
if( ! empty($value) ){
echo '<p class="product-subtitle">' . $value . '</p>'; // Display
}
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
I tried to create a checkbox in the product edit site in woocommerce, which allows me to enable/disable a custom badge banner showed only on specific products. I got it working in the normal edit page, but also want to show the checkbox in the product quickedit panel.
I got it working in the product edit page with the code showing below. This was pretty simple as it was working out of the box.
/* 1. Add new checkbox to product edit page (General tab) */
add_action('woocommerce_product_options_general_product_data', 'bbloomer_add_badge_checkbox_to_products');
function bbloomer_add_badge_checkbox_to_products() {
woocommerce_wp_checkbox(array(
'id' => 'custom_badge',
'class' => '',
'label' => 'Echt SPECHTWERK'
)
);
}
/* 2. Save checkbox via custom field */
add_action('save_post', 'bbloomer_save_badge_checkbox_to_post_meta');
function bbloomer_save_badge_checkbox_to_post_meta($product_id) {
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
return;
if (isset($_POST['custom_badge'])) {
update_post_meta($product_id, 'custom_badge', $_POST['custom_badge']);
} else
delete_post_meta($product_id, 'custom_badge');
}
// 3. Display badge # single product page if checkbox checked
add_action('woocommerce_single_product_summary', 'bbloomer_display_badge_if_checkbox', 6);
function bbloomer_display_badge_if_checkbox() {
global $product;
if (get_post_meta($product->get_id(), 'custom_badge', true)) {
?> <div class="echt-spechtwerk-badge">
<img class="advantages-symbols" src="<?php echo get_bloginfo('wpurl') . '/wp-content/uploads/echt-SPECHTWERK-V6.svg' ?>">
</div>
<?php
}
}
Add the follows code for product bulk edit and quick edit with custom field -
function add_custom_field_in_bulk_edit_quick_edit(){
echo '<div class="inline-edit-group">';
woocommerce_wp_checkbox( array(
'id' => 'custom_badge',
'class' => '',
'label' => 'Echt SPECHTWERK'
) );
echo '</div>';
}
add_action( 'woocommerce_product_quick_edit_end', 'add_custom_field_in_bulk_edit_quick_edit', 99 );
add_action( 'woocommerce_product_bulk_edit_end', 'add_custom_field_in_bulk_edit_quick_edit', 99 );
function save_custom_field_in_bulk_edit_quick_edit( $post_id, $post ){
// 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 ( 'product' !== $post->post_type ) return $post_id;
if (isset($_REQUEST['custom_badge'])) {
update_post_meta( $post_id, 'custom_badge', $_REQUEST['custom_badge'] );
} else {
delete_post_meta( $post_id, 'custom_badge' );
}
}
add_action( 'woocommerce_product_bulk_and_quick_edit', 'save_custom_field_in_bulk_edit_quick_edit', 99, 2 );
I wanted to show product custom field value in product description page tab
first I have created a custom tab with the name of 'Youtube video' in function.php (/wp-content/themes/themename/functions.php)
Here is the code
add_filter( 'woocommerce_product_tabs', 'woo_new_product_tab' );
function woo_new_product_tab( $tabs ) {
// Adds the new tab
$tabs['test_tab'] = array(
'title' => __( 'Youtube Video', 'woocommerce' ),
'priority' => 55,
'callback' => 'woo_new_product_tab_content'
);
return $tabs;
}
And my function content
function woo_new_product_tab_content() {
$mood = get_post_meta($post->ID, 'Mood', true);
if ($mood) { ?>
<p>Today's Mood: <? echo $mood; ?></p>
<?php
} else {
echo "No data found";
}
}
Both code I have pasted in function.php (https://docs.woocommerce.com/document/editing-product-data-tabs/)
And I have set a custom tab value in product page (please check the first field in bellow image )
But in product page I am unable to get this value!
please let me know where am I wrong?
Thank you
I work on site that use External products from Amazon, but want instead pointing users to that external URL, first to add to cart that product. I have this function, that change Default Button text for each product, to Add to cart.
function sv_wc_external_product_button( $button_text, $product ) {
if ( 'external' === $product->get_type() ) {
// enter the default text for external products
return $product->button_text ? $product->button_text : 'Add To Cart';
}
return $button_text;
}
add_filter( 'woocommerce_product_single_add_to_cart_text',
'sv_wc_external_product_button', 10, 2 );
But this function not add product to cart.
How to make this function to Add selected product to cart?
Thanks.
Updated 2020
This is a complete different way with simple products and a custom field external link.
In this answer we will use simple products instead of external products.
We add an "External URL" custom field in product option settings and we save the data.
Add a custom field on general product option settings for simple products only :
add_action( 'woocommerce_product_options_general_product_data', 'simple_product_with_external_url' );
function simple_product_with_external_url() {
global $product_object;
echo '<div class="options_group show_if_simple hidden">';
// External Url
woocommerce_wp_text_input( array(
'id' => '_ext_url_cust',
'label' => 'External Url',
'description' => 'Custom external URL',
'desc_tip' => 'true',
'placeholder' => 'Enter here your custom external URL'
) );
echo '</div>';
}
Save the custom field data if it's a simple product and not empty:
add_action( 'woocommerce_admin_process_product_object', 'save_simple_product_with_external_url' );
function save_simple_product_with_external_url( $product ) {
if( $product->is_type('simple') && isset($_POST['_ext_url_cust']) ) {
$product->update_meta_data( '_ext_url_cust', sanitize_url($_POST['_ext_url_cust']) );
}
}
2) This will not work on shop pages and archives pages, if we don't set in WooCommerce the cart redirection when adding a product to cart.
So we will replace add-to-cart button (just for our simple products with a custom link redirection) on shop pages and archives pages by a linked custom button to single product pages.
Replacing add-to-cart button in shop pages and archives pages (for simple products with custom external url):
add_filter( 'woocommerce_loop_add_to_cart_link', 'quantity_inputs_for_woocommerce_loop_add_to_cart_link', 10, 2 );
function quantity_inputs_for_woocommerce_loop_add_to_cart_link( $html, $product ) {
$external_url = $product->get_meta('_ext_url_cust');
if ( ! empty($external_url) ) {
$html = sprintf( '%s', $product->get_permalink(), __("Read More", "woocommerce") );
}
return $html;
}
3) If the custom field value is not empty, the product is added to cart first and then redirected to the external URL (our custom field value in single product pages)
External URL redirection after adding to cart (when custom field is not empty in simple products):
add_filter( 'woocommerce_add_to_cart_redirect', 'redirect_simple_product_with_external_url' );
function redirect_simple_product_with_external_url( $url ) {
if( isset($_REQUEST['add-to-cart']) && absint( $_REQUEST['add-to-cart'] ) > 0 )
return get_post_meta( absint( $_REQUEST['add-to-cart'] ), '_ext_url_cust', true );
return $url;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works on WooCommerce version 3+
Use https://stackoverflow.com/a/44036965/3730754 instead.
You should try to use woocommerce_product_add_to_cart_url filter hook to change the add-to-cart link (here for grouped products), this way:
add_filter( 'woocommerce_product_add_to_cart_url', 'override_external_product_url', 10, 2 );
function override_external_product_url( $url, $product ){
if ( 'external' === $product->get_type() ) {
//Get product ID -- WooCommerce compatibility
if ( method_exists( $product, 'get_id' ) ) {
$product_id = $product->get_id();
} else {
$product_id = $product->id;
}
// custom add to cart url example
$url = home_url( "/product/?add-to-cart=$product_id");
}
return $url;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Update: But this will not add to cart this external product before redirecting to an external url even if it works displaying the add-to-cart url (as add-to-cart is ajax driven).
I fixed myself. For External products, to replace default "Buy This Product" with other generic text, add this functions into functions.php file into theme:
add_filter( 'woocommerce_product_add_to_cart_text' ,
'wpf_custom_add_cart_text_archive',11);
function wpf_custom_add_cart_text_archive() {
global $product;
$product_type = $product->product_type;
switch ( $product_type ) {
case 'external':
return __( 'Add to Cart', 'woocommerce' );
break;
case 'grouped':
return __( 'View products', 'woocommerce' );
break;
case 'simple':
return __( 'Add to cart', 'woocommerce' );
break;
case 'variable':
return __( 'Select options', 'woocommerce' );
break;
default:
return __( 'Read more', 'woocommerce' );
}
}
add_filter( 'woocommerce_product_single_add_to_cart_text',
'wpf_custom_add_cart_text',11);
and this one:
function wpf_custom_add_cart_text() {
return __( 'Add to Cart', 'woocommerce' );
}
to replace text everywhere.