Show “Bulk discounts” badge for Woodmart theme
The Woodmart WooCommerce theme ships with its own product label system that overrides the default woocommerce_sale_flash hook with a custom function — woodmart_product_label. Because Woodmart manages the sale badge rendering entirely on its own, the standard approach used by Advanced Dynamic Pricing for WooCommerce to display bulk discount badges is bypassed and never fires.
This article provides a ready-to-use snippet that correctly replaces Woodmart’s label handler with a custom one that is fully compatible with Advanced Dynamic Pricing’s bulk discount rules — while preserving all of Woodmart’s other label features (Hot, New, Sold Out, product attributes, and percentage labels).
Code Sample
Add the following snippet to your theme’s functions.php or the Code Snippets plugin:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
add_action('init', function() { if ( false !== ( $priority = has_action( 'woocommerce_sale_flash','woodmart_product_label' ) ) ) { if ( remove_action( 'woocommerce_sale_flash','woodmart_product_label', $priority ) ) { add_action( 'woocommerce_sale_flash', 'wdp_product_label' ); } } }); function lmb_customize_badge( $badge ) { global $product; if ( ! function_exists( 'adp_functions' ) ) { return $badge; } $helper = adp_functions(); $rules = $helper->getActiveRulesForProduct( $product, 999.0 ); if ( empty( $rules ) ) { return $badge; } $changeBadgeText = false; foreach( $rules as $r ) { $adjustmentHandler = $r->getProductRangeAdjustmentHandler(); if ( $adjustmentHandler && $adjustmentHandler->getType() === $adjustmentHandler::TYPE_BULK ) { $changeBadgeText = true; break; } } if ( $changeBadgeText ) { return 'Bulk discounts'; // modify this line only } return $badge; } function wdp_product_label() { global $product; $output = array(); $product_attributes = woodmart_get_product_attributes_label(); $percentage_label = woodmart_get_opt( 'percentage_label' ); if ( $product->is_on_sale() ) { $percentage = ''; if ( $product->get_type() == 'variable' && $percentage_label ) { $available_variations = $product->get_variation_prices(); $max_percentage = 0; foreach( $available_variations['regular_price'] as $key => $regular_price ) { $sale_price = $available_variations['sale_price'][$key]; if ( $sale_price < $regular_price ) { $percentage = round( ( ( $regular_price - $sale_price ) / $regular_price ) * 100 ); if ( $percentage > $max_percentage ) { $max_percentage = $percentage; } } } $percentage = $max_percentage; } elseif ( ( $product->get_type() == 'simple' || $product->get_type() == 'external' ) && $percentage_label ) { $percentage = round( ( ( $product->get_regular_price() - $product->get_sale_price() ) / $product->get_regular_price() ) * 100 ); } if ( $percentage ) { $output[] = '<span class="onsale product-label">' . lmb_customize_badge( '-' . $percentage . '%' ) . '</span>'; } else { $output[] = '<span class="onsale product-label">' . lmb_customize_badge ( esc_html__( 'Sale', 'woodmart' ) ) . '</span>'; } } if( !$product->is_in_stock() ){ $output[] = '<span class="out-of-stock product-label">' . esc_html__( 'Sold out', 'woodmart' ) . '</span>'; } if ( $product->is_featured() && woodmart_get_opt( 'hot_label' ) ) { $output[] = '<span class="featured product-label">' . esc_html__( 'Hot', 'woodmart' ) . '</span>'; } if ( get_post_meta( get_the_ID(), '_woodmart_new_label', true ) && woodmart_get_opt( 'new_label' ) ) { $output[] = '<span class="new product-label">' . esc_html__( 'New', 'woodmart' ) . '</span>'; } if ( $product_attributes ) { foreach ( $product_attributes as $attribute ) { $output[] = $attribute; } } if ( $output ) { echo '<div class="product-labels labels-' . woodmart_get_opt( 'label_shape' ) . '">' . implode( '', $output ) . '</div>'; } } |
To customise the badge text, find this line and change
'Bulk discounts'to any string you prefer:
1 return 'Bulk discounts'; // modify this line only
Code Explained (for Developers)
The snippet is made up of three parts: a hook swap on init, a badge text override function, and a full label renderer that replaces Woodmart’s default one.
Part 1 — Hook swap (init action)
|
1 2 3 4 5 6 7 |
add_action( 'init', function() { if ( false !== ( $priority = has_action( 'woocommerce_sale_flash', 'woodmart_product_label' ) ) ) { if ( remove_action( 'woocommerce_sale_flash', 'woodmart_product_label', $priority ) ) { add_action( 'woocommerce_sale_flash', 'wdp_product_label' ); } } }); |
| Element | Description |
|---|---|
add_action( 'init', ... ) | Runs after WordPress and all plugins/themes have loaded, ensuring Woodmart’s hooks are already registered before we attempt to modify them. |
has_action( 'woocommerce_sale_flash', 'woodmart_product_label' ) | Checks whether Woodmart has registered woodmart_product_label on woocommerce_sale_flash. Returns the registered priority if found, or false if not. Storing the return value in $priority is essential — remove_action() requires the exact priority used during registration. |
remove_action( 'woocommerce_sale_flash', 'woodmart_product_label', $priority ) | Removes Woodmart’s label renderer from the hook. Returns true on success, ensuring we only register our replacement if the removal actually worked. |
add_action( 'woocommerce_sale_flash', 'wdp_product_label' ) | Registers our custom label renderer as the replacement. Only fires if the removal of Woodmart’s function succeeded — preventing duplicate labels. |
Part 2 — Badge text override (lmb_customize_badge)
|
1 |
function lmb_customize_badge( $badge ) { ... } |
| Element | Description |
|---|---|
function_exists( 'adp_functions' ) | Safety check — if Advanced Dynamic Pricing is not active or not loaded, the function returns the original badge unchanged to avoid fatal errors. |
adp_functions()->getActiveRulesForProduct( $product, 999.0 ) | Retrieves all currently active pricing rules for the product at a quantity of 999.0. Using a high quantity ensures bulk pricing tiers are included in the result. |
$r->getProductRangeAdjustmentHandler() | Accesses the adjustment handler for each rule, which describes the type of discount applied. |
$adjustmentHandler->getType() === $adjustmentHandler::TYPE_BULK | Checks whether the rule is specifically a bulk discount rule. If at least one bulk rule is found, $changeBadgeText is set to true and the loop exits early via break. |
return 'Bulk discounts' | The replacement badge text shown when a bulk rule is active. This is the only line you need to change to customise the displayed text. |
Fallback return $badge | If no bulk rule is found, the original badge string (e.g. -25% or Sale) is returned unchanged. |
Part 3 — Label renderer (wdp_product_label)
This function is a near-complete replacement for Woodmart’s woodmart_product_label(). It preserves all of Woodmart’s native label logic while routing the sale badge text through lmb_customize_badge() to enable bulk discount detection.
| Element | Description |
|---|---|
woodmart_get_product_attributes_label() | Woodmart function that returns any custom product attribute labels configured in the theme settings. Preserved as-is. |
woodmart_get_opt( 'percentage_label' ) | Reads the Woodmart theme option for whether to show percentage labels. The percentage calculation only runs if this is enabled. |
$product->is_on_sale() | Standard WooCommerce check — the sale label block only runs for products that are currently on sale (either via WooCommerce native prices or dynamic pricing rules). |
| Variable product branch | Loops all variation prices to find the highest discount percentage across all variations, matching Woodmart’s native behavior. |
| Simple / external branch | Calculates the discount percentage from get_regular_price() and get_sale_price() directly. |
lmb_customize_badge( '-' . $percentage . '%' ) | Passes the computed percentage string to the badge customiser. If a bulk rule is active, it replaces the percentage with 'Bulk discounts'; otherwise, the percentage is shown as-is. |
lmb_customize_badge( esc_html__( 'Sale', 'woodmart' ) ) | Same as above but for products with no percentage (e.g. products with a sale price but no regular price set). |
| Sold out, Hot, New labels | Woodmart’s native labels — fully preserved and output exactly as the original woodmart_product_label() function would. |
woodmart_get_opt( 'label_shape' ) | Reads the Woodmart label shape setting and applies it as a CSS class, maintaining theme styling consistency. |
Customising the Bulk Badge Text
Only one line needs to be changed to customise the label displayed for bulk discount products:
|
1 |
return 'Bulk discounts'; // modify this line only |
Replace 'Bulk discounts' with any text you prefer, for example:
|
1 2 3 |
return 'Volume pricing'; return 'Buy more, save more'; return __( 'Bulk discounts', 'your-text-domain' ); // translatable version |
How to Apply This Code
- Open Appearance → Theme File Editor in your WordPress admin, or open the Code Snippets plugin.
- Paste the full snippet into your active child theme’s
functions.php, or create a dedicated snippet. - Save and navigate to a shop or category page containing products with active bulk discount rules.
- Verify that the product label shows your custom bulk discount text instead of the default sale badge.
⚠️ Do not paste this into Woodmart’s parent theme files — it will be overwritten on theme updates. Always use a child theme or the Code Snippets plugin.
⚠️ If you already have custom code that modifies
woocommerce_sale_flash, check for conflicts — only one replacement handler should be registered at a time.
What Woodmart Labels Are Preserved?
This snippet is a full drop-in replacement for woodmart_product_label(). All of the following Woodmart labels continue to work exactly as before:
| Label | Condition |
|---|---|
| Sale / percentage badge | Product is on sale (is_on_sale()) |
| Bulk discounts (new) | Product has an active bulk pricing rule |
| Sold out | Product is out of stock |
| Hot | Product is featured + Woodmart “Hot label” option enabled |
| New | Product has _woodmart_new_label meta + Woodmart “New label” option enabled |
| Attribute labels | Custom product attribute labels configured in Woodmart |
When Should You Use This?
- You use the Woodmart theme and bulk discount labels are not appearing on product cards.
- Advanced Dynamic Pricing’s bulk rules are active, but the product badge still shows “Sale” or a percentage instead of a bulk discount indicator.
- You want to inform shoppers at a glance that a product has volume pricing available, directly on the product card.
- You need a Woodmart-compatible badge solution that doesn’t break the theme’s Hot, New, Sold Out, or attribute labels.