WooCommerce:在特定分类中显示缺货商品的实战教程
在使用WooCommerce构建电商网站时,你可能遇到过这样的场景:默认设置会隐藏所有“缺货”的商品,但这对于某些特殊分类(如“预售商品”或“即将到货”)来说并不适用。你需要让客户在特定分类下看到缺货商品,以便进行预订或了解商品动向。本文将提供几种实现这一功能的实战方法。
理解缺货商品的默认行为
WooCommerce后台的“产品”设置中,有一个选项可以全局控制缺货商品的可见性。当你启用“隐藏库存不足的商品”后,所有库存为零的商品都会从商品列表和搜索结果中消失。虽然这能避免顾客购买缺货商品,但同时也堵死了展示那些“即将补货”或“可预订”商品的可能性。
我们的目标是在不改变全局设置的前提下,仅对特定分类(或分类集合)中的商品,让它们即使缺货也能正常显示在前台。
方法一:使用functions.php自定义查询
这是最直接、最可控的方法。通过修改WooCommerce的主查询(WP_Query),我们可以指定某些分类ID或分类Slug,在这些分类中不执行“隐藏缺货”的过滤。
下面是一个代码示例,将代码添加到主题的 functions.php 文件或一个自定义功能插件中:
// 定义需要显示缺货商品的分类ID(可以在后台查看分类ID)
function custom_show_out_of_stock_in_category( $query, $query_vars ) {
// 确保只在WooCommerce主循环中生效,且不是后台
if ( ! is_admin() && $query->is_main_query() && ( is_shop() || is_product_category() ) ) {
// 在这里定义你想要显示缺货商品的分类Slug列表
$allowed_categories = array( 'pre-order', 'coming-soon' );
// 检查当前请求是否属于这些分类
$current_category = get_queried_object();
if ( is_a( $current_category, 'WP_Term' ) && $current_category->taxonomy === 'product_cat' ) {
if ( in_array( $current_category->slug, $allowed_categories ) ) {
// 移除WooCommerce隐藏缺货产品的过滤条件
remove_filter( 'posts_clauses', array( 'WC_Query', 'filter_out_of_stock_products' ) );
}
}
}
return $query;
}
add_action( 'pre_get_posts', 'custom_show_out_of_stock_in_category', 20, 1 );这段代码的工作原理是:在WordPress执行商品查询前,检查当前访问的分类是否属于我们预设的分类Slug列表。如果是,则移除WooCommerce自带的过滤缺货商品的函数。这样,所有缺货商品就会正常出现在该分类列表中。
如何获取分类Slug?
你可以在WooCommerce后台的“产品 > 分类”中找到每个分类。分类Slug就是URL中显示的那部分纯英文标识。如果找不到,你也可以直接在浏览器地址栏中查看分类页面的URL,最后一部分就是它的Slug。
方法二:利用CSS和查询参数(备用方案)
如果不想修改核心代码,另一种思路是:先在WooCommerce设置中关闭“隐藏缺货商品”,让所有缺货商品都显示。然后通过CSS或JavaScript,在那些不需要显示缺货商品的分类中,将它们隐藏起来。这种方法的逻辑与第一种相反,适用于对缺货商品有统一处理需求的情况。
通过添加CSS类实现
WooCommerce商品列表中的每个商品都带有分类相关的class。例如,属于“默认分类”的商品会有 .product_cat-default 这样的class。我们可以利用这个特性,为所有商品显示缺货标志,然后利用CSS在非目标分类中隐藏它们。
/* 默认隐藏所有缺货商品 */
.product.outofstock {
display: none;
}
/* 但允许在特定分类中显示 */
.product_cat-pre-order.product.outofstock,
.product_cat-coming-soon.product.outofstock {
display: block; /* 或者 inline-block */
}将上面的CSS代码添加到“外观 > 自定义 > 额外CSS”中。你需要将 product_cat-pre-order 中的 pre-order 替换为你的实际分类Slug。
方法三:使用产品可见性筛选器
WooCommerce提供了一个更精细的钩子 woocommerce_product_is_visible,允许你针对每个产品判断其可见性。这种方法的优势在于可以对条件进行更复杂的逻辑判断。
// 根据产品分类和库存状态控制可见性
function custom_product_visibility( $visible, $product_id ) {
// 获取产品对象
$product = wc_get_product( $product_id );
// 如果是缺货产品,才需要进一步判断
if ( $product && ! $product->is_in_stock() ) {
// 获取该产品的所有分类
$categories = wp_get_post_terms( $product_id, 'product_cat', array( 'fields' => 'slugs' ) );
// 定义允许显示的分类
$allowed = array( 'pre-order', 'coming-soon' );
// 如果有任何允许的分类,则返回可见(true)
$has_allowed = array_intersect( $categories, $allowed );
if ( ! empty( $has_allowed ) ) {
return true;
} else {
// 不属于允许的分类,且缺货,则不可见
return false;
}
}
// 不缺货的产品正常显示
return $visible;
}
add_filter( 'woocommerce_product_is_visible', 'custom_product_visibility', 10, 2 );这段代码会遍历每一个产品。如果产品是缺货状态,它会检查该产品是否属于我们指定的分类Slug列表。只有属于指定分类的缺货产品才会被设为可见,其他的缺货产品则被隐藏。
总结与注意事项
选择哪种方法?
- 方法一(过滤器)是最优解,它逻辑清晰,只影响查询本身,性能损耗小。缺点是如果你修改了分类的Slug,需要同步更新代码中的 $allowed_categories 数组。
- 方法二(CSS)简单快捷,适合不擅长代码的用户。但它默认所有缺货商品都显示,然后再隐藏,有点“先开后关”的味道。如果网站缺货商品很多,可能会影响页面加载和体验。
- 方法三(可见性钩子)非常灵活,能精确控制每一个产品的可见性。但它会在每次页面加载时检查每个产品的条件和分类,如果产品数量巨大(成千上万),可能会有性能开销。
重要提醒
- 缓存问题:上述代码修改了查询逻辑,如果你的网站启用了页面缓存(如WP Rocket、W3 Total Cache等),你可能需要在修改代码后清理所有缓存,才能在前台看到效果。
- 插件的兼容性:某些多语言插件或高级库存管理插件可能会覆盖或修改WooCommerce的可见性逻辑。如果代码没有按预期工作,请检查是否有其他插件干扰了
pre_get_posts或woocommerce_product_is_visible钩子。 - 代码安全:
functions.php中的错误可能会导致网站崩溃。建议先将代码放在一个子主题中,或者使用像“Code Snippets”这样的插件来运行自定义代码,这样出现问题可以一键禁用。
通过以上方法,你就可以精准地控制WooCommerce在特定分类中显示缺货商品,从而满足业务需求,比如展示即将上架的新品或允许客户预订缺货产品。