在WooCommerce精选产品区块中显示产品变体
在WooCommerce精选产品区块显示产品变体的解决方案
问题说明
我尝试在WooCommerce精选产品区块中展示产品变体,目前商店与归档页面的变体显示方案运行正常,但在使用精选产品区块时,原代码无法成功加载变体。原代码如下:
/** * Display product variations in WooCommerce Hand-picked Products block. * * @param array $attributes Block attributes. * @param string $content Block content. * @return string */ function custom_display_product_variations_in_handpicked_block($attributes, $content) { // Check if the block is a Hand-picked Products block if ($attributes['name'] === 'woocommerce/handpicked-products') { // Get the list of hand-picked product IDs $product_ids = ! empty($attributes['products']) ? $attributes['products'] : array(); if (! empty($product_ids)) { $content .= '<ul class="product-variations-list">'; foreach ($product_ids as $product_id) { // Get product variations $variations = wc_get_product_variations($product_id); if ($variations) { foreach ($variations as $variation) { $variation_id = $variation->get_id(); $variation_name = wc_get_formatted_variation($variation->get_variation_attributes(), true); $variation_price = $variation->get_price_html(); // Display variation details $content .= '<li>'; $content .= '<a href="' . esc_url(get_permalink($variation_id)) . '">' . esc_html($variation_name) . '</a>'; $content .= '<span class="variation-price">' . $variation_price . '</span>'; $content .= '</li>'; } } } $content .= '</ul>'; } } return $content; } add_filter('render_block', 'custom_display_product_variations_in_handpicked_block', 10, 2);
问题分析
原代码存在以下关键问题:
wc_get_product_variations()返回的是数组而非产品对象,直接调用->get_id()会触发错误- 直接在区块末尾追加变体列表,导致变体与对应产品分离,布局混乱
- 未校验产品类型,非可变产品也会被处理
修正后的代码
/** * 在WooCommerce精选产品区块中显示产品变体 * * @param string $content 区块渲染内容 * @param array $block 区块数据 * @return string */ function custom_display_variations_in_handpicked_block($content, $block) { // 校验是否为精选产品区块 if ($block['blockName'] !== 'woocommerce/handpicked-products') { return $content; } // 获取选中的产品ID列表 $product_ids = $block['attrs']['products'] ?? []; if (empty($product_ids)) { return $content; } foreach ($product_ids as $product_id) { $product = wc_get_product($product_id); // 仅处理可变产品 if (!$product || !$product->is_type('variable')) { continue; } // 获取所有可用变体(排除不可售/缺货变体) $variations = $product->get_available_variations(); if (empty($variations)) { continue; } // 构建变体列表HTML $variation_html = '<ul class="product-variations-list">'; foreach ($variations as $variation) { $variation_obj = wc_get_product($variation['variation_id']); $variation_name = wc_get_formatted_variation($variation['attributes'], true); $variation_price = $variation_obj->get_price_html(); $variation_link = get_permalink($variation['variation_id']); $variation_html .= sprintf( '<li><a href="%s">%s</a><span class="variation-price">%s</span></li>', esc_url($variation_link), esc_html($variation_name), $variation_price ); } $variation_html .= '</ul>'; // 将变体列表插入对应产品的容器内,保证布局一致性 $product_selector = sprintf('[data-product-id="%d"]', $product_id); $content = preg_replace('/(' . preg_quote($product_selector, '/') . '.+?<\/div>)/s', '$1' . $variation_html, $content); } return $content; } add_filter('render_block', 'custom_display_variations_in_handpicked_block', 10, 2);
代码改进点
- 先通过
wc_get_product()获取产品对象,校验是否为可变产品后再处理 - 使用
get_available_variations()获取可用变体,避免展示不可售的选项 - 通过正则匹配将变体列表嵌入对应产品的容器中,保证变体与产品关联展示
- 增加数据合法性校验,避免空值或错误对象导致的报错
内容的提问来源于stack exchange,提问作者Chris Grant
相关产品推荐
相关产品推荐

