How can I show the percentage discount for a product?

If you're using a Sale or Percentage Sale Price Type on products, you can show the "before/after" price using the built-in [[+price_rendered]] placeholder. Out of the box, that will show the old price with a strike through it, and the formatted price followed by it. That also uses Offer microdata for search engines.

For example, having a product with a regular price of €29 on sale for €19 may resemble the following markup:

<span class="product-price__container product-price__discounted" itemscope itemtype="https://schema.org/Offer">
    <meta itemprop="priceCurrency" content="EUR" />
    <meta itemprop="priceValidUntil" content="2022-04-07" />

    <del class="product-price__old">€29.00</del>

    <span class="product-price" itemprop="price" content="19.00">€19.00</span>
    <span class="product-discount">53% korting</span>
</span>

To show how big of a saving that is, we need some math, and the frontend/price.twig template that actually powers the price_rendered placeholder.

The basic math to calculate a percentage difference is "(new - old) / old * 100". As that returns a negative number for a discount, we're actually multiplying by -100. In twig, that looks like this:

{% set discount = 0 %}
{% if regular.integer > 0 %}
    {% set discount = ((integer - regular.integer) / regular.integer) * -100 %}
{% endif %}
{% if discount > 0 %}
    <span class="product-discount">Save {{ discount|number_format(0) }}%!</span>
{% endif %}

Add that to frontend/price.twig where you'd like it to show up, and make sure you're using [[+price_rendered]] in your templates. 

What about showing the discount percentage in the cart?

It's a little more complex in the cart as you may have a certain number of quantities. Commerce does not currently store the "regular total" on an order item - only the actually applied price per product, and the various calculated totals.

However, as you do have access to the product via item.product, you can expand the single-product price rendering to include the regular price and a calculated percentage with something like this:

{% set discount = 0 %}
{% set regular = item.product ? item.product.regular_price : 0 %}
{% if regular > 0 %}
    {% set discount = ((item.price - regular) / regular) * -100 %}
{% endif %}
{% if discount > 0 %}
    <del class="product-price__old">
        {{ item.product.regular_price_formatted }}
    </del>
    <span class="product-discount">Save {{ discount|number_format(0) }}%!</span>
{% endif %}

Still need help? Send us an email Send us an email