Search code examples
phpwordpressloopswoocommercehook-woocommerce

Customize WooCommerce single products but not on other product loops


I've got some custom code in my woocommerce price hook and it makes the change everywhere on the site. I'd like to only have it affect the product page (all of our products are simple products currently).

While designing the product collections page the same snippet below is showing up there that shows up on the product page. I tried to apply an if statement to only make the change to woocommerce_format_sale_price when it was on a product page, but that doesn't seem to have worked.

Any advice?

function add_discount_woocommerce_format_sale_price( $price, $regular_price, $sale_price ){
    $percentage = round( ( $regular_price - $sale_price ) / $regular_price * 100 ).'%';

    $price = '<ins>' . ( is_numeric( $sale_price ) ? wc_price( $sale_price ) : $sale_price ) . '</ins> <del>' . ( is_numeric( $regular_price ) ? wc_price( $regular_price ) : $regular_price ) . '</del><br><span class="plan-atc">*Payment Plan Available at Checkout</span><br> <span class="below-atc">Add to cart today, get ' . $percentage . __( ' off </span>', 'text-domain' );
    return $price;
}
add_filter( 'woocommerce_format_sale_price', 'add_discount_woocommerce_format_sale_price', 99, 3 );

Thanks!


Solution

  • You could use is_product() conditional function, but it's not enough as there is other product loops on single product pages, like upsells products, related products…

    To make your function active only for single products pages (and not on other product loops), use the following:

    add_filter( 'woocommerce_format_sale_price', 'display_percentage_discount_on_sale_price_format', 99, 3 );
    function display_percentage_discount_on_sale_price_format( $price, $regular_price, $sale_price ){
        global $woocommerce_loop;
    
        // Only on single product pages (and not on other product loops)
        if( is_product() && isset($woocommerce_loop['name']) && empty($woocommerce_loop['name']) ) {
    
            $percentage = round( ( $regular_price - $sale_price ) / $regular_price * 100 ).'%';
    
            $price = '<ins>' . ( is_numeric( $sale_price ) ? wc_price( $sale_price ) : $sale_price ) . '</ins> <del>' . ( is_numeric( $regular_price ) ? wc_price( $regular_price ) : $regular_price ) . '</del><br><span class="plan-atc">*Payment Plan Available at Checkout</span><br> <span class="below-atc">Add to cart today, get ' . $percentage . __( ' off </span>', 'text-domain' );
        }
        return $price;
    }
    

    Now there is a missing closing </span>. Try the following revisited code instead:

    add_filter( 'woocommerce_format_sale_price', 'display_percentage_discount_on_sale_price_format', 99, 3 );
    function display_percentage_discount_on_sale_price_format( $price, $regular_price, $sale_price ){
        global $woocommerce_loop;
    
        // Only on single product pages (and not on other product loops)
        if( is_product() && isset($woocommerce_loop['name']) && empty($woocommerce_loop['name']) ) {
            $percentage  = round( ( $regular_price - $sale_price ) / $regular_price * 100 ).'%';
            $text_end    = sprintf( __("Add to cart today, get %s off", "woocommerce"), $percentage );
            $text_prefix = sprintf( ' <br><span class="plan-atc">%s</span> <br><span class="below-atc">%s</span>',
            __("Payment Plan Available at Checkout", "woocommerce"), $text_end );
    
            $price_html = '<ins>' . ( is_numeric( $sale_price ) ? wc_price( $sale_price ) : $sale_price ) . '</ins> <del>' . ( is_numeric( $regular_price ) ? wc_price( $regular_price ) : $regular_price ) . '</del>' . $text_prefix;
        }
        return $price_html;
    }
    

    Code goes in functions.php file of the active child theme (or active theme). Tested and works.