Learn how to create a WooCommerce add-to-cart button that automatically adds products to the cart, by SKU and Quantity. Deploy the button as a shortcode in your content, or hook the single product page to show “add x5”, “add x10” buttons. Because we’re going to render the HTML ourselves, we should be able to do a great job on making the button SEO-friendly.
We’re going to breakdown the problem into a couple of support/ancillary functions, and a core meat-and-potatoes function… a function that does one thing, and does it well.
Before we Start
- To follow this tutorial you’ll need to be using a custom child theme so you can keep our theme’s functions.php clean.
- Make sure you’ve got WooCommerce installed and working, and you’ve got at least one product with an SKU. You should really use SKUs for all your products and variations, if you can.
Featured plugin
Let’s Write some Code
Our core function will take the parameters $sku
, $quantity
and $text
. If the button’s text isn’t specified then we’ll create it automatically by using the name of the product. Then we’ll call our function from a shortcode handler… and anywhere else we want to use it.
First off, create some scaffolding by making a PHP file in your custom child theme’s folder, called functions-add-to-cart.php. Paste the following into it.
<?php /** * https://wp-tutorials.tech/refine-wordpress/woocommerce-add-to-cart-button-shortcode/ */ // Block direct access. defined('WPINC') || die(); function hw_atc_button(string $sku, int $quantity, string $text) { $html = ''; // Render the button HTML here. $html .= '<p>Hello World</p>'; return $html; } function do_shortcode_hw_atc_button($atts) { $args = shortcode_atts( array( 'sku' => '', 'qty' => 1, 'text' => '', ), $atts ); $html = hw_atc_button( strval($args['sku']), intval($args['qty']), strval($args['text']) ); return $html; } add_shortcode('atc_button', 'do_shortcode_hw_atc_button');
To reference the new code from the theme, open your custom child theme’s functions.php file and add the following:
/** * WooCommerce Add-to-Cart button */ require_once dirname(__FILE__) . '/functions-add-to-cart.php';
Save these two files and find a bit of content (a post or a page) where you can add a shortcode. Save and then view your content — you should see the text “Hello World” where you added the shortcode. This confirms that…
- The shortcode is registered properly
- The shortcode is calling our
hw_atc_button()
function - We’re properly rendering the HTML output from
hw_atc_button()
We can now concentrate on the core functionality — making hw_atc_button()
do a really nice job of rendering an SEO-rich add-to-cart button.
The Core Function
The only thing the main function needs to do is return a string with some HTML in it, based on the three parameters we pass into it. The HTML output string will come out looking something like this:
<!-- Pseudo-HTML for our button --> <a href="?add-to-cart=567&quantity=3" title="Buy 3x ACME Product One" class="..." rel="nofollow"> <span class="qty qty-3">3</span> <span class="label">Multipack</span> </a>
infoThe number “567” is the internal WooCommerce product id, not the SKU.
So, given that we pass-in the SKU, quantity and an optional label, we just need to convert the SKU into a WooCommerce Product Id, create an add-to-cart URL, and stitch-together the HTML fragments.
Here’s an updated version of hw_atc_button()
that you can paste into your functions-add-to-cart.php file.
function hw_atc_button(string $sku, int $quantity, string $text) { $html = ''; if (!function_exists('WC')) { $html .= sprintf('<code>WooCommerce is not installed</code>'); } elseif (empty($sku)) { $html .= sprintf('<code>SKU not specified</code>'); } elseif (empty($product_id = wc_get_product_id_by_sku($sku))) { $html .= sprintf('<code>Product not found: %s</code>', $args['sku']); } elseif (empty($product = wc_get_product($product_id))) { $html .= sprintf('<code>Failed to get product data: %s (%d)</code>', $args['sku'], $product_id); } else { $product_name = $product->get_name(); // Check that the quantity is valid. if ($quantity <= 0) { $quantity = 1; } // If we didn't set a text label, then use the product name. if (empty($text)) { $text = $product_name; } $url = sprintf( '%s?add-to-cart=%d&quantity=%d', wc_get_cart_url(), $product_id, $quantity ); // If you want more/different CSS classes on your <a> wrapper, you // can add them to this array. $css_classes = array( 'hw-atc', 'sku-' . sanitize_title($sku), ); // Open the anchor element. $html .= sprintf( '<a href="%s" class="%s" title="Buy %d × %s" rel="nofollow">', esc_url($url), esc_attr(implode(' ', $css_classes)), $quantity, esc_attr($product_name) ); // Quantity and text/label. $html .= sprintf( '<span class="qty qty-%d">%d</span><span class="label">%s</span>', $quantity, $quantity, esc_html($text) ); // Close the anchor element. $html .= '</a>'; } return $html; }
Like with any function that takes some inputs, does some work, and then generates some output… you should always check that the inputs are “sane” before you process them. The top part of the functions checks that everything is OK, and the last part of the function does the actual work.
- Check that WooCommerce is installed and the SKU is valid.
- If $quantity is a strange number, set it to a (sane) value of 1
- If $label isn’t specified then set it to the name of the product
- Create the $url string
- Create the $html string
tipNotice the sanitize_title() function where we make a list of CSS classes for our anchor element. This is a handy WordPress function that takes any sort of text input and converts it into lowercase characters with no spaces. For example, “Some Test String” would become “some-test-string”. It’s usually used for making permalinks/slugs, but you can use it for other things too, like creating CSS class names or HTML entity IDs.
Add a bit of Style
We’ve structured the HTML so you can do loads with the CSS, and the following will get you started. Add this to your custom child theme’s style.css file. It’s not going to win any design awards, but you can adjust it later, when the code is tested and working.
/* * WooCommerce Add-to-Cart button */ .hw-atc { display: inline-block; position: relative; background-color: blue; border-radius: 0.5em; padding: 0.5em 1em; transition: 0.3s; color: white; } .hw-atc:hover { text-decoration: none; background-color: cornflowerblue; color: white; } .hw-atc .qty::before { content: '+'; } .hw-atc .qty { position: absolute; display: block; left: 0; top: 0; width: 3em; height: 3em; background-color: green; border-radius: 50%; color: white; font-weight: bold; text-align: center; padding-top: 0.75em; transform: translate(-65%, -50%) rotate(-10deg); box-shadow: 0 0 0.25em rgba(0, 0, 0, 0.50); }
…and there you have it. An SEO-friendly customised add-to-cart button that you can use anywhere on your site.
More Uses for the Add-to-Cart Button
Now we’ve got a function that does a single function (and does it well) we can use it elsewhere. Let’s take the standard WooCommerce single product page. It’s full of action hooks that let us inject bits of HTML. If we use the woocommerce_after_add_to_cart_button hook then we can inject some HTML after the standard Add to Cart button.
All we have do is add the following snippet to functions-add-to-cart.php to hook the action and call our function three times, wrapped in a containing <div>
:
function hw_atc_add_buttons() { // Get the current product. if (empty($product = wc_get_product())) { // We should never end up in here. } elseif (empty($sku = $product->get_sku())) { // Product has no SKU. } else { echo '<div class="add-qty-buttons">'; echo hw_atc_button($sku, 5, 'Add Five'); echo hw_atc_button($sku, 10, 'Add Ten'); echo hw_atc_button($sku, 15, 'Add Fifteen'); echo '</div>'; // .add-qty-buttons } } add_action('woocommerce_after_add_to_cart_button', 'hw_atc_add_buttons');
…and a little bit of CSS to space-out the buttons nicely:
.add-qty-buttons { display: block; clear: both; display: flex; flex-direction: row; justify-content: space-between; padding: 2em 0; } .add-qty-buttons .hw-atc { width: 25%; }
Wrapping Up
- Try putting in silly values for SKU and quantity to make sure the error-handling works properly.
- Tidy up the CSS so the button doesn’t look so rubbish 😉
Have fun selling stuff with your website 😎👍