WooCommerce is chock-full of filters, hooks and functions to help you customize and utilize the plugin in your theme or plugin. Here are some small, but useful, code examples, a-ha’s and how-tos of common changes of different text outputs.

Changing “Add to cart” button texts

There are two filters; one for “add to cart” texts in loop (woocommerce_product_add_to_cart_text), and another for the button in single product (woocommerce_product_single_add_to_cart_text):

// Single product view
add_filter('woocommerce_product_single_add_to_cart_text', function($text) {
	return __('Buy this now', 'txtdomain');
});

// Loop
add_filter('woocommerce_product_add_to_cart_text', function($text) {
	return __('Buy this', 'txtdomain');
});

However keep in mind that this overrides all “Add to cart” texts. Even those which were originally “Select options” (variable products) or “Read more” (unpurchasable products – no price or out of stock). If you want more finetuning, include the second argument to these filters; the product object. Use the product object to conditionally control the output. For example by product type or whether or not product can be purchased:

add_filter('woocommerce_product_add_to_cart_text', function($text, $product) {
	if ($product->is_type('variable')) {
		return __('Take your pick', 'txtdomain');
	}
	if (!$product->is_purchasable()) {
		return __('Read more', 'txtdomain');
	}
	return $text;
}, 10, 2);

Change the price range output on variable and grouped products

As default WooCommerce will display the lowest and the highest price on variable and grouped products, with a “-” inbetween. You can very easily modify this range output. For example make sure it only shows the lowest price, in the form of “From: <lowest price>”. WooCommerce has one filter for variable products and another for grouped products, so let’s look at them both in turn.

Controlling the price range HTML output for variable products is done with the filter woocommerce_variable_price_html. The product object is provided as second argument.

Inside the function we need to fetch all the prices. WooCommerce offers a handy function on variable product objects, get_variation_prices(). This returns an array of all variant prices, sorted by lowest first. All we need to do if pop off the first element in the prices array, and output it nicely:

add_filter('woocommerce_variable_price_html', function($html, $product) {
	$prices = $product->get_variation_prices(true);
	$from_price = wc_price(current($prices['price']));
	return sprintf(__('From: %s', 'txtdomain'), $from_price . $product->get_price_suffix());
}, 10, 2);

The price range HTML output filter for grouped products is very similar to variable products but with one difference; an array of all grouped product “children”‘s prices is included as argument to the filter. The filter to use is woocommerce_grouped_price_html:

add_filter('woocommerce_grouped_price_html', function($html, $product, $child_prices) {
	$from_price = wc_price(current($child_prices));
	return sprintf(__('From: %s', 'txtdomain'), $from_price . $product->get_price_suffix());
}, 10, 3);

Modify stock status text output

If you have activated display of stock status in WooCommerce settings, it should display the precise amount of stock left in single product view (e.g. “42 in stock”). However you can modify the output to instead show a range rather than the precise amount. Or just “In stock” if you want to conceal the number.

The filter for doing this is woocommerce_get_stock_html and if you include the second argument you get the product object. With the product object you can do the necessary operations for finetuning the output. Keep in mind that the filterable output is wrapped inside a <p> element, and your output should too.

For simply showing “In stock” or “Not in stock” this will suffice:

add_filter('woocommerce_get_stock_html', function($html, $product) {
	if ($product->is_in_stock()) {
		return sprintf('<p class="stock in-stock">%s</p>', __('In stock', 'txtdomain'));
	} else {
		return sprintf('<p class="stock out-of-stock">%s</p>', __('Out of stock', 'txtdomain'));
	}
	return $html;
}, 10, 2);

Showing stock in “range values” can be done like this:

add_filter('woocommerce_get_stock_html', function($html, $product) {
	$current_stock = $product->get_stock_quantity();
	if ($current_stock <= 0) {
		$new_html = __('Out of stock', 'txtdomain');
	} else if ($current_stock > 500) {
		$new_html = sprintf('500+ %s', __('in stock', 'txtdomain'));
	} else if ($current_stock > 100) {
		$new_html = sprintf('100+ %s', __('in stock', 'txtdomain'));
	} else if ($current_stock > 20) {
		$new_html = sprintf('20+ %s', __('in stock', 'txtdomain'));
	} else {
		$new_html = __('In stock', 'txtdomain');
	}
	return sprintf('<p class="stock">%s</p>', $new_html);
}, 10, 2);

Rename order statuses

Sometimes a client wants different labels on order statuses to make more sense according to their webshop practices. For example you might want “On hold” to be renamed into “Unsent” or “Completed” to be renamed “Sent”. Just to make more sense which orders need to be sent and which has already been sent. WooCommerce offers a simple filter, wc_order_statuses, on all available order statuses’ names.

add_filter('wc_order_statuses', function($order_statuses) {
	$order_statuses['wc-on-hold'] = __('Unsent', 'txtdomain');
	$order_statuses['wc-completed'] = __('Sent', 'txtdomain');
	return $order_statuses;
});

Available keys are wc-pending, wc-processing, wc-on-hold, wc-completed, wc-cancelled, wc-refunded, and wc-failed.