4
votes

IN WooCommerce I am using the code of this tread to display with a short code the product prices from a defined product ID. But it don't really do what I want. Here is that code:

function so_30165014_price_shortcode_callback( $atts ) {
$atts = shortcode_atts( array(
'id' => null,
), $atts, 'bartag' );

$html = '';

if( intval( $atts['id'] ) > 0 && function_exists( 'wc_get_product' ) ){
 $_product = wc_get_product( $atts['id'] );
 $number = number_format($_product->get_price(), 2, '.', ',');
 $html = "$" . $number;

 }
 return $html;
 }
 add_shortcode( 'woocommerce_price', 'so_30165014_price_shortcode_callback' );

I have a poor knowledge in php coding. But I've seen that there this other thread to display product prices:

$_product->get_regular_price();
$_product->get_sale_price();
$_product->get_price();

I Have tried to mix these code into the big code, and replaced get_price()… It works, but what I want is to display prices is something like this :

What I want to display

So the Regular price crossed out, and the Sale price next to it, like in this screenshot. If there is no Sale price, it display only the regular price.

Also I have some other problems:

  • I need to display the price is in , not in $, so I have replaced the currency symbol from $ (dollars) to (euros) with this code: $html = "€" . $number;

  • I need to display the currency symbol after the price, like : 37 € (with a blank space between), not like $37.

How can I make it work in a clean normal way?

4
Everything was correctly set in the settings of Woocommerce before I put this code. But it doesn't display what I want. Maybe because the code is not suitable for my use. But I can't see that because I don't know php coding.Gaou

4 Answers

12
votes

Updated (takes into account if your prices are displayed with or without taxes)

With Woocommerce there is already formatting price function wc_price() that you can use in your code. Also you need to get the sale price

To get this working when there is a sale price or without it try this code (commented):

function custom_price_shortcode_callback( $atts ) {

    $atts = shortcode_atts( array(
        'id' => null,
    ), $atts, 'product_price' );

    $html = '';

    if( intval( $atts['id'] ) > 0 && function_exists( 'wc_get_product' ) ){
        // Get an instance of the WC_Product object
        $product = wc_get_product( intval( $atts['id'] ) );

        // Get the product prices
        $price         = wc_get_price_to_display( $product, array( 'price' => $product->get_price() ) ); // Get the active price
        $regular_price = wc_get_price_to_display( $product, array( 'price' => $product->get_regular_price() ) ); // Get the regular price
        $sale_price    = wc_get_price_to_display( $product, array( 'price' => $product->get_sale_price() ) ); // Get the sale price

        // Your price CSS styles
        $style1 = 'style="font-size:40px;color:#e79a99;font-weight:bold;"';
        $style2 = 'style="font-size:25px;color:#e79a99"';

        // Formatting price settings (for the wc_price() function)
        $args = array(
            'ex_tax_label'       => false,
            'currency'           => 'EUR',
            'decimal_separator'  => '.',
            'thousand_separator' => ' ',
            'decimals'           => 2,
            'price_format'       => '%2$s %1$s',
        );

        // Formatting html output
        if( ! empty( $sale_price ) && $sale_price != 0 && $sale_price < $regular_price )
            $html = "<del $style2>" . wc_price( $regular_price, $args ) . "</del> <ins $style1>" . wc_price( $sale_price, $args ) . "</ins>"; // Sale price is set
        else
            $html = "<ins $style1>" . wc_price( $price, $args ) . "</ins>"; // No sale price set
    }
    return $html;
 }
 add_shortcode( 'product_price', 'custom_price_shortcode_callback' );

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.


USAGE (for example product ID 37):

[product_price id="37"]

This code is tested and works. You will get this:

enter image description here

1
votes

An alternative, if anyone needs simple text output of prices, is the following:

function wc_price_by_id_shortcode( $atts ) {
    $atts = shortcode_atts( array( 'id' => null, ), $atts, 'bartag' );

    if( intval( $atts['id'] ) > 0 && function_exists( 'wc_get_product' ) ){ 
        $_product = wc_get_product( $atts['id'] ); 
        $price = wc_price( $_product->get_price() );
      } 
  return $price; 
} 
add_shortcode( 'product_price', 'wc_price_by_id_shortcode' );

The shortcode is then [product_price id=XX] (replacing XX with the product id)

To add styling to the price, add a span class by adding the line:

$html .= "<span class="price_by_id_shortcode">". $price . "</span>";,

change the line return $price; to return $html;,

then add your style formatting to your css as needed.

(N.B. this only outputs current price, not regular price.)

0
votes

OK, a friend of me helped me, and gave me the good code. If it help someone else ... Here it is:

function so_30165014_price_shortcode_callback( $atts ) {
    $atts = shortcode_atts( array('id' => null,), $atts, 'bartag' );
    $html = '';

    if( intval( $atts['id'] ) > 0 && function_exists( 'wc_get_product' ) ){ 
          $_product = wc_get_product( $atts['id'] ); 

      $price = $_product->get_price();
      $regular_price = $_product->get_regular_price();

          $price_format = number_format($_product->get_price(), 2, '.', ','); 
          $regular_price_format = number_format($_product->get_regular_price(), 2, '.', ',');

      if($price != $regular_price){
        $html .= "<span style='font-size:25px;text-decoration:line-through;'>".$regular_price_format."&nbsp;€"."</span>";  
      } 
      $html .= "<span style='font-size:40px;font-weight:bold;'>&nbsp;". $price_format."&nbsp;€"."</span>"; 
  } 
  return $html; 
} 

add_shortcode( 'woocommerce_price', 'so_30165014_price_shortcode_callback' );

bye !

0
votes

@LoicTheAztec thanks so much for your code!!!

I've done done a few modifications, so I'm sharing it here. Maybe it's useful for somebody too :)

Note: this version is NOT "plug and play". In other words: it needs some work if you want to adapt it to your needs.

This version also changes the currency depending on the page language. For example:

  • If the page is in English, the prices are displayed in British Pounds.
  • If the page is in Spanish, the prices are displayed in EURO.

Note: this version also:

  • Removes the css. Instead, it add a class. I did it in that way because I already have my styles defined in that class.
  • Add a link in the discounted price to checkout. So if the page language is fr, the result URL will be: https://www.edinventa.com/fr/checkout/?fill_cart=7982

Code:

/**
 * Shortcode to display default price and discounted price
 * USAGE: 
 * [product_price id="37"]
 * Original code: https://stackoverflow.com/a/47237674/1198404
 * Modificated code to fit our needs: https://stackoverflow.com/a/63418231/1198404
 */
function custom_price_shortcode_callback( $atts ) {

    $atts = shortcode_atts( array(
        'id' => null,
    ), $atts, 'product_price' );

    $html = '';

    if( intval( $atts['id'] ) > 0 && function_exists( 'wc_get_product' ) ){
        // Get an instance of the WC_Product object
        $product = wc_get_product( intval( $atts['id'] ) );

        // Get the product prices
        $price         = wc_get_price_to_display( $product, array( 'price' => $product->get_price() ) ); // Get the active price
        $regular_price = wc_get_price_to_display( $product, array( 'price' => $product->get_regular_price() ) ); // Get the regular price
        $sale_price    = wc_get_price_to_display( $product, array( 'price' => $product->get_sale_price() ) ); // Get the sale price
        
        // Build checkout URL like: https://www.edinventa.com/fr/checkout/?fill_cart=7982&
        $domain_base_url = get_bloginfo('wpurl');
        $wpml_language_code = ICL_LANGUAGE_CODE;
        $checkout_url = $domain_base_url . "/" . $wpml_language_code . "/checkout/?fill_cart=" . $atts['id'];

        // Get currency symbol
        $currency_symbol = get_woocommerce_currency();
        
        // Your price CSS styles
        $style1 = 'class="my-discount-price" style="outline: none; text-decoration: none;"';
        $style2 = 'class="my-standard-price" style="text-decoration: line-through;"';

        // Formatting price settings (for the wc_price() function)
        $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(),
        );
        
        
        // Formatting html output with discount price with link like: <a href="https://www.ed...;" ins class="xxx"> 49€</a>
        if( ! empty( $sale_price ) && $sale_price != 0 && $sale_price < $regular_price )
            $html = "<del $style2>" . wc_price( $regular_price, $args ) . "</del> <a href=$checkout_url ins $style1>" . wc_price( $sale_price, $args ) . "</ins>"; // Sale price is set
        else
            $html = "<a href=$checkout_url ins $style1>" . wc_price( $sale_price, $args ) . "€</ins>"; // No sale price set (UNTESTED)

    }
    return $html;
 }
 add_shortcode( 'product_price', 'custom_price_shortcode_callback' );

CSS code:

.my-standard-price{
    font-size:200%;
}
.my-discount-price{
    font-size:150%;
}

Result:

result