WooCommerce购物车添加Details字段展示预订时长及别墅每晚价格
Got it, let's tackle this problem for your villa booking site built with WooCommerce + WooCommerce Bookings. You want to add a "Details" field in the cart that shows the booking duration and nightly price for each villa, right? Here's how you can do this properly, following WooCommerce best practices:
Method 1: Use WooCommerce Hooks (Recommended)
This approach avoids modifying theme templates (so you won't lose changes when updating your theme). We'll use the woocommerce_get_item_data filter to inject our custom "Details" field into the cart item metadata.
Add this code to your theme's functions.php file or a custom plugin:
add_filter( 'woocommerce_get_item_data', 'add_booking_duration_nightly_price_to_cart', 10, 3 ); function add_booking_duration_nightly_price_to_cart( $item_data, $cart_item, $cart_item_key ) { // Check if the product is a booking type $product = wc_get_product( $cart_item['product_id'] ); if ( ! $product || ! $product->is_type( 'booking' ) ) { return $item_data; } // Get the booking object associated with the cart item $booking = wc_get_booking( $cart_item['booking_id'] ); if ( ! $booking ) { return $item_data; } // Format booking duration (e.g., "3 Nights" instead of "3 night") $duration = $booking->get_duration(); $duration_unit = ucfirst( $booking->get_duration_unit() ); $duration_text = sprintf( '%d %s', $duration, $duration > 1 ? $duration_unit . 's' : $duration_unit ); // Get nightly price (adjust this part if your pricing is tied to specific resources) if ( $booking->has_resources() ) { // If using resources with block costs, get the first resource's cost $resources = $booking->get_resources(); $resource = reset( $resources ); $nightly_price = wc_price( $resource->get_cost() ); } else { // Fallback to product's per-night cost $nightly_price = wc_price( $product->get_cost_per_night() ); } // Build the Details text $details_content = sprintf( 'Duration: %s | Nightly Price: %s', $duration_text, $nightly_price ); // Add the Details field to the cart item data $item_data[] = array( 'key' => 'Details', 'value' => $details_content, 'display' => $details_content, ); return $item_data; }
Key Notes for This Method:
- Resource Pricing Adjustment: If your villa's nightly price is tied to specific resources (with block costs), the code checks for resources and pulls the cost from the first associated resource. Adjust the resource logic if you need to handle multiple resources.
- Formatting: The duration text is automatically pluralized (e.g., "1 Night" vs "2 Nights") for better user experience.
- Compatibility: This works with default WooCommerce cart templates and most well-coded themes.
Method 2: Modify Cart Template (For Custom Theme Setups)
If you need full control over the HTML layout of the Details field, you can modify your theme's cart template.
- Copy the
cart/cart-item-data.phptemplate from the WooCommerce plugin folder to your theme'swoocommerce/cart/directory (create the folder if it doesn't exist). - Add this code to the copied template, where you want the "Details" field to appear:
<?php // Get product and booking data $product = wc_get_product( $cart_item['product_id'] ); if ( $product && $product->is_type( 'booking' ) && $booking = wc_get_booking( $cart_item['booking_id'] ) ) : $duration = $booking->get_duration(); $duration_unit = ucfirst( $booking->get_duration_unit() ); $duration_text = sprintf( '%d %s', $duration, $duration > 1 ? $duration_unit . 's' : $duration_unit ); // Get nightly price (adjust for resources as needed) $nightly_price = $booking->has_resources() ? wc_price( reset( $booking->get_resources() )->get_cost() ) : wc_price( $product->get_cost_per_night() ); ?> <div class="booking-custom-details"> <strong><?php esc_html_e( 'Details', 'woocommerce' ); ?>:</strong> <?php echo esc_html( $duration_text ); ?> | <?php echo wp_kses_post( $nightly_price ); ?> </div> <?php endif; ?>
Important Reminder:
When modifying templates, always keep a backup and re-apply changes if you update your theme. The hook method is preferred for long-term maintainability.
内容的提问来源于stack exchange,提问作者Matthieu Verneau

