The wc_price function solves your WooCommerce price formatting problems. Using it means you can ignore the WooCommerce price settings.
When you work on WooCommerce customization in your plugin/code snippet, you often need to format a price in order to display it correctly on the front-end.
Unfortunately, this can get tricky: you need to get (from the store settings) the WooCommerce currency symbol, the number of decimals, the decimal separator, the suffix, and so on. “Rebuilding” the price format each time can be really time-consuming.
Developers; please meet wc_price
.
This neat WooCommerce function can finally solve your price formatting nightmares and make you completely forget about the WooCommerce price settings: it’ll do the job for you.
As usual, we’ll take a look at practical examples; but first, let’s analyze the function code.
Function Code
By doing a quick search of the WooCommerce plugin’s files for the “function wc_price” term, we get a single result under \woocommerce\includes\wc-formatting-functions.php
:
/**
* Format the price with a currency symbol.
*
* @param float $price Raw price.
* @param array $args Arguments to format a price {
* Array of arguments.
* Defaults to empty array.
*
* @type bool $ex_tax_label Adds exclude tax label.
* Defaults to false.
* @type string $currency Currency code.
* Defaults to empty string (Use the result from get_woocommerce_currency()).
* @type string $decimal_separator Decimal separator.
* Defaults the result of wc_get_price_decimal_separator().
* @type string $thousand_separator Thousand separator.
* Defaults the result of wc_get_price_thousand_separator().
* @type string $decimals Number of decimals.
* Defaults the result of wc_get_price_decimals().
* @type string $price_format Price format depending on the currency position.
* Defaults the result of get_woocommerce_price_format().
* }
* @return string
*/
function wc_price( $price, $args = array() ) {
$args = apply_filters(
'wc_price_args',
wp_parse_args(
$args,
array(
'ex_tax_label' => false,
'currency' => '',
'decimal_separator' => wc_get_price_decimal_separator(),
'thousand_separator' => wc_get_price_thousand_separator(),
'decimals' => wc_get_price_decimals(),
'price_format' => get_woocommerce_price_format(),
)
)
);
$original_price = $price;
// Convert to float to avoid issues on PHP 8.
$price = (float) $price;
$unformatted_price = $price;
$negative = $price < 0;
/**
* Filter raw price.
*
* @param float $raw_price Raw price.
* @param float|string $original_price Original price as float, or empty string. Since 5.0.0.
*/
$price = apply_filters( 'raw_woocommerce_price', $negative ? $price * -1 : $price, $original_price );
/**
* Filter formatted price.
*
* @param float $formatted_price Formatted price.
* @param float $price Unformatted price.
* @param int $decimals Number of decimals.
* @param string $decimal_separator Decimal separator.
* @param string $thousand_separator Thousand separator.
* @param float|string $original_price Original price as float, or empty string. Since 5.0.0.
*/
$price = apply_filters( 'formatted_woocommerce_price', number_format( $price, $args['decimals'], $args['decimal_separator'], $args['thousand_separator'] ), $price, $args['decimals'], $args['decimal_separator'], $args['thousand_separator'], $original_price );
if ( apply_filters( 'woocommerce_price_trim_zeros', false ) && $args['decimals'] > 0 ) {
$price = wc_trim_zeros( $price );
}
$formatted_price = ( $negative ? '-' : '' ) . sprintf( $args['price_format'], '<span class="woocommerce-Price-currencySymbol">' . get_woocommerce_currency_symbol( $args['currency'] ) . '</span>', $price );
$return = '<span class="woocommerce-Price-amount amount"><bdi>' . $formatted_price . '</bdi></span>';
if ( $args['ex_tax_label'] && wc_tax_enabled() ) {
$return .= ' <small class="woocommerce-Price-taxLabel tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>';
}
/**
* Filters the string of price markup.
*
* @param string $return Price HTML markup.
* @param string $price Formatted price.
* @param array $args Pass on the args.
* @param float $unformatted_price Price as float to allow plugins custom formatting. Since 3.2.0.
* @param float|string $original_price Original price as float, or empty string. Since 5.0.0.
*/
return apply_filters( 'wc_price', $return, $price, $args, $unformatted_price, $original_price );
}
There are quite a few PHP statements inside that function!
Let’s break down each section:
- The function starts by getting the
$args
, which are basically what we said in the introduction: separators, currency, number of decimals, and suffix. These will be used later to formatting a number as a WooCommerce price. - Next, the function converts the raw price to a float in case it’s not a float:
$price = (float) $price
. This is for PHP 8 compatibility. - Then, should the price be negative for whatever reason,
$price * -1
does its magic and makes it a positive number. - Now to the cool part. The
number_format
PHP function converts the original floating point number into a price by using the$args
we previously gathered. - Optionally,
wc_trim_zeros( $price )
trims trailing zeros. (Yep,wc_trim_zeros
is now a candidate for one of the next WooCommerce function of the week posts!) - We then move to HTML; our “number” is formatted thanks to a series of spans, tags, classes and wrappers. It’s stored inside the
$return
variable. - A filter,
wc_price
, finally allows us to change the price format if necessary. (A different name might have been better to avoid confusion, but that’s how it is.)
And that’s it!
Function Usage
We know the code now, so let’s look at how it’s used.
Let’s pick a number:
5.6
Let’s call wc_price
and print its result:
echo wc_price( 5.6 );
And finally, let’s take a look at the generated HTML:
<span class="woocommerce-Price-amount amount">
<bdi>
<span class="woocommerce-Price-currencySymbol">$</span>
5.60
</bdi>
</span>
Magic! (Please note the currency symbol, the currency position, the price with two decimals… that’s all from the settings.)
Function Example
Now to the case study.
It may happen that you need to display the total discount the customer has totaled based on the items in the cart.
You’d calculate this total as a float, and with wc_price
you can nicely format it based on the store settings without concerning yourself with them!
Let’s trigger a notice on the Cart page:
/**
* @snippet Display formatted discount | WooCommerce Cart
* @how-to Get CustomizeWoo.com FREE
* @author Rodolfo Melogli
* @testedwith WooCommerce 6
* @donate $9 https://businessbloomer.com/bloomer-armada/
*/
add_action( 'woocommerce_before_cart', 'bbloomer_show_total_discount' );
function bbloomer_show_total_discount() {
if ( WC()->cart->is_empty() ) return;
$discount_total = 0;
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
$product = $values['data'];
if ( $product->is_on_sale() ) {
$regular_price = $product->get_regular_price();
$sale_price = $product->get_sale_price();
$discount = ( $regular_price - $sale_price ) * $values['quantity'];
$discount_total += $discount;
}
}
if ( $discount_total > 0 ) {
wc_print_notice( 'Your total discount is: ' . wc_price( $discount ), 'notice' );
}
}
Right there at the end, I’ve used wc_price
to format the total discount inside the notice: wc_price( $discount )
.
Here’s a screenshot of the output:
(Regular price was $997, sale price is $897, and quantity = 1, therefore the total discount is $100.)
I hope you enjoyed yet another WooCommerce shortcut.
Just my wc_price( 0.02 )
!