WooCommerce分类页可变商品属性显示异常修复请求
WooCommerce可变商品属性展示适配修改方案
原代码在简单商品上运行正常,但针对可变商品,当某个属性对应的变体售罄后,仍会展示全部属性选项。以下是修改后的代码,可实现仅显示有库存的属性值:
add_action( 'woocommerce_before_shop_loop_item_title', 'new_template_loop_product_meta', 20 ); function new_template_loop_product_meta() { global $product; $attrs_by_cats = [ 20 => [ 'pa_size' ], ]; $attr_list = [ 'Size' => 'pa_size', ]; if ( ! is_object( $product ) ) { $product = wc_get_product( get_the_id() ); } $cats = $product->get_category_ids(); if ( ! is_array( $cats ) ) { return; } $attrs = []; foreach ( $cats as $cat ) { if ( isset( $attrs_by_cats[ $cat ] ) ) { $attrs[] = $attrs_by_cats[ $cat ]; } } $allowed_attrs = array_unique( array_merge( [], ...$attrs ) ); echo '<div class="custom-attributes">'; foreach ( $attr_list as $attr_title => $attr_name ) { if ( in_array( $attr_name, $allowed_attrs, true ) ) { show_attribute( $product, $attr_title, $attr_name ); } } echo '</div>'; } /* Show attr */ function show_attribute( $product, $attr_title, $attr_name ) { if ( 'sku' === $attr_name ) { $attr = (string) esc_html( $product->get_sku() ); } else { // 针对可变商品处理库存筛选 if ( $product->is_type('variable') ) { $available_terms = []; $variations = $product->get_available_variations(); foreach ( $variations as $variation ) { // 检查变体是否有库存且可购买 if ( $variation['is_in_stock'] && $variation['is_purchasable'] ) { foreach ( $variation['attributes'] as $key => $term_slug ) { if ( 'attribute_' . $attr_name === $key ) { $term = get_term_by('slug', $term_slug, $attr_name); if ( $term ) { $available_terms[] = $term->name; } } } } } // 去重并整理属性值 $available_terms = array_unique( $available_terms ); if ( empty($available_terms) ) { return; } $attr_arr = []; foreach ( $available_terms as $term_name ) { $attr_arr[] = sprintf('<span class="attr-term">%s</span>', $term_name); } $attr = implode(' ', $attr_arr); } else { // 简单商品保留原有逻辑 $attr = $product->get_attribute( $attr_name ); if ( ! $attr ) { return; } $attr = explode( ', ', $attr ); $attr_arr = []; foreach ( $attr as $term_name ) { $attr_arr[] = sprintf('<span class="attr-term">%s</span>', $term_name); } $attr = implode(' ', $attr_arr); } } if ( '' === $attr ) { return; } printf( '<div class="custom-attributes-text">%s: %s</div>', $attr_title, $attr); }
关键修改说明
- 新增可变商品类型判断:通过
$product->is_type('variable')区分商品类型,针对可变商品单独处理 - 筛选有库存的变体:遍历商品的可用变体,仅保留
is_in_stock和is_purchasable为true的变体 - 提取有效属性值:从符合条件的变体中提取对应属性的术语名称,去重后再格式化为前端展示的HTML结构
- 保留简单商品原有逻辑:确保非可变商品的展示不受影响
内容的提问来源于stack exchange,提问作者Dmitry
相关产品推荐
相关产品推荐

