On the WooCommerce single product page there is an “Add to cart” button
Click here to enroll in our Free WooCommerce Coding Course
In most cases people will want the button to appear as they’ll want to make it as easy as possible to buy products in their store.
I have seen requests to remove the button though, and replace it with text such as “Call us for availability”.
There is a way to remove the button by calling remove_action
but you have to be careful using this method as although it does remove the “Add to cart” button, it can also remove other functionality.
Let’s take a look at how WooCommerce renders the “Add to cart” button and the best way to remove it.
The Process that WooCommerce Uses to add the “Add to cart” button to the Single Product Page
If I look at the single product page with the excellent “Query Monitor” plugin installed and bring up the diagnostics, it shows me the template that rendered the page
So we know that this is the template that has rendered the single product page, if we then look at the “single-product.php” file in the WooCommerce plug-in source we can see the following line
<?php wc_get_template_part( 'content', 'single-product' ); ?>
Because of the way that the wc_get_template_part
function works the line above will cause it to look for the following template
wp-content/plugins/woocommerce/templates/content-single-product.php
Inside that template is the following code
<?php /** * Hook: woocommerce_single_product_summary. * * @hooked woocommerce_template_single_title - 5 * @hooked woocommerce_template_single_rating - 10 * @hooked woocommerce_template_single_price - 10 * @hooked woocommerce_template_single_excerpt - 20 * @hooked woocommerce_template_single_add_to_cart - 30 * @hooked woocommerce_template_single_meta - 40 * @hooked woocommerce_template_single_sharing - 50 * @hooked WC_Structured_Data::generate_product_data() - 60 */ do_action( 'woocommerce_single_product_summary' ); ?>
We can see from the code above that the woocommerce_single_product_summary
action has a function named woocommerce_template_single_add_to_cart
hooked to it, let’s take a look at the code for that function which we can find in wp-content/plugins/woocommerce/includes/wc-template-functions.php
/** * Trigger the single product add to cart action. */ function woocommerce_template_single_add_to_cart() { global $product; do_action( 'woocommerce_' . $product->get_type() . '_add_to_cart' ); }
As you can see from the code above the function calls an action that it creates the name of by concatenating the current product type in the middle of a couple of other strings, if we imagine that we are looking at a simple product then the action that will get called is woocommerce_simple_add_to_cart
In the wp-content/plugins/woocommerce/includes/wc-template-hooks.php file the woocommerce_simple_add_to_cart
action is hooked to a function that is also called woocommerce_simple_add_to_cart
add_action( 'woocommerce_simple_add_to_cart', 'woocommerce_simple_add_to_cart', 30 );
The woocommerce_simple_add_to_cart
function can be found in the wp-content/plugins/woocommerce/includes/wc-template-functions.php
function woocommerce_simple_add_to_cart() { wc_get_template( 'single-product/add-to-cart/simple.php' ); }
As you can see from the code above, it uses the wc_get_template
function to render the single-product/add-to-cart/simple.php template. It is this template that renders the add to cart button to the screen.
Now we know how the “Add to cart” button is added to the single product page we can write some code to remove it, it would be tempting to write something that used the remove_action
function to remove the woocommerce_template_single_add_to_cart
function from the woocommerce_single_product_summary
action. The code would look something like this. Please note, this is just an example, it’s not the best way to solve the problem
add_action('woocommerce_single_product_summary', 'hwn_remove_add_to_cart_using_remove_action', 2 ); function hwn_remove_add_to_cart_using_remove_action(){ global $product; $tshirt_with_logo_product_id = 32; if ($product->get_id() == $tshirt_with_logo_product_id) { remove_action('woocommerce_single_product_summary','woocommerce_template_single_add_to_cart',30 ); } }
The code above hooks into the woocommerce_single_product_summary
action using a low priority number, this allows it to remove the woocommerce_template_single_add_to_cart
function before it fires. In the code above we add an if
statement so the action is only removed if the current product has a specific id.
So what are the drawbacks of doing it this way?
The main drawback is that by removing the woocommerce_template_single_add_to_cart
function we also remove any functions that are fired as part of that function, such as woocommerce_simple_add_to_cart
, so if any other plugins or themes are hooked into that function their functionality will be removed when our code runs.
So what would be a better solution?
The answer to this lies in the single-product/add-to-cart/simple.php template, the following code is at the top of the template file
As you can se there is an if statement on line 22 that returns out of the template if the $product->is_purchasable()
check returns false, if we could make a particular product not purchasable then we could get the code to drop out of the template and not write the “Add to cart” button to the screen.
Luckily, we can do this, if we look at the code for is_purchaseble()
we can see it fires a filter with the tag woocommerce_is_purchasable
/** * Returns false if the product cannot be bought. * * @return bool */ public function is_purchasable() { return apply_filters( 'woocommerce_is_purchasable', $this->exists() && ( 'publish' === $this->get_status() || current_user_can( 'edit_post', $this->get_id() ) ) && '' !== $this->get_price(), $this); }
If we hook into this filter then we can remove the “Add to cart” button by returning false and causing the template to return before it has added the “Add to cart” button to the screen, here’s how we could do it using the same product as we did in our remove_action
example
function hwn_remove_add_to_cart_using_is_purchasable($product_purchasable,$product) { $tshirt_with_logo_product_id = 32; if( $product->get_id() == $tshirt_with_logo_product_id ) { return false; } return $product_purchasable; } add_filter('woocommerce_is_purchasable', 'hwn_remove_add_to_cart_using_is_purchasable',10,2);
If we add this snippet to our store then the “Add to cart” button will be removed for the specified product
and we won’t have had to any remove any functions from action hooks, so this change should play nicely with other custom code and plugins that we are using in our store.
So Now We’ve Finally Removed The Add To Cart Button , How Can We Replace It With Something Else?
We can do this by adapting the code we wrote to remove the action, if we change it to add an action just after the woocommerce_template_single_add_to_cart
function is fired then it will add text to the single product screen just after where “Add to cart” button would normally be.
function hwn_remove_add_to_cart_using_remove_action(){ global $product; $tshirt_with_logo_product_id = 32; if ($product->get_id() == $tshirt_with_logo_product_id) { add_action('woocommerce_single_product_summary','hwn_text_to_replace_add_to_cart_button',31 ); } } function hwn_text_to_replace_add_to_cart_button(){ echo "This product can not currently be purchased via our online store, please contact us for more details."; } add_action('woocommerce_single_product_summary', 'hwn_remove_add_to_cart_using_remove_action', 2 );
As you can see from the code above we use the add_action
function to hook a function to the woocommerce_single_product_summary
action, we use the same if
logic as we did previously so the action will only be added if the single product screen is showing a certain product.
If we now add all our code together we get the following
function hwn_remove_add_to_cart_using_remove_action(){ global $product; $tshirt_with_logo_product_id = 32; if ($product->get_id() == $tshirt_with_logo_product_id) { add_action('woocommerce_single_product_summary','hwn_text_to_replace_add_to_cart_button',31 ); } } function hwn_text_to_replace_add_to_cart_button(){ echo "This product can not currently be purchased via our online store, please contact us for more details."; } add_action('woocommerce_single_product_summary', 'hwn_remove_add_to_cart_using_remove_action', 2 ); function hwn_remove_add_to_cart_using_is_purchasable($product_purchasable,$product) { $tshirt_with_logo_product_id = 32; if( $product->get_id() == $tshirt_with_logo_product_id ) { return false; } return $product_purchasable; } add_filter('woocommerce_is_purchasable', 'hwn_remove_add_to_cart_using_is_purchasable',10,2);
If the code above is added to a store then it will remove the “Add to cart” button and also add the extra text the echoed in the hwn_text_to_replace_add_to_cart_button
function
You could change the text echoed by the hwn_text_to_replace_add_to_cart_button
function to be anything you like, or replace it with a contact form etc.
Click here for more details about the "Learning WooCommerce Development By Example" book
Final Thoughts
That’s ended up being quite a long post as I went through how the “Add to cart” button is added to the single product page and the different ways we can remove it. I’d be interested to know if you enjoy posts like this or if you’d prefer shorter posts with code snippets. Please let me know what you think about that, and any other questions you have in the comments below.