WooCommerce存档页产品循环:添加变体选择下拉与加购按钮
在WooCommerce存档页为可变产品添加单属性选择及加入购物车按钮
直接替换你现有的产品循环代码,以下是完整实现方案:
<?php while ( have_posts() ): the_post(); ?> <?php $product = wc_get_product( get_the_ID() ); // 获取产品属性(针对可变产品) $attributes = $product->get_variation_attributes(); // 默认取第一个属性(单属性场景) $selected_attr = !empty($attributes) ? key($attributes) : ''; ?> <div class="post-item" data-id="<?php the_id(); ?>"> <a href="<?php the_permalink(); ?>" class="post-link"> <div class="post-image"> <?php echo get_the_post_thumbnail(); ?> </div> <div class="post-content"> <h3><?php the_title(); ?></h3> <div class="address"> <span class="icon-post"><img src="https://inmemoryoflife.com/wp-content/uploads/2020/07/pin-1.svg" alt=""></span><?php echo get_field('crematorium_address'); ?> </div> <div class="price"> <span class="icon-post"><img src="https://inmemoryoflife.com/wp-content/uploads/2020/06/pound-sterling.svg" alt=""></span> <?php // 可变产品显示初始价格区间,后续JS动态更新 if ($product->is_type('variable')) { echo wc_price($product->get_variation_price('min', true)) . ' - ' . wc_price($product->get_variation_price('max', true)); } else { echo $product->get_price_html(); } ?> </div> <div class="product-actions"> <?php if ($product->is_type('variable') && !empty($selected_attr)): ?> <!-- 可变产品:属性下拉 + 加购按钮 --> <select class="variation-select" data-product-id="<?php echo $product->get_id(); ?>"> <option value="">请选择选项</option> <?php // 遍历属性值,关联对应变体ID foreach ($attributes[$selected_attr] as $attr_value) { $variation_id = wc_get_product_variation_id_by_attributes($product->get_id(), array($selected_attr => $attr_value)); if ($variation_id) { $variation = wc_get_product($variation_id); $price_html = $variation->get_price_html(); $stock_status = $variation->is_in_stock() ? 'in-stock' : 'out-of-stock'; echo '<option value="' . $variation_id . '" data-price="' . htmlspecialchars($price_html) . '" data-stock="' . $stock_status . '">' . $attr_value . '</option>'; } } ?> </select> <form class="add-to-cart-form" method="post" enctype="multipart/form-data"> <input type="hidden" name="product_id" value="<?php echo $product->get_id(); ?>"> <input type="hidden" name="variation_id" value="" class="variation-id"> <input type="hidden" name="quantity" value="1"> <?php wp_nonce_field('woocommerce-add-to-cart', 'woocommerce-add-to-cart-nonce'); ?> <button type="submit" class="add-to-cart-btn" disabled>加入购物车</button> </form> <?php elseif ($product->is_type('simple')): ?> <!-- 简单产品:直接显示加购按钮 --> <form class="add-to-cart-form" method="post" enctype="multipart/form-data"> <input type="hidden" name="add-to-cart" value="<?php echo $product->get_id(); ?>"> <input type="hidden" name="quantity" value="1"> <?php wp_nonce_field('woocommerce-add-to-cart', 'woocommerce-add-to-cart-nonce'); ?> <button type="submit" class="add-to-cart-btn" <?php echo !$product->is_in_stock() ? 'disabled' : ''; ?>> <?php echo $product->is_in_stock() ? '加入购物车' : '缺货'; ?> </button> </form> <?php else: ?> <!-- 其他产品类型:保留原跳转按钮 --> <div class="button-post"> <span>View Details</span> </div> <?php endif; ?> </div> </div> </a> </div> <?php endwhile; ?> <!-- 变体切换逻辑脚本 --> <script> document.addEventListener('DOMContentLoaded', function() { const variationSelects = document.querySelectorAll('.variation-select'); variationSelects.forEach(select => { select.addEventListener('change', function() { const selectedOption = this.options[this.selectedIndex]; const priceContainer = this.closest('.post-item').querySelector('.price span:last-child'); const addToCartBtn = this.closest('.product-actions').querySelector('.add-to-cart-btn'); const variationIdInput = this.closest('.product-actions').querySelector('.variation-id'); if (selectedOption.value) { // 更新价格显示 priceContainer.innerHTML = selectedOption.dataset.price; // 设置选中的变体ID variationIdInput.value = selectedOption.value; // 根据库存状态切换按钮状态 if (selectedOption.dataset.stock === 'in-stock') { addToCartBtn.disabled = false; addToCartBtn.textContent = '加入购物车'; } else { addToCartBtn.disabled = true; addToCartBtn.textContent = '缺货'; } } else { // 重置为初始价格区间 const productId = this.dataset.productId; fetch(window.location.origin + '/wp-json/wc/v3/products/' + productId) .then(res => res.json()) .then(data => { priceContainer.innerHTML = data.price_html; }); addToCartBtn.disabled = true; addToCartBtn.textContent = '加入购物车'; variationIdInput.value = ''; } }); }); }); </script>
关键说明
- 产品类型适配:针对可变产品、简单产品分别处理,其他产品类型保留原跳转逻辑
- 单属性指定:默认取可变产品的第一个属性,若需指定特定属性,可将
$selected_attr = !empty($attributes) ? key($attributes) : '';改为目标属性的slug(如$selected_attr = 'pa_size';) - 动态状态同步:通过JS监听下拉选择,实时更新价格显示、按钮可用性及变体ID
- 合规性保障:保留WooCommerce的nonce验证字段,确保加购请求合法有效
- 库存状态判断:自动检测变体库存,缺货时禁用加购按钮并提示状态
内容的提问来源于stack exchange,提问作者Matt Stafford
相关产品推荐
相关产品推荐

