WooCommerce产品及归档页:满50美元显示免运费徽章问题
Got it, let's fix this properly. The issue with your existing code is that it's not covering all product types and edge cases like products without inventory management enabled. Here's a robust solution that handles every scenario—variable products, sale items, variable sale items, and even products without stock tracking—by always using the lowest active purchasable price as the threshold check.
Step 1: Function to Get the Lowest Valid Price
First, we need a reliable way to pull the lowest price for any product, regardless of type or stock status. This uses WooCommerce's native methods to avoid edge-case bugs:
// Get the lowest active purchasable price for any WooCommerce product function get_product_lowest_price( $product ) { // Ensure we're working with a valid WC_Product object if ( ! is_a( $product, 'WC_Product' ) ) { $product = wc_get_product( $product ); } if ( ! $product ) return 0; // For variable products: get the minimum price of all purchasable variations (including sales) if ( $product->is_type( 'variable' ) ) { $price = $product->get_variation_price( 'min', true ); } // For simple/grouped/external products: get the active price (sale price if available, else regular) else { $price = $product->get_price(); } // Convert to float to prevent string comparison errors return (float) $price; }
This function automatically handles:
- Variable products (pulls the cheapest variation that's purchasable)
- Sale items (uses the sale price instead of regular price)
- Products without inventory tracking (WooCommerce's
get_price()method still returns the correct value here)
Step 2: Badge Display Function
Next, we'll create the function that checks the price threshold and outputs the badge:
// Display "Free Delivery" badge when price meets threshold function display_free_delivery_badge() { global $product; $min_price = get_product_lowest_price( $product ); $free_delivery_threshold = 50; // Adjust this to your desired threshold // Only show the badge if the product is purchasable AND meets the price threshold if ( $min_price > $free_delivery_threshold && $product->is_purchasable() ) { echo '<span class="free-delivery-badge">Free Delivery</span>'; } }
The $product->is_purchasable() check ensures we don't show the badge for products that can't be bought (like out-of-stock items that don't allow backorders).
Step 3: Hook the Badge to Your Store
Now we'll attach the badge to both product loops (shop pages, category pages) and single product pages using WooCommerce hooks:
// Add badge to product loops (shop, categories, etc.) add_action( 'woocommerce_after_shop_loop_item_title', 'display_free_delivery_badge', 15 ); // Add badge to single product page add_action( 'woocommerce_single_product_summary', 'display_free_delivery_badge', 15 );
The priority 15 ensures the badge appears right after the product price (adjust if you want it in a different position).
Step 4: Style the Badge
Add this CSS to your theme's custom CSS area or child theme's style.css to make the badge look polished:
.free-delivery-badge { background-color: #27ae60; color: #ffffff; padding: 3px 7px; border-radius: 3px; font-size: 0.85em; font-weight: 600; display: inline-block; margin-left: 6px; } /* Adjust position for product loops */ .woocommerce ul.products li.product .free-delivery-badge { margin-top: 5px; display: block; margin-left: 0; }
Feel free to tweak the colors, padding, or font to match your theme.
Scenarios This Fixes
- ✅ Simple products (with or without sale prices)
- ✅ Variable products (including those with sale-priced variations)
- ✅ Products without inventory management enabled
- ✅ Out-of-stock products (won't show the badge if they're not purchasable)
- ✅ Grouped/external products
内容的提问来源于stack exchange,提问作者Cray

