返回

WooCommerce如何展示已售罄产品?4种实用技巧

php

玩转 WooCommerce:打造一个自动展示“已售罄”产品的页面

嘿,各位 WooCommerce 店主们,是不是有时候想展示一下那些曾经热卖但现在已经光荣售罄的宝贝?这不仅能秀出你的店铺人气,还能给潜在顾客一种“再不下手就没了”的紧迫感,妥妥地提升信任度嘛!最近就有朋友在用 WordPress 和 Elementor 搭建 WooCommerce 店铺时遇到了点小麻烦:咋整一个“已售罄”产品展示页,让那些库存为零的商品自动上榜呢?

别急,这事儿能搞定!这位朋友还尝试了一段从 Business Bloomer 找来的代码,想用短代码 [out_of_stock_products] 来解决问题,结果页面空空如也。他用的短代码是这样的:[products limit="6" columns="3" out_of_stock_products="true"]

这篇文章咱们就来好好盘盘,为啥那段代码没按预期工作,以及有几种方法可以帮你实现这个“已售罄”产品展示页。

一、 问题出在哪?短代码为啥“罢工”了?

咱们先来看看这位朋友遇到的具体问题。他用的 Business Bloomer 提供的代码片段是这样的:

/**
 * @snippet       Display Out of Stock Products via Shortcode - WooCommerce
 * @how-to        businessbloomer.com/woocommerce-customization
 * @author        Rodolfo Melogli, Business Bloomer
 * @compatible    WooCommerce 5
 * @community     https://businessbloomer.com/club/
 */

add_shortcode( 'out_of_stock_products', 'bbloomer_out_of_stock_products_shortcode' );

function bbloomer_out_of_stock_products_shortcode() {

   $args = array(
      'post_type' => 'product',
      'posts_per_page' => -1, // 显示所有符合条件的产品
      'post_status' => 'publish',
      'meta_query' => array(
         array(
            'key' => '_stock_status',
            'value' => 'outofstock',
         )
      ),
      'fields' => 'ids', // 仅获取产品 ID
   );

   $product_ids = get_posts( $args );
   $product_ids = implode( ",", $product_ids );

   return do_shortcode("[products ids='$product_ids']"); // 将获取到的 ID 传递给 WooCommerce 内置的 [products] 短代码

}

这段代码本身是没毛病的。它的核心作用是:

  1. 注册新短代码add_shortcode( 'out_of_stock_products', ... ) 这行代码注册了一个全新的短代码,名字叫 [out_of_stock_products]
  2. 查询售罄产品bbloomer_out_of_stock_products_shortcode 函数会去数据库里找出所有库存状态(_stock_status)为 outofstock 的已发布(publish)产品。
  3. 内部调用原生短代码 :它会把找到的所有售罄产品的 ID 搜集起来,然后传递给 WooCommerce 自带的 [products ids='...'] 短代码来展示这些产品。

关键来了!这位朋友在使用时,往 Elementor 容器里放的短代码是 [products limit="6" columns="3" out_of_stock_products="true"]

问题就在这儿:

  • 他试图修改的是 WooCommerce 原生的 [products] 短代码,给它加了一个 out_of_stock_products="true" 的属性。
  • 但是,WooCommerce 原生的 [products] 短代码并不认识 out_of_stock_products 这个属性。
  • 那段 PHP 代码创建的是一个全新的短代码 [out_of_stock_products]。正确的使用方法应该是直接用这个新短代码,而不是试图给老的 [products] 短代码添加不存在的参数。

简单说,就是用错了“遥控器”。

二、 对症下药:几种创建“已售罄”产品页面的方案

既然知道了问题所在,那解决起来就方便多了。下面介绍几种方法,从易到难,总有一款适合你。

方案一:正确使用并优化自定义PHP短代码

这是针对那位朋友尝试过的代码进行修正和改进。

1. 原理和作用

咱们已经分析过了,这段 PHP 代码的目的是创建一个新的短代码 [out_of_stock_products],它会自动获取所有售罄产品的 ID,并利用 WooCommerce 内置的 [products] 短代码来展示它们。

2. 操作步骤

  • 添加代码:

    • 方法A (推荐给新手): 如果你用的是子主题 (Child Theme),把上面那段 PHP 代码复制粘贴到子主题的 functions.php 文件末尾。为啥用子主题?因为主题更新时,你的自定义代码不会被覆盖掉。
    • 方法B: 你也可以使用像 "Code Snippets" 这样的插件来添加 PHP 代码,这样更安全,也方便管理,不用直接碰主题文件。
    • 不推荐: 直接修改父主题的 functions.php 文件,因为主题一旦更新,你的修改就白费了。
  • 使用短代码:
    在你想展示售罄产品的页面(比如你用 Elementor 创建的“Sold”页面),添加一个“文本编辑器”小部件或者“短代码”小部件,然后在里面输入:

    [out_of_stock_products]
    

    这就行了!它会自动列出所有售罄的产品。

3. 进阶使用技巧:让短代码支持列数和数量限制

原始代码有个小缺点:它一次性加载所有售罄产品 (posts_per_page = -1),并且列数这些得依赖 [products] 短代码的默认设置,或者你得修改 WooCommerce 的全局设置。如果想让 [out_of_stock_products] 短代码更灵活,比如能直接控制显示数量和列数,可以稍微改造一下 bbloomer_out_of_stock_products_shortcode 函数:

// 修改后的代码,使其支持 limit 和 columns 参数
add_shortcode( 'out_of_stock_products', 'bbloomer_out_of_stock_products_shortcode_v2' );

function bbloomer_out_of_stock_products_shortcode_v2( $atts ) {
    // 1. 设置短代码属性的默认值
    $atts = shortcode_atts( array(
        'limit'   => -1, // 默认显示所有
        'columns' => 4,  // 默认4'orderby' => 'date', // 默认按日期排序
        'order'   => 'DESC', // 默认降序
    ), $atts, 'out_of_stock_products' );

    // 2. 构建查询参数
    $query_args = array(
        'post_type'      => 'product',
        'post_status'    => 'publish',
        'posts_per_page' => intval( $atts['limit'] ), // 使用短代码传入的 limit
        'meta_query'     => array(
            array(
                'key'   => '_stock_status',
                'value' => 'outofstock',
            )
        ),
        'fields'         => 'ids', // 只需要产品 ID
    );

    $product_ids = get_posts( $query_args );

    if ( ! empty( $product_ids ) ) {
        $product_ids_str = implode( ",", $product_ids );
        // 3. 构建并返回内部 [products] 短代码,传递参数
        $shortcode_str = sprintf(
            '[products ids="%s" columns="%s" orderby="%s" order="%s"]',
            esc_attr( $product_ids_str ),
            esc_attr( $atts['columns'] ),
            esc_attr( $atts['orderby'] ),
            esc_attr( $atts['order'] )
        );
        // 如果 limit 不是 -1 (即有数量限制),且你想让 [products] 短代码也知道这个限制
        // (通常 ids 优先级更高,limit 会被忽略,但为了完整性可以加上)
        // $shortcode_str = str_replace(']', sprintf(' limit="%s"]', esc_attr( $atts['limit'] )), $shortcode_str);

        return do_shortcode( $shortcode_str );
    }

    return '<p>当前没有已售罄的产品。</p>'; // 如果没有售罄产品,给个提示
}

现在,你就可以这样使用了:

[out_of_stock_products limit="6" columns="3"]

或者:

[out_of_stock_products limit="10" columns="5" orderby="title" order="ASC"]

4. 额外安全建议

  • 定期备份你的网站,尤其是在修改代码文件之前。
  • 如果你对 PHP 不太熟,优先考虑使用 Code Snippets 插件。

方案二:利用 Elementor Pro 的“产品”小部件

如果你用的是 Elementor Pro 版本,事情就简单多了,根本不用写代码。

1. 原理和作用

Elementor Pro 的“产品 (Products)”小部件内置了强大的查询构建器,允许你根据各种条件(包括库存状态)来筛选和展示产品。

2. 操作步骤

  1. 用 Elementor 编辑你的“Sold”页面。

  2. 从 Elementor 小部件面板中,拖拽“产品 (Products) ”小部件到页面编辑区域。

  3. 在左侧的“产品”小部件设置面板中,找到“Query (查询) ”选项卡。

  4. Source (来源) :选择“Products”或“Manual Selection”通常不行,因为我们要动态获取。保持默认的“Latest Products”或“Sale Products”等,然后通过查询条件细化。更直接的是选择 “Custom Query (自定义查询) ”。

  5. 展开“Query (查询) ”部分,你会看到各种筛选条件。找到和库存相关的设置。

    • 点击“Include By ”旁边的 “+” 号,添加一条规则。
    • 在弹出的选项中,你可能需要寻找“Stock Status ”或者类似的选项(具体名称可能因 Elementor 版本或 WooCommerce 的集成方式略有不同,但思路是一致的)。通常你会找到一个更通用的查询 ID 设置,如 "Get posts by... -> Term"。
    • 如果 Elementor 的 Products 小部件有直接的库存状态筛选 (Stock Status filter),直接选择 "Out of stock"。
    • 如果 Elementor Pro 的版本直接提供了高级查询,你可以在那里设置 meta_key_stock_status 并且 meta_valueoutofstock
    • 在 Elementor 的较新版本中,针对 Products 小部件,Query 部分可能会有一个专门的 “Stock” 或 “Availability” 过滤器,直接选择 “Out of stock” 即可。
  6. 更直接的方式(如果 Query 选项支持):

    • 在 "Query" (查询) 部分,将 "Source" (来源) 设置为 "Custom Query" (自定义查询)。
    • 你可能需要利用 "Query ID" (如果你定义了一个预设查询) 或者直接在查询参数中添加。
    • 重点 :在 "Query" 设置中,寻找 "Stock Status " 或类似筛选器,并将其设置为 "Out of Stock "。 Elementor Pro 的产品小部件通常会有这个选项。
    • 如果找不到直接的库存状态筛选,可能需要用 "Terms" 筛选,然后选择对应的产品可见性 Term (比如 WooCommerce 可能会把缺货产品归类到一个特定的内部 Term,但这不常见)。最可靠的是直接的库存状态过滤。

    示例路径 (可能因 Elementor 版本有差异):
    Products Widget -> Content Tab -> Query -> Source: Current Query (如果是在产品归档页想改) 或 Source: Latest Products/Custom Query -> 往下找 StockAvailability 或相关的 Meta Query 选项。

  7. 调整“Layout (布局)”选项卡中的列数、每页产品数等。

  8. 保存页面。

3. 进阶使用技巧

  • 你可以组合其他查询条件,比如只显示某个分类下的售罄产品。
  • Elementor Pro 提供了丰富的样式选项,你可以把这个“售罄产品”区域打扮得漂漂亮亮。

方案三:使用 WordPress 区块编辑器 (Gutenberg) 的“所有产品”区块

如果你的主题和 WooCommerce 支持 Gutenberg 区块编辑器,并且你倾向于使用原生WordPress功能,这也是一个好选择。

1. 原理和作用

WooCommerce 为 Gutenberg 提供了很多产品相关的区块,“所有产品 (All Products)”区块允许你通过界面操作筛选产品,包括按库存状态。

2. 操作步骤

  1. 在 WordPress 后台编辑你的“Sold”页面 (确保你在使用区块编辑器)。
  2. 点击“+”号添加新区块,搜索并选择“所有产品 (All Products) ”区块 (或者叫 "Products by Category", "Products by Tag" 等,选择最泛用的那个,然后修改其设置)。
  3. 插入区块后,在右侧的区块设置面板中,你会看到“筛选产品 (Filter Products) ”或类似的选项。
  4. 展开“库存状态 (Stock Status) ”筛选器。
  5. 勾选“缺货 (Out of stock) ”选项。
  6. 你还可以调整列数、行数等布局设置。
  7. 保存页面。

3. 进阶使用技巧

  • 这个区块同样支持按分类、标签等进行筛选,可以组合使用。
  • 结合其他区块,比如标题区块、段落区块,来丰富你的“已售罄”页面内容。

方案四:自定义页面模板与 WP_Query (适合有一定PHP基础的开发者)

这种方法灵活性最高,但需要你懂一点点 PHP 和 WordPress 主题开发。

1. 原理和作用

你可以创建一个自定义的 WordPress 页面模板,在这个模板里使用 WP_Query 直接查询数据库中所有售罄的产品,然后按照你想要的方式循环展示它们。

2. 操作步骤

  1. 创建页面模板文件:

    • 在你的子主题文件夹里,创建一个新的 PHP 文件,比如命名为 template-sold-products.php
    • 在该文件顶部添加模板声明:
      <?php
      /**
       * Template Name: Sold Products Page
       *
       * This is the template that displays all out-of-stock products.
       */
      
      get_header(); // 加载网站头部
      ?>
      
  2. 编写查询和循环代码:
    get_header(); 之后,添加以下代码:

    <div id="primary" class="content-area">
        <main id="main" class="site-main" role="main">
    
            <header class="page-header">
                <h1 class="page-title"><?php _e( 'Sold Out Products', 'your-text-domain' ); ?></h1>
            </header><!-- .page-header -->
    
            <?php
            $args = array(
                'post_type'      => 'product',
                'post_status'    => 'publish',
                'posts_per_page' => -1, // 显示所有,或者设置为你想要的数量,比如12
                // 'paged'          => get_query_var('paged') ? get_query_var('paged') : 1, // 如果需要分页
                'meta_query'     => array(
                    array(
                        'key'     => '_stock_status',
                        'value'   => 'outofstock',
                        'compare' => '=',
                    ),
                ),
                'orderby'        => 'date', // 可以按需修改排序方式
                'order'          => 'DESC',
            );
    
            $sold_products_query = new WP_Query( $args );
    
            if ( $sold_products_query->have_posts() ) :
                echo '<ul class="products columns-3">'; // WooCommerce 产品列表通常用这个 class
                while ( $sold_products_query->have_posts() ) : $sold_products_query->the_post();
                    /**
                     * Hook: woocommerce_shop_loop.
                     *
                     * @hooked wc_get_template_part - 10 - loop/content-product.php
                     */
                    // 使用 WooCommerce 标准的产品循环项模板
                    wc_get_template_part( 'content', 'product' );
                endwhile;
                echo '</ul>';
                wp_reset_postdata(); // 重置 post data
    
                // 如果需要分页
                // woocommerce_pagination();
            else :
                echo '<p class="woocommerce-info">' . __( 'No sold out products found yet.', 'your-text-domain' ) . '</p>';
            endif;
            ?>
    
        </main><!-- #main -->
    </div><!-- #primary -->
    
    <?php
    // get_sidebar(); // 如果需要侧边栏
    get_footer(); // 加载网站底部
    ?>
    

    确保你的主题文本域 (your-text-domain) 是正确的,用于国际化。如果你不需要翻译,可以直接写中文。

  3. 在 WordPress 后台应用模板:

    • 创建一个新的 WordPress 页面(比如命名为“已售商品陈列”)。
    • 在页面编辑界面的右侧“页面属性 (Page Attributes)”元框中,找到“模板 (Template) ”下拉菜单。
    • 选择你刚刚创建的“Sold Products Page”模板。
    • 发布页面。

3. 额外安全建议/进阶

  • 代码中的 columns-3 是 WooCommerce 常用的 CSS 类,表示三列布局。你需要确保你的主题支持这个类,或者自行添加 CSS 样式来控制产品的布局。
  • wc_get_template_part( 'content', 'product' ); 会调用 WooCommerce 标准的产品单元格模板。如果你想对售罄产品的展示样式做深度定制,可以复制 WooCommerce 的 templates/content-product.php 文件到你的子主题的 woocommerce 文件夹下进行修改,或者在这个循环里直接写 HTML。
  • 如果售罄产品非常多,考虑添加分页功能 (posts_per_page 设置为一个合理的数字,并取消 woocommerce_pagination() 的注释)。

三、一些优化的小建议

不管你选哪种方法,这里还有几个小贴士可以让你的“已售罄”页面更出色:

  1. 清晰的标签和说明: 在页面顶部清楚地告诉用户这个页面展示的是“已售罄”、“过往热销”或类似的产品。
  2. 视觉区分: 可以考虑给售罄的产品加上特殊的标记或样式,比如“SOLD”水印,或者略微灰化的图片,让用户一眼就能看出来。这通常需要自定义 CSS。
  3. 不要影响购买流程: 确保这些售罄产品不会干扰用户寻找和购买当前有货的商品。它们只是展示作用,所以加入购物车按钮应该是隐藏或禁用的。WooCommerce 默认会对缺货产品禁用购买按钮。
  4. 性能考虑: 如果售罄产品超级多,使用方案一或方案四时,一次性查询所有 (posts_per_page = -1) 可能会对性能有轻微影响。可以考虑分页,或者只显示最近售罄的一批产品。Elementor Pro 和 Gutenberg 区块通常内置了分页或懒加载机制。

搞定!希望上面这些方法能帮你顺利创建出酷炫的“已售罄”产品展示页,给你的店铺再添一把火。选择最适合你技术水平和需求的那一个方案动手试试吧!