duannao3819 2019-03-12 16:33
浏览 40
已采纳

列出没有短代码的WooCommerce畅销产品

So, I have been trying to do exactly the same thing as the [products limit="10" columns="4" best_selling="true" ] shortcode does.

I need to implement it to a php page template, but I have read that do_shortcode is bad practice, and I would like to do it the right way.

This is what I have so far, but where do I go from here?

$args = array(
        'limit' => '10',
        'columns'      => '4',
        'orderby' => 'total_sales',
        'order' => 'DESC',
);
$products = wc_get_products( $args );

If I understand it correctly this will save the 10 best selling products, descending by the number of total sales into $products. Is this not correct?

How do I show the actual product listings from $products correctly (just like the shortcode would do)?

  • 写回答

1条回答 默认 最新

  • doujing1156 2019-03-12 17:04
    关注

    total_sales can be set in the query using meta_key.

    Once you return the results from the query, you just need to loop through them and output whatever attributes you need.

    $args = array(
            'limit'     => '10',
            'orderby'   => array( 'meta_value_num' => 'DESC', 'title' => 'ASC' ),
            'meta_key'  => 'total_sales',
        );
    
        $query    = new WC_Product_Query( $args );
        $products = $query->get_products();
        if ( $products ) {
            foreach ( $products as $product ) {
                echo $product->get_name(); // Here, we're just listing each product's name
            }
        } else {
            echo __( 'No products found' );
        }
    

    Update

    With this update, we're now using the results from wc_get_products() on a custom page template adapted from archive-product.php. The goal here was to avoid using WP_Query/get_posts(), as they are not recommended for product querying.

    wc_get_products and WC_Product_Query provide a standard way of retrieving products that is safe to use and will not break due to database changes in future WooCommerce versions. Building custom WP_Queries or database queries is likely to break your code in future versions of WooCommerce as data moves towards custom tables for better performance. This is the best-practices way for plugin and theme developers to retrieve multiple products. wc_get_products and WC_Product_Query are similar to WordPress get_posts and WP_Query. Just like those, you pass in an array of arguments defining the criteria for the search.

    We're now able to get the same layout/styles that normal product category/archive pages have, but with our top-sellers query. We have the product title, image, price, and add-to-cart button and all of the WooCommerce/theme styles applied without having to build everything from scratch as with the previous method (above).

    Tested and working in WooCommerce 3.5.6

    defined( 'ABSPATH' ) || exit;
    get_header( 'shop' );
    do_action( 'woocommerce_before_main_content' );
    ?>
        <header class="woocommerce-products-header">
            <?php if ( apply_filters( 'woocommerce_show_page_title', true ) ) : ?>
                <h1 class="woocommerce-products-header__title page-title"><?php echo get_the_title(); ?></h1>
            <?php endif; ?>
        </header>
    <?php
    
    
    if ( ! function_exists( 'wc_get_products' ) ) {
        return;
    }
    echo '<div class="woocommerce">'; // needed for default styles 
    $top_selling_products = wc_get_products( array(
        'meta_key' => 'total_sales', // our custom query meta_key
        'return'   => 'ids', // needed to pass to $post_object
        'orderby'  => array( 'meta_value_num' => 'DESC', 'title' => 'ASC' ), // order from highest to lowest of top sellers
    ) );
    if ( $top_selling_products ) {
        do_action( 'woocommerce_before_shop_loop' );
        woocommerce_product_loop_start();
        foreach ( $top_selling_products as $top_selling_product ) {
            $post_object = get_post( $top_selling_product );
            setup_postdata( $GLOBALS['post'] =& $post_object );
            do_action( 'woocommerce_shop_loop' );
            wc_get_template_part( 'content', 'product' );
        }
        wp_reset_postdata();
        woocommerce_product_loop_end();
        do_action( 'woocommerce_after_shop_loop' );
    } else {
        do_action( 'woocommerce_no_products_found' );
    }
    echo '</div><!-- .woocommerce -->';
    
    do_action( 'woocommerce_after_main_content' );
    do_action( 'woocommerce_sidebar' );
    get_footer( 'shop' );
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 如何通过代码传输视频到亚马逊平台
  • ¥15 php查询mysql数据库并显示至下拉列表中
  • ¥15 freertos下使用外部中断失效
  • ¥15 输入的char字符转为int类型,不是对应的ascall码,如何才能使之转换为对应ascall码?或者使输入的char字符可以正常与其他字符比较?
  • ¥15 devserver配置完 启动服务 无法访问static上的资源
  • ¥15 解决websocket跟c#客户端通信
  • ¥30 Python调用dll文件输出Nan重置dll状态
  • ¥15 浮动div的高度控制问题。
  • ¥66 换电脑后应用程序报错
  • ¥50 array数据同步问题