I have created this piece of code that displays the price on any page on the website, which is controlled by woocommerce.
add_shortcode( 'hhs_product_price', 'hhs_woo_product_price_shortcode' );
function hhs_woo_product_price_shortcode( $atts ) {
$atts = shortcode_atts( array(
'id' => null
), $atts, 'hhs_product_price' );
if ( empty( $atts[ 'id' ] ) ) {
return '';
}
$product = wc_get_product( $atts['id'] );
if ( ! $product ) {
return '';
}
return $product->get_price_html();
}
What I would like to do is modify the code so that if a customer selects a product with a variation. Then the price changes to display the variation price. For example right now if a person selects a product, in this case a tincture bottle, with a price variation connected to the size of the bottle. On the products page they see the following:-
Product (Tincture) $30 - $50
From a drop down menu they can select an option of either 10mg bottle ($30), 15mg bottle ($40), or 20mg bottle ($50). So if a person selects option 20mg the price should display $50 instead of $30 - $50
I have already looked at various posts on stackoverflow with a similar problem but non of those solutions are working for me
Display woocommerce variable product price
Woocommerce get variation product price
Any help would be greatly appropriated.
Thank you
To display the selected product price from a variation on variable products, jQuery is required. So the following shortcode will handle all product types, including variable products and their price variations:
add_shortcode( 'product_price', 'display_formatted_product_price' );
function display_formatted_product_price( $atts ) {
extract(shortcode_atts( array(
'id' => null
), $atts, 'product_price' ) );
global $product;
if( ! empty($id) || ! is_a($product, 'WC_Product') ) {
$product = wc_get_product( empty($id) ? get_the_id() : $id );
}
$price_html = $product->get_price_html();
// Others product types than variable
if ( ! $product->is_type('variable') ) {
return '<span class="product-price">' . $price_html . '</span>';
}
// For variable products
else {
ob_start();
?>
<script type="text/javascript">
jQuery( function($){
var p = '<?php echo $price_html; ?>', s = 'span.product-price';
$( 'form.variations_form.cart' ).on('show_variation', function(event, data) {
$(s).html(data.price_html); // Display the selected variation price
});
$( 'form.variations_form.cart' ).on('hide_variation', function() {
$(s).html(p); // Display the variable product price range
});
});
</script>
<?php
return ob_get_clean() . '<span class="product-price">' . $price_html . '</span>';
}
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
USAGE:
Use [product_price] or in php code echo do_shortcode('[product_price]').
You can also define a product id like (for example for product id 37): [product_price id="37"]
I'd like to thank LoicTheAztec for this code which is tested and works. However I banged my head on one issue: if product variations are all with the same price, the price_html will come back empty (issue described here: https://github.com/woocommerce/woocommerce/issues/11827). I solved this with a filter found in the github conv above:
add_filter( 'woocommerce_show_variation_price', '__return_true');
Related
I'm trying to create a shortcode to place on my single product pages so to display the stock quantity for admins only. For normal customers I just show whether the product is in stock or not. This is the snippet I'm trying to create:
function Product_stock() {
if ( current_user_can( 'administrator' ) ) {
echo '<div class="sales-admin"><b>Available Stock (admin):</b><ol>';
global $product;
echo wc_get_stock_html( $product );
}
}
add_shortcode( 'Product_stock', 'Product_stock' );
However the above code displays the stock in the format I have it set for my woocommerce store, so it just displays again in this format Availability: In stock or Availability: Out of stock.
What do I need to write to add to get it to print the actual stock value?
One solution is to hook the product availability text.
You can try something like that :
/**
* WC : add product quantity on front-end only to admins and shop managers
*/
add_filter( 'woocommerce_get_availability_text', 'a3w_woocommerce_get_availability_text', 10, 2);
function a3w_woocommerce_get_availability_text( $availability, $product ) {
if ( current_user_can( 'manage_woocommerce' ) ) { // replace 'manage_woocommerce' by 'administrator' for admin only OR any other condition
$availability .= sprintf( ' ( %d )', $product->get_stock_quantity() );
}
return $availability;
}, 20, 2 );
This will display something like that to admins :
Availability: In stock ( 18 )
And this to customers :
Availability: In stock
Tested and working.
Place this code in the functions.php in your child theme.
I'm attempting to display the selected product variation description on my single product page after add to cart button on variable product pages.
Below is the code I've implemented, but it does not appear to be working:
add_action( 'woocommerce_after_add_to_cart_form', 'description_below_add_cart', 11 );
function description_below_add_cart() {
global $post;
$terms = wp_get_post_terms( $post->ID, 'product_cat' );
foreach ( $terms as $term ) $categories[] = $term->slug;
if ( in_array( 'cookware', $categories ) ) {
global $product;
$weight = $product->get_weight();
$dimensions = wc_format_dimensions($product->get_dimensions(false));
echo '<div class="short-description">' . $item['product']->get_description() .'</div>';
}
}
Here is a product page from the site.
How can I display specific data (the variation description) from selected product variation in Woocommerce after add to cart button for variable products?
Updated: Your current code can be simplified a bit regarding the product categories part. I have added some code to display the variation description for the selected product variation from variable product pages.
Here is the way to display the selected product variations description (requires some JQuery):
add_action( 'woocommerce_after_add_to_cart_form', 'description_below_add_cart', 11 );
function description_below_add_cart() {
global $product;
$terms_slugs = wp_get_post_terms( $product->get_id(), 'product_cat', array('fields' => 'slugs') ); // Get the terms slugs
// Only for 'cookware' product category
if ( in_array( 'cookware', $terms_slugs ) ) {
$weight = $product->get_weight();
$weight = ! empty($weight) ? wc_format_weight($weight) : '';
$dimensions = $product->get_dimensions(false);
$dimensions = ! empty($dimensions) ? wc_format_dimensions($dimensions) : '';
// For variable products
if ( $product->is_type('variable') ) {
// Display the selected variation description
echo '<div class="selected-variation-description"></div>';
?>
<script type="text/javascript">
jQuery( function($){
// On select variation display variation description
$('form.variations_form').on('show_variation', function( event, data ){
$('div.selected-variation-description').html(data.variation_description);
console.log(data.variation_description);
});
// On unselect variation remove variation description
$('form.variations_form').on('hide_variation', function(){
$('div.selected-variation-description').html('');
});
});
</script>
<?php
}
}
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
I need help for a particular situation. In WooCommerce, if "Manage Stock" is enabled for a simple product or variation, then a notification is being displayed in the product page => such as [this example][1]
However, if "Manage Stock" is not enabled, then there is no notification which I find it a pity because I still want to inform my customers that it's precisely in stock even if I don't manage the stock quantities.
I've found the below code. For simple products, it works without any problem. However, for variable product, this message is being displayed even before that a variation is selected. This is of course not okay, this code should be displayed only after that a variation is selected.
Can someone help me to fix this? For variable products, this message should only be displayed after that a particular variation is selected.
I've made a video capture to be a bit more illustrative : https://sgevcen.tinytake.com/tt/NDQzNTU2OF8xNDAyNTU2NA
function mycustom_shop_display_stock() {
global $product;
if ( !$product->get_manage_stock() && $product->is_in_stock() ) {
echo '<p class="stock in-stock">In Stock</p>';
}
}
add_action( 'woocommerce_before_add_to_cart_button', 'mycustom_shop_display_stock', 11 );
[1]: https://i.stack.imgur.com/aFnN1.png
Try the following instead that should allow to display your custom stock availability only for the variations of a variable product (and also on simple products):
add_filter( 'woocommerce_get_stock_html', 'filter_wc_get_stock_html', 10, 2 );
function filter_wc_get_stock_html( $html, $product ) {
if ( ! $product->is_type('variable') && ! $product->get_manage_stock() && $product->is_in_stock() ) {
$html = '<p class="stock in-stock">' . __( "In Stock", "woocommerce" ) . '</p>';
}
return $html;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
To exclude some product categories use the following (related to your comment):
add_filter( 'woocommerce_get_stock_html', 'filter_wc_get_stock_html', 10, 2 );
function filter_wc_get_stock_html( $html, $product ) {
// Here define the product categories to be excluded (can be term Ids, slugs or names)
$terms_excl = array('hoodies', 'albums');
$product_id = $product->is_type('variation') ? $product->get_parent_id() : $product->get_id();
if ( ! $product->is_type('variable') && ! $product->get_manage_stock() && $product->is_in_stock()
&& ! has_term( $terms_excl, 'product_cat', $product_id ) ) {
$html = '<p class="stock in-stock">' . __( "In Stock", "woocommerce" ) . '</p>';
}
return $html;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
Related thread: Display custom stock message if "Manage Stock" is not enabled in WooCommerce
I'm trying to find a way to place custom text before availability info (out of stock, in stock etc.) on woocommerce single product page.
I am using something like that:
add_filter( 'woocommerce_get_availability', 'change_product_availability_display' );
add_filter( 'unknown filter', 'change_product_availability_display' );
function change_product_availability_display( $availability ) {
// Additional text
$text = __('Availability:');
// returning the text before the availability
return $text . ' ' . $availability;
}
Its's based on: Add a custom text before the price display in WooCommerce.
In case of price filter named in my code "unknown filter" was woocommerce_cart_item_price. I've looked for this kind of filter for availability/stock item, but can't find it.
Maybe someone could review this code and help me to find this "unknown_filter" or have other idea how I can put custom text before availability info?
I have revisited your code as your are trying to merge a string with an array. Also I have added a 2nd hooked function that will allow to display your "labeled" availability to items in cart and checkout.
The code:
add_filter( 'woocommerce_get_availability', 'add_label_to_availability_display' );
function add_label_to_availability_display( $availability ) {
if( is_product() || is_cart() || is_checkout() ){
$label = __( 'Availability', 'woocommerce' ) . ': ';
$availability['availability'] = $label . $availability['availability'];
}
return $availability;
}
add_filter( 'woocommerce_cart_item_name', 'add_availability_below_cart_item_name', 10, 3);
function add_availability_below_cart_item_name( $item_name, $cart_item, $cart_item_key ) {
$availability = $cart_item['data']->get_availability();
return $item_name . '<br>' . $availability['availability'];
}
Code goes in function.php file of your active child theme (active theme).
Tested and works.
In my WooCommerce store, I have some products which are only available in USA, I want to hide the "Add to Cart" button on a Single Product Page, when the geolocation finds any country other than USA.
If it is USA, show "add to cart', if it is not USA, hide "add to cart" button.
(P.S. I used a plugin for that, but it is not working for some javascript conflict with other plugins.)
When conditions match (specific product IDs and other countries), this code will replace the add to cart buttons in shop archives by a link to the product and in single product pages by a custom text.
You just need to set in:
1st function the needed country code … (for you 'US' and already done)
2nd and 3rd functions your product IDs in the array
Here is the code:
// Conditional function country code detection
// #argument $code (string): country code restriction
// #return boolean
if( ! function_exists('is_from_country_code') ){
// ==> HERE below set your country code (Replace 'US' by yours)
function is_from_country_code( $code = 'US' ){
$location = new WC_Geolocation;
$user_ip = $location->get_ip_address();
$user_country_code = $location->geolocate_ip( $user_ip, false, false )['country'];
return $user_country_code == $code ? true : false;
}
}
// Replace "Add to cart" single product button and quantity by a custom text
add_action( 'woocommerce_single_product_summary', 'Custom_single_add_to_cart', 1 );
function Custom_single_add_to_cart(){
global $product;
// Set here your product IDS
$product_ids = array( 56, 53, 50 );
if( is_from_country_code() ||
( ! is_from_country_code() && ! in_array( $product->get_id(), $product_ids) ) )
return; // Continue for foreign countries and the specific products IDs
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
add_action('woocommerce_single_product_summary', function(){
echo '<p class="custom-text">'.__('Not available for your country', 'woocommerce').'</p>';
}, 30);
}
// Shop and archives pages: we replace the button add to cart by a link to the product
add_filter( 'woocommerce_loop_add_to_cart_link', 'custom_text_replace_button', 10, 2 );
function custom_text_replace_button( $button, $product ) {
// Set here your product IDS
$product_ids = array( 56, 53, 50 );
if( is_from_country_code() ||
( ! is_from_country_code() && ! in_array( $product->get_id(), $product_ids) ) )
return $button; // Continue for foreign countries and the specific products IDs
$button_text = __("View product", "woocommerce");
return '<a class="button" href="'.$product->get_permalink().'">'.$button_text.'</a>';
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested on woocommerce version 3+ and works