This question already has an answer here:
Adding custom attribute to WooCommerce shop loop product title
(1 answer)
Closed 4 years ago.
I have found some code here on the site, to show a product attribute on the category pages. This works fine, it shows the attribute I want perfectly, but it would be really perfect if I could get this just below th product title, and not below the button, as where it is now. Can someone help me how I can do this?
this is how it looks now
/**
* PPM
*/
add_action( 'woocommerce_after_shop_loop_item', 'acf_template_loop_product_meta', 20 );
function acf_template_loop_product_meta() {
global $product;
// Check that we got the instance of the WC_Product object, to be sure (can be removed)
if( ! is_object( $product ) ) {
$product = wc_get_product( get_the_id() );
}
echo '<h4>Afdruksnelheid: ' . $product->get_attribute('pa_afdruksnelheid') .' PPM</h4>';
}
add_action( 'woocommerce_before_shop_loop_item_title', 'custom_before_title' );
function custom_before_title() {
global $product;
// Check that we got the instance of the WC_Product object, to be sure (can be removed)
if( ! is_object( $product ) ) {
$product = wc_get_product( get_the_id() );
}
echo '<h4>Afdruksnelheid: ' . $product->get_attribute('pa_afdruksnelheid') .' PPM</h4>';
}
There is no hook exactly in the place you mentioned. Check this hook guide for more info
Related
i want add, on product listing, over image a text badge "Free delivery" based on specific shipping class "spedizione-gratuita".
You can help me ?
I test this code but dont work
add_action( 'woocommerce_before_shop_loop_item_title', 'single_product_label', 10 );
function single_product_label() {
global $product;
$shipping_classes = 'spedizione-gratuita';
if ( $product->get_shipping_class() ) {
echo '<div class="spedizione-gratuita"><span class="freedel">SPEDIZIONE GRATUITA</span></div>';
}
}
Tnks
I believe this will achieve what you are trying to do. You almost had it, but the $product global has no value in the shop loop you need to use $post instead
add_action( 'woocommerce_before_shop_loop_item_title', 'single_product_label', 10 );
function single_product_label() {
global $post;
$_product = wc_get_product( $post->ID );
$shipping_classes = 'spedizione-gratuita';
if ( $shipping_classes == $_product->get_shipping_class() ) {
echo '<div class="spedizione-gratuita"><span class="freedel">SPEDIZIONE GRATUITA</span></div>';
}
}
I am running an art gallery website using WooCommerce and the owner does not want to show the product name/title if the product has been sold/out of stock.
I have got this far with putting together a function, but it doesn't work. I wondered if anyone could give me any tips?
// Hides title on Sold products
add_filter( 'woocommerce_shop_loop_item_title', 'remove_name', 10, 2 );
function remove_name ( $product ) {
if ( ! $product->is_in_stock()) {
$title = '';
}
return $title;
}
Your code contains some errors and mistakes:
woocommerce_shop_loop_item_title is NOT an filter but an action hook
No arguments are passed to this hook , while your code says there would be 2
$product is undefined, use global $product;
Note: I've added a line with debug information, it can be removed
So you get:
function action_woocommerce_shop_loop_item_title() {
global $product;
// Is a WC product
if ( is_a( $product, 'WC_Product' ) ) {
// Should be removed but may be useful towards debugging
echo '<p style="color: red; font-size: 20px;">DEBUG information: ' . $product->get_stock_status() . '</p>';
// NOT in stock
if ( ! $product->is_in_stock() ) {
// Removes a function from a specified action hook.
remove_action( 'woocommerce_shop_loop_item_title', 'woocommerce_template_loop_product_title', 10 );
}
}
}
add_action( 'woocommerce_shop_loop_item_title', 'action_woocommerce_shop_loop_item_title', 9 );
Please try to use this hook to remove product title. Use this inside the condition to check if product is in stock:
remove_action( 'woocommerce_shop_loop_item_title','woocommerce_template_loop_product_title', 10 );
This does what you want but still allows access to the product page.
add_action( 'woocommerce_shop_loop_item_title', function() {
global $product;
if ( ! $product->is_in_stock()) {
remove_action( 'woocommerce_shop_loop_item_title','woocommerce_template_loop_product_title', 10 );
}
}, 5 );
add_action( 'woocommerce_single_product_summary', function() {
global $product;
if ( ! $product->is_in_stock()) {
remove_action('woocommerce_single_product_summary', 'woocommerce_template_single_title', 5);
}
}, 1);
Short version: How do I get upsell for variable product in Woocommerce?
Longer version:
I need the product ids for upsells.
My old code contains depracated code:
$upsells = $product->get_upsells(); // $product is instace of WC_Product_Variable::
The call should be the following:
$upsells = $product->get_upsells_ids(); // $product is WC_Product::
But a different class.
I tried to get the parent instance using wc_get_product($product->get_parent_id()) - but fail.
So, given the instance of WC_Product_Variable how do I get to the parent method WC_Product::$product->get_upsells_ids() ??
Thanks
The get_upsells-ids() method does not exist. Try get_upsell_ids().
The following code will show you all the upsell ids for the product you are currently visiting:
// quick test to check upsell ids
add_action( 'woocommerce_before_single_product', 'echo_upsell_ids' );
function echo_upsell_ids() {
global $product;
$product_id = $product->is_type('variation') ? $product->get_parent_id() : $product->get_id();
$product = wc_get_product( $product_id );
$upsell_ids = $product->get_upsell_ids();
echo '<pre>' . print_r( $upsell_ids, true ) . '</pre>';
}
I have tested the code and it works. The snippet goes into your child theme's functions.php file.
I have created a advance custom field using ACF wordpress plugin to check if the product is available for this month or not. The code I am using is below but when it does work to point where it shows add to cart button if the product is available for that month if not then shows the message.
Now the issue is when product is available to purchase if I click on add to cart it says "Sorry, this product cannot be purchased." I am not able to find what is wrong with it.
add_filter('woocommerce_is_purchasable', 'woocommerce_is_purchasable_filter_callback', 10, 2 );
function woocommerce_is_purchasable_filter_callback( $purchasable, $product ) {
$months = (array) get_field('availability');
$purchasable = in_array( date('F'), $months ) ? $purchasable : false;
return $purchasable;
}
add_action( 'woocommerce_single_product_summary', 'unavailable_product_display_message', 20 );
function unavailable_product_display_message() {
global $product;
if(! $product->is_purchasable() ){
echo '<p style="color:#e00000;">' . __("This product is currently unavailable.") . '</p>';
}
}
Try to change this line of code:
$months = (array) get_field('availability');
to:
$months = (array) get_field('availability', $product->get_id());
The get_field function doesn`t know from which product to get, so this will be an empty array. The variable $purchasable will always be false when this happens.
I am trying to edit the short-description template to be different on variable (single) product pages than on simple products. the code in that page is here:
global $post;
if ( ! $post->post_excerpt )
return;
?>
<div itemprop="description">
<?php echo apply_filters( 'woocommerce_short_description', $post->post_excerpt ) ?>
</div>
I want to add some code to the if statement that will be something like
if post has variations, don't display short description, if simple product DO display
but I can't find any way in the code to distinguish between a regular simple product post and one that is variable (has variations). And looking through the API docs over at the Woo site (http://docs.woothemes.com/wc-apidocs/) I found nothing of that sort.
Use $product->is_type() function to check the product type. To check if the product is a variable product use:
global $product;
// $product->is_type( $type ) checks the product type, string/array $type ( 'simple', 'grouped', 'variable', 'external' ), returns boolean
if ( $product->is_type( 'variable' ) ) {}
There is also $product->get_type() function that returns the internal type of a product as a string.
After much heartache, I have found the following two solutions:
In the product loop, you can use this:
if( $product->has_child() ) {
but for some reason in the short description on the single product page, I had to use this:
global $post;
$children = get_pages('child_of='.$post->ID);
if( count( $children ) !== 0 ) {
Hope this helps others that were struggling as I was...
Variable product always is based on WC_Product_Variable class. E.g. WooCommerce Subscriptions follows this approach.
So, the checking can be:
is_a( $product, 'WC_Product_Variable' )
This ensures that the type of product is variable regardless of the presence of children. And it's fast.
For some reason if you have deleted your variation, the has_child() function it still turns true.
So I used the below solution
if(empty($product->get_available_variations())) {
// Your code goes here
}
This is the solution for me, using on body_class filter:
if ( is_singular( 'product' ) ) {
$product = wc_get_product( get_the_ID() );
if ( $product->is_type( 'variable' ) ) {
...
}
}