返回
WooCommerce 商品列表页变量商品属性优化显示
php
2024-12-20 20:32:25
WooCommerce 商品列表页变量商品属性值的优化显示
在 WooCommerce 商店中,让客户快速了解商品的各种属性至关重要。直接在商品列表页,比如归档页和分类页上显示属性,可以提升购物体验,减少客户点击到具体商品页面去查看的次数。对于简单商品,提取并显示属性通常很容易;但对于变量商品,情况就要复杂一些,可能会遇到一些挑战。下面介绍如何处理变量商品属性值的优化显示,避免某些缺货变体属性也展示的问题。
问题分析
直接提取变量商品的属性值存在一个问题:这可能获取到所有变体的属性值,不论这个变体库存是多少,是“有货”还是“缺货”。当某个变体的库存为零时,在商品列表页仍可能显示出该变体的属性,给顾客造成困扰,误以为还能购买,造成用户体验不好。正确的做法是,只显示尚有库存的变体属性。
解决方案
解决思路是获取所有有库存的变体的属性,过滤掉库存为零的变体。主要使用 WooCommerce 的 get_available_variations()
方法。修改原来的 new_template_loop_product_meta()
函数来实现更精确的属性显示。
操作步骤如下:
-
获取所有变体: 使用
get_available_variations()
获取所有可用变体数据。 -
筛选属性: 遍历可用变体,提取指定属性。
-
去重并排序: 对提取的属性值进行去重和排序操作,确保相同属性值的多个变体仅显示一个值,并按自然排序规则排列。
-
显示属性: 将处理后的属性值展示在页面上。
改进代码
改进new_template_loop_product_meta()
函数中原来的输出:
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 );
// 替换成下面
if( $product->is_type('variable')){
show_variable_attribute( $product, $attr_title, $attr_name);
} else {
show_attribute( $product, $attr_title, $attr_name );
}
}
}
echo '</div>';
}
/* 新增函数: 专门处理可变商品的属性 */
function show_variable_attribute( $product, $attr_title, $attr_name ) {
$variations = $product->get_available_variations();
$attribute_values = [];
foreach ( $variations as $variation ) {
if( isset($variation['attributes']['attribute_' . $attr_name]) && $variation['is_in_stock'] == true){ // 确保该变体存在指定的属性值, 且该变体有库存
$attribute_value = $variation['attributes']['attribute_' . $attr_name];
if ( ! empty( $attribute_value ) ) {
$attribute_values[] = $attribute_value;
}
}
}
// 去重排序
$unique_values = array_unique( $attribute_values );
natsort($unique_values);
// 没有需要展示的属性时直接退出函数
if( empty($unique_values)){
return;
}
$attribute_string = '';
foreach( $unique_values as $term_name ){
$attribute_string .= sprintf('<span class="attr-term">%s</span>', $term_name);
}
printf( '<div class="custom-attributes-text">%s: %s</div>', $attr_title, $attribute_string);
}
/* 原有函数, 展示简单商品属性, 不做改动 */
function show_attribute( $product, $attr_title, $attr_name ) {
// ... 代码保持原样 ...
}
代码解释:
show_variable_attribute()
函数专门处理变量商品。它获取所有可购买的变体。对每个变体,判断该变体是否有指定的属性,且该变体有库存;满足条件后读取属性的值,把值加入到$attribute_values
数组中。去重、排序,最后显示在商品列表页。
安全建议
- 数据验证: 在显示属性值之前,进行数据验证,避免安全问题。
- 避免代码注入:
sprintf()
和esc_html()
函数可以提供保护,避免一些代码注入漏洞。在修改上述代码的时候,需要谨慎思考每个变量的用法,小心处理用户提供的数据。
优化
为了提升效率和代码可读性,还有几点优化措施:
- 缓存 : 如果属性很少变动,可以考虑对属性结果进行缓存,以减少数据库查询次数,加快页面加载速度。可以根据自身需要增加刷新缓存的机制。
- 按需加载 : 根据业务的实际需求来考虑按需加载的策略。比如用户翻页浏览很多产品数据的时候。
- 优化
$attrs_by_cats
变量 : 按实际业务要求维护此变量, 不要在此变量里填入无关的类目。避免引入过多无用计算量。