如何在WooCommerce前端展示Block Count Range Type及优化动态附加成本字段?
Hey there! Let's break down how to solve your WooCommerce Bookings needs step by step.
1. Display Block Count Range Type & Additional Costs on single-product.php
To show the block count range details (including extra costs like daily insurance, surcharges, etc.) on your product page, you can add custom code directly to your single-product.php template (or better yet, use a child theme to avoid losing changes on updates).
Here's a practical code snippet you can drop in the appropriate section of your template (e.g., right after the product price):
global $product; // Only run this for booking products if ($product->is_type('booking')) { $booking_settings = get_post_meta($product->get_id(), '_wc_booking_settings', true); // Check if block count cost ranges exist if (isset($booking_settings['cost_block_count']['ranges']) && !empty($booking_settings['cost_block_count']['ranges'])) { echo '<div class="booking-cost-breakdown" style="margin: 20px 0; padding: 15px; border: 1px solid #eee;">'; echo '<h3 style="margin-top:0;">预订成本明细</h3>'; echo '<ul style="list-style: disc; margin-left: 20px;">'; foreach ($booking_settings['cost_block_count']['ranges'] as $range) { $from = $range['from'] ?? 1; $to = $range['to'] ?? '不限'; $base_cost = wc_price($range['cost']); // Output range base info echo "<li><strong>时段范围:{$from} - {$to} 个单位</strong>"; echo "<ul style='list-style: circle; margin-left: 20px; margin-top: 5px;'>"; echo "<li>基础费用:{$base_cost}</li>"; // Output additional costs if they exist if (isset($range['additional_costs']) && !empty($range['additional_costs'])) { // Map your cost keys to user-friendly labels (adjust these to match your setup) $cost_labels = [ 'daily_insurance' => '每日保险费', 'service_surcharge' => '附加服务费', 'cleaning_fee' => '清洁费' ]; foreach ($range['additional_costs'] as $cost_key => $cost_value) { $label = $cost_labels[$cost_key] ?? ucfirst(str_replace('_', ' ', $cost_key)); echo "<li>{$label}:" . wc_price($cost_value) . "</li>"; } } echo '</ul></li>'; } echo '</ul></div>'; } }
Notes:
- Adjust the
$cost_labelsarray to match the actual keys you used for your additional costs in the Block Count Cost Field settings. - Style the output with CSS to match your theme's design (the inline styles are just for quick testing).
2. Better Dynamic Additional Cost Handling
If you need more flexibility than the built-in Block Count Range fields offer, here are two optimized approaches:
Option 1: Dynamic Cost Calculation via Hooks
Use WooCommerce Bookings' native hooks to calculate additional costs based on booking details (like duration, date, or customer type) instead of relying on fixed ranges.
// Add dynamic costs to booking total add_filter('woocommerce_booking_calculated_cost', 'calculate_dynamic_booking_addons', 10, 3); function calculate_dynamic_booking_addons($total_cost, $booking, $product) { $duration = $booking->get_duration(); // Get number of booking blocks/days // 1. Daily insurance fee ($5 per day) $insurance_fee = 5 * $duration; $total_cost += $insurance_fee; // 2. Weekend surcharge ($20 per day for Sat/Sun) $start_date = $booking->get_start(); if (date('N', strtotime($start_date)) >= 6) { // Check if start date is weekend $weekend_surcharge = 20 * $duration; $total_cost += $weekend_surcharge; } // 3. Percentage-based service fee (10% of base cost) $service_fee = $total_cost * 0.10; $total_cost += $service_fee; return $total_cost; }
Option 2: Admin-Manageable Custom Fields
Make additional costs editable from the product admin page (no code changes needed for updates) by adding custom meta fields, then use those values in your dynamic calculations.
First, add the fields to the booking product edit screen:
// Add custom fields to booking product settings add_action('woocommerce_product_options_general_product_data', 'add_booking_addon_fields'); function add_booking_addon_fields() { global $post; $product = wc_get_product($post->ID); if ($product && $product->is_type('booking')) { echo '<div class="options_group">'; woocommerce_wp_text_input([ 'id' => '_daily_insurance', 'label' => '每日保险费', 'type' => 'number', 'custom_attributes' => ['step' => '0.01', 'min' => '0'], 'desc_tip' => true, 'description' => '设置每天的保险费用' ]); woocommerce_wp_text_input([ 'id' => '_service_fee_percent', 'label' => '服务费比例 (%)', 'type' => 'number', 'custom_attributes' => ['step' => '0.01', 'min' => '0'], 'desc_tip' => true, 'description' => '基于基础费用的服务费比例' ]); echo '</div>'; } } // Save custom field values add_action('woocommerce_process_product_meta_booking', 'save_booking_addon_fields'); function save_booking_addon_fields($post_id) { if (isset($_POST['_daily_insurance'])) { update_post_meta($post_id, '_daily_insurance', sanitize_text_field($_POST['_daily_insurance'])); } if (isset($_POST['_service_fee_percent'])) { update_post_meta($post_id, '_service_fee_percent', sanitize_text_field($_POST['_service_fee_percent'])); } }
Then update the calculation hook to use these admin-set values:
add_filter('woocommerce_booking_calculated_cost', 'use_admin_set_addon_costs', 10, 3); function use_admin_set_addon_costs($total_cost, $booking, $product) { $duration = $booking->get_duration(); // Get admin-set values $daily_insurance = get_post_meta($product->get_id(), '_daily_insurance', true); $service_fee_percent = get_post_meta($product->get_id(), '_service_fee_percent', true); // Apply insurance fee if ($daily_insurance) { $total_cost += floatval($daily_insurance) * $duration; } // Apply service fee if ($service_fee_percent) { $service_fee = $total_cost * (floatval($service_fee_percent) / 100); $total_cost += $service_fee; } return $total_cost; }
Why This Is Better:
- Flexibility: Costs adjust based on real booking data (dates, duration) instead of fixed ranges.
- Maintainability: Admins can update costs without touching code.
- Scalability: Easily add new conditional costs (e.g., holiday surcharges, group discounts) later.
内容的提问来源于stack exchange,提问作者KrnRbts

