显示 WooCommerce 产品变体循环的自定义简码

Custom shortcode displaying a loop of WooCommerce product variations

我正在尝试制作自定义短代码,以显示一些没有库存数量的产品变体 stock <= 0

这是我目前所做的:

if( ! function_exists('preorable_products') ) {

    // Add Shortcode
    function preorable_products( $atts ) {
        global $woocommerce_loop;

        // Attributes 
        $atts = shortcode_atts(
            array(
                'columns'   => '4',
                'limit'     => '20',
                'preordable'     => "yes",
                'stock'       => 0,
            ),
            $atts, 'preorable_products'
        );


        $woocommerce_loop['columns'] = $atts['columns'];
        
        // The WP_Query
        $products_variation = new WP_Query( array (
            'post_type'         => 'product_variation',
            'post_status'       => 'publish',
            'fields'         => 'id=>parent',
            'posts_per_page'    => $atts['limit'],
            'meta_query'        => array(
                'relation'      => 'AND',
                'preordable'  => array(
                    'key'       =>'_ab_preorder_checkbox',
                    'value'     => "yes",
                    'compare'   => '=='
                ),
                'stock'  => array(
                    'key'       =>'_stock',
                    'value'     => 0,
                    'compare'   => '<='
                ),
            )
        ));
        $products = $products_variation;
        ob_start();
        
        if ( $products->have_posts() ) { ?>

            <?php woocommerce_product_loop_start(); ?>

                <?php while ( $products->have_posts() ) : $products->the_post(); ?>

                    <?php wc_get_template_part( 'content', 'product' ); ?>

                <?php endwhile; // end of the loop. ?>

            <?php woocommerce_product_loop_end(); ?>

            <?php
        } else {
            do_action( "woocommerce_shortcode_products_loop_no_results", $atts );
            echo "<p>Aucun article disponible à la précommande.</p>";
        }

        woocommerce_reset_loop();
        wp_reset_postdata();

        return '<div class="woocommerce columns-' . $atts['columns'] . '">' . ob_get_clean() . '</div>';
    }

    add_shortcode( 'preorable_products', 'preorable_products' );
}

WP 查询部分似乎工作正常,但显示产品的代码部分似乎有问题。我觉得 $product 变量没有 have_post 方法:

if ( $products->have_posts() ) { ?>
    <?php woocommerce_product_loop_start(); ?>

        <?php while ( $products->have_posts() ) : $products->the_post(); ?>

            <?php wc_get_template_part( 'content', 'product' ); ?>

        <?php endwhile; // end of the loop. ?>

    <?php woocommerce_product_loop_end(); ?>

    <?php
} else {
    do_action( "woocommerce_shortcode_products_loop_no_results", $atts );
    echo "<p>Aucun article disponible à la précommande.</p>";
}

woocommerce_reset_loop();
wp_reset_postdata();

return '<div class="woocommerce columns-' . $atts['columns'] . '">' . ob_get_clean() . '</div>';     

欢迎任何帮助。

您的代码中存在一些错误和遗漏的内容,请改用以下重新访问的代码:

if( ! function_exists('get_preordable_products') ) {

    function get_preordable_products( $atts ) {
        // Shortcode Attributes
        extract( shortcode_atts( array(
            'columns'    => '4',
            'limit'      => '20',
            'preordable' => "yes",
            'stock'      => 0,
        ), $atts, 'preordable_products' ) );

        // The WP_Query
        $query = new WP_Query( array (
            'post_type'         => 'product_variation',
            'post_status'       => 'publish',
            'posts_per_page'    => $limit,
            'meta_query'        => array(
                'relation'      => 'AND',
                'preordable'  => array(
                    'key'       =>'_ab_preorder_checkbox',
                    'value'     => "yes",
                    'compare'   => '=='
                ),
                array(
                    'key'       =>'_stock',
                    'value'     => 0,
                    'compare'   => '<='
                ),
            )
        ) );

        global $woocommerce_loop;

        $woocommerce_loop['columns']      = $columns;
        $woocommerce_loop['is_shortcode'] = 1;
        $woocommerce_loop['name']         = 'preordable_products';
        $woocommerce_loop['total']        = $query->post_count;
        $woocommerce_loop['total_pages']  = $query->max_num_pages;
        $woocommerce_loop['per_page']     = $limit;

        ob_start();

        if ( $query->have_posts() ) {
            woocommerce_product_loop_start();

            while ( $query->have_posts() ) {
                $query->the_post();
                wc_get_template_part( 'content', 'product' );
            }
            woocommerce_product_loop_end();
            woocommerce_reset_loop();
            wp_reset_postdata();
        } else {
            do_action( "woocommerce_shortcode_products_loop_no_results", $atts );

            echo '<p>'. __("Aucun article disponible à la précommande.") . '</p>';
        }

        $content = ob_get_clean();

        return '<div class="woocommerce columns-' . $columns . '">' . $content . '</div>';
    }

    add_shortcode( 'preordable_products', 'get_preordable_products' );
}

代码进入活动子主题(或活动主题)的 functions.php 文件。已测试并有效。

用法: [preordable_products] 或在 Php 代码中 echo do_shortcode('[preordable_products]');