I am trying to remove the structured data that Woocommerce adds to the product pages.
I did some research and found that WC_Structured_Data::generate_product_data() generates the structured data markup. It's hooked in the woocommerce_single_product_summary action hook in the woocommerce/templates/content-single-product.php template file.
I tried by adding the following code to the functions.php
remove_action( 'woocommerce_single_product_summary', 'WC_Structured_Data::generate_product_data()', 60 );
So structured data wouldn't be added by Woocommerce, but it doesn't work…
Am I doing something wrong? Is there another way to do what I am trying to achieve?
Instead, you can use dedicated filter hook 'woocommerce_structured_data_product' that is located in WC_Structured_Data for generate_product_data() method nulling the structured data output in single product pages:
add_filter( 'woocommerce_structured_data_product', 'structured_data_product_nulled', 10, 2 );
function structured_data_product_nulled( $markup, $product ){
if( is_product() ) {
$markup = '';
}
return $markup;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
I suspect people want to remove the default tabs and they come here after they see the Woocommerce content-single-product.php template. In this template you see that generate_product_data() is hooked with priority 60.
After inspecting the hooks that run on woocommerce_single_product_summary.
You can easily remove the tabs with:
remove_action( 'woocommerce_single_product_summary', 'woocommerce_output_product_data_tabs', 60 );
I think Woocommerce forgot to mention this add_action.
This is how you can remove hooks associated with instantiated object method. You have to find the variable that holds the new Object instance.
In this case the main WooCommerce object is accessible as $GLOBALS['woocommerce'] and it has public property $structured_data which holds an instance of the WC_Structured_Data object.
Hence, to remove the hook in the question you can write this code:
remove_action( 'woocommerce_before_main_content', array( $GLOBALS['woocommerce']->structured_data, 'generate_website_data' ), 30 );
Add to functions.php:
add_action('wp_loaded', function() {
remove_action('woocommerce_single_product_summary', [$GLOBALS['woocommerce']->structured_data, 'generate_product_data'], 60);
});
Unhooks WC_Structured_Data::generate_product_data(). Will not waste resources on generating product data first for no reason and then "nulling" that same generated data a moment later using a filter.
Related
Within WooCommerce I have been making some edits to templates. So far this has been straight forward.
Now I am trying to add some columns into the 'Order Details' table under 'my-account > view-order'.
I am in the template view-order.php which is a template under 'myaccount' in WooCommerce.
Instead of seeing some code in a template to edit, I am seeing the following code:
<?php do_action( 'woocommerce_view_order', $order_id ); ?>
Where is the code from this action called and can I edit it?
Thanks for all time and help.
You need to look at WooCommerce plugin includes/wc-template-hooks.php core file (line 259):
add_action( 'woocommerce_view_order', 'woocommerce_order_details_table', 10 );
As you can see, the function woocommerce_order_details_table() is hooked in. So now let's find this function that is located in includes/wc-template-functions.php core file (starting line 2584).
As you will see this hooked function call the template file order/order-details.php.
So now you can make some changes:
1). Overriding the template file order/order-details.php via your active child theme or theme as explained in this documentation.
Note: The template file order/order-details.php is also used in Order received (thankyou), so take care to target your changes using the following condition:
// For view order
if ( is_wc_endpoint_url( 'view-order' ) ) {
// Here your changes
}
// For other cases
else {
// Here keep the original code
}
2). Or/and you could also remove this hooked function to replace it by your own custom function, with something like:
remove_action( 'woocommerce_view_order', 'woocommerce_order_details_table', 10 );
add_action( 'woocommerce_view_order', 'custom_order_details_table', 10 );
function custom_order_details_table( $order_id ) {
if ( ! $order_id ) {
return;
}
// Here below add your own custom code
}
You can also call your own custom template in that custom function, that will be used exclusively in order view endpoint...
Related: WooCommerce action hooks and overriding templates
WooCommerce Documentations:
Template structure & Overriding templates via a theme
WooCommerce Conditional Tags
I am trying to remove or edit the "sale!" badge is in woocommrce loop
In the content-product.php,
the comment block says the woocommerce_show_product_loop_sale_flash is hooked with woocommerce_before_shop_loop_item.
However it actually works with woocommerce_after_shop_loop_item_title.
I tried to remove everything from the hook, still, the sales badge still appears:
remove_action( 'woocommerce_after_shop_loop_item_title', 'woocommerce_template_loop_rating' );
remove_action( 'woocommerce_after_shop_loop_item_title', 'woocommerce_template_loop_price' );
remove_action( 'woocommerce_after_shop_loop_item_title', 'woocommerce_show_product_loop_sale_flash' );
The following is also not working:
remove_action( 'woocommerce_shop_loop_item_title', 'woocommerce_show_product_loop_sale_flash' );
remove_action( 'woocommerce_before_shop_loop_item_title', 'woocommerce_show_product_loop_sale_flash' );
So I really have no idea where the sales badge function is being called from?
I'm not sure why it's not working for you, because all you have to do is use remove_action, the parameters are the hook location being used and the action name. In this case:
remove_action( 'woocommerce_before_shop_loop_item_title', 'woocommerce_show_product_loop_sale_flash', 10 );
This works, I checked. I was looking for the same thing. Just add it to your functions.php file. It removes the action called woocommerce_show_product_loop_sale_flash from being hooked into the woocommerce_before_shop_loop_item_title hook location.
Perhaps there is a plugin putting it there as well?
In my case, I did not want the sale flash to be inside of the link so I moved it up to be a direct child of the li instead. I did this by first removing the action via the above, and then adding a new action with a new hook location. The new hook location is the same as the one used to open the link, so I had to modify the priority number to make sure it was executed before the link action sharing the hook.
add_action( 'woocommerce_before_shop_loop_item', 'woocommerce_show_product_loop_sale_flash', 5 );
I am trying to move the product tabs from woocommerce_after_single_product_summary to woocommerce_before_single_product_summary. Essentially, I want to replace the image of the product on the single product with a tab that has the image gallery, but all the other tabs show up in that same container. I have issues trying to get the container around the tabs to act like the container around the image, but what's got me stumped is how to remove the tabs from the woocommerce_after_single_product_summary section. I can remove "related products" no problem, from the same section, but nothing I've done has budged the tabs.
This works fine to remove the image:
remove_action ('woocommerce_before_single_product_summary',
'woocommerce_show_product_images',20);
This works fine to add the tabs in its place (Other than the container issue):
add_action( 'woocommerce_before_single_product_summary',
'woocommerce_output_product_data_tabs', 20 );
But this never seems to get rid of the tabs:
remove_action( 'woocommerce_after_single_product_summary',
'woocommerce_output_product_data_tabs', 10 );
I've checked that 10 is the correct number (which I found does make a difference) but it IS correct. I traced the add_action to
woocommerce/includes/wc-template-hooks.php:
/**
* After Single Products Summary Div.
*
* #see woocommerce_output_product_data_tabs()
* #see woocommerce_upsell_display()
* #see woocommerce_output_related_products()
*/
add_action( 'woocommerce_after_single_product_summary',
'woocommerce_output_product_data_tabs', 10 );
add_action( 'woocommerce_after_single_product_summary',
'woocommerce_upsell_display', 15 );
add_action( 'woocommerce_after_single_product_summary',
'woocommerce_output_related_products', 20 );
I can remove related products with:
remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_output_related_products', 20 );
I've tried the suggestion (in another topic) that the hook might need a "template redirect" but that didn't work either. What I tried was:
// Trying template redirect
function esb_product_category_filter_changes()
{remove_action('woocommerce_after_single_product_summary',
'woocommerce_output_product_data_tabs', 10);
}
do_action('template_redirect','esb_product_category_filter_changes');
Any ideas? I've searched all the possibly relevant plugins, turned a bunch off, and still the same behavior. I can put the tabs anywhere I want, but I can't get rid of them.
I have tested on Storefront theme:
remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_output_product_data_tabs', 10 );
And it works. So your issue can be due to your theme or some plugins that are making some customizations on this.
How to check it: With the following hooked function you will get the raw data output for woocommerce_after_single_product_summary hook (all callbacks, with priorities and arguments). This way you will be able to see if woocommerce_output_related_products is hooked in it and what is the priority.
This testing function will output the data for admins only in archives and product pages:
add_action( 'woocommerce_before_main_content', function(){
// Only for admin user role
if( ! current_user_can('edit_products')) return;
global $wp_filter;
echo '<pre>';
print_r( $wp_filter['woocommerce_after_single_product_summary'] );
echo '</pre>';
}, 50 );
Code goes in function.php file of the active child theme (or active theme).
Now you can get the correct priority to set in the remove_action() (and remove this testing code).
You could also try the following code (without any guaranty):
add_action( 'woocommerce_after_single_product_summary', 'removing_product_tabs', 2 );
function removing_product_tabs(){
remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_output_product_data_tabs', 10 );
}
Code goes in function.php file of the active child theme (or active theme).
i'm trying to change the order of my product page in woocommerce but i have a few problems with the remove_action().
I activated the child theme and in my functions.php i'm tryin to remove the add-to-cart button to add it back on another position.
I tried to put my remove_action() into a function that gets executed right after my parent theme loads.
function change_order() {
add_action('woocommerce_single_product_summary','woocommerce_template_single_add_to_cart', 15 );
remove_action('woocommerce_single_product_summary','woocommerce_template_single_add_to_cart', 30 );
}
add_action( 'after_setup_theme', 'change_order' );
The add_action gets excuted but the remove_action() isn't working...
I tried the same with 'init' instead of 'after_setup_theme' but it is still not working...
Does anybody know a solution for my problem ?
Use a different single product hook
add_action('woocommerce_single_product_summary','change_order' );
function change_order() {
add_action('woocommerce_product_meta_end','woocommerce_template_single_add_to_cart', 15 );
remove_action('woocommerce_single_product_summary','woocommerce_template_single_add_to_cart', 30 );
}
Works and tested.
Ever since we upgraded to Woocommerce version 3 our order confirmations are showing huge titles that include the variation detail. I don't like how it looks and it breaks some important functionalities in some custom-made plugins.
Reference: Order Name Showing Variations since update to WC version 3
There is a filter that can be used to disable this data displaying in the title called woocommerce_product_variation_title_include_attribute_name from what I understand. But I have no idea where to apply the filter.
Is there a quick way to apply the filter to change it back to display as it did before?
This filter should work returning a false value for $should_include_attributes first argument in woocommerce_product_variation_title_include_attributes filter hook this way:
add_filter( 'woocommerce_product_variation_title_include_attributes', 'custom_product_variation_title', 10, 2 );
function custom_product_variation_title($should_include_attributes, $product){
$should_include_attributes = false;
return $should_include_attributes;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
It should just work as you expect.
Update: The shorter way is:
add_filter( 'woocommerce_product_variation_title_include_attributes', '__return_false' );
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
just works too.
A quick gotcha if you're using this filter to remove attributes from e-mail items. It appears that once an item has been written to an order the properties of it will not change.
add_filter( 'woocommerce_product_variation_title_include_attributes', '__return_false' );
As #freemason_17 pointed out, #LoicTheAztec's answer could potentially hide those details at other places as well so just to be sure I added a condition that would limit this to the cart page alone:
function custom_product_variation_title($should_include_attributes, $product){
if(is_cart()) {
$should_include_attributes = false;
return $should_include_attributes;
}
}
add_filter( 'woocommerce_product_variation_title_include_attributes', 'custom_product_variation_title', 10, 2 );
I use this:
/* -------------------- Remove variation names from title ------------------- */
add_filter( 'woocommerce_product_variation_title_include_attributes', '__return_false' );
add_filter( 'woocommerce_is_attribute_in_product_name', '__return_false' );