WooCommerce: Display ONLY on-sale products in Shop

前端 未结 5 1350
花落未央
花落未央 2020-12-08 11:57

I need to create a products archive page (usually the Shop page in WooCommerce) but displays ONLY the ON SALE<

相关标签:
5条回答
  • 2020-12-08 12:14

    Create a new page using shortcode [sale_products per_page="12"]

    List of available shortcodes and their parameters is here: http://docs.woothemes.com/document/woocommerce-shortcodes/

    0 讨论(0)
  • 2020-12-08 12:23

    @mirus' answer regarding the shortcode gave me the idea to check out how WooCommerce is querying only the on-sale items. Apparently WooCommerce has a wc_get_product_ids_on_sale() function that will return the IDs of the on-sale items. Then we can easily adjust the query using the post__in parameter to only return those specific items.

    WooCommerce has a woocommerce_product_query hook in the class-wc-query.php class that allows for us to modify the query before it is run.... it is run on pre_get_posts which is the usual place for modifying the query. Using Woo's hook just means you let them handle the majority of the conditional logic about when this query modification should be applied.

    add_action( 'woocommerce_product_query', 'so_20990199_product_query' );
    
    function so_20990199_product_query( $q ){
    
        $product_ids_on_sale = wc_get_product_ids_on_sale();
    
        $q->set( 'post__in', $product_ids_on_sale );
    
    }
    
    0 讨论(0)
  • 2020-12-08 12:27

    Solution for variable and simple products:

    add_action( 'save_post_product', 'update_product_set_sale_cat_var' );
    
    function update_product_set_sale_cat_var( $post_id ) {
    
        $sales_ids = wc_get_product_ids_on_sale();
    
        foreach ( $sales_ids as $sale_id ) :
            if ($sale_id == $post_id) :
                wp_set_object_terms($post_id, 'sale', 'product_cat', true );
            else :
                if ( has_term( 'sale', 'product_cat', $post_id ) ) {
                    wp_remove_object_terms( $post_id, 'sale', 'product_cat' );
                }
            endif;
        endforeach; 
    
    }
    
    0 讨论(0)
  • 2020-12-08 12:28

    @gmaggio using query_posts() will break your site. Use pre_get_posts

    add_filter( 'pre_get_posts', 'catalog_filters' );
    function catalog_filters( $query ) {
        if ( $query->is_main_query() && $query->post_type = 'product' ) {
            if(isset($_GET['onsale'])) {
                $meta_query = array(
                    'relation' => 'OR',
                    array( // Simple products type
                    'key' => '_sale_price',
                    'value' => 0,
                    'compare' => '>',
                    'type' => 'numeric'
                    ),
                    array( // Variable products type
                    'key' => '_min_variation_sale_price',
                    'value' => 0,
                    'compare' => '>',
                    'type' => 'numeric'
                    )
                ); $query->set('meta_query', $meta_query);
            }
            if(isset($_GET['bestsellers'])) {
                $meta_query     = array(
                array( 
                    'key'           => 'total_sales',
                    'value'         => 0,
                    'compare'       => '>',
                    'type'          => 'numeric'
                    )
                );
            }
        }
    
    return $query;
    }
    
    0 讨论(0)
  • 2020-12-08 12:35

    I managed to filter out the ON SALE products with the code below placed just above the if ( have_posts() ) : line...

    $args = array(
        'post_type'      => 'product',
        'meta_query'     => array(
            'relation' => 'OR',
            array( // Simple products type
                'key'           => '_sale_price',
                'value'         => 0,
                'compare'       => '>',
                'type'          => 'numeric'
            ),
            array( // Variable products type
                'key'           => '_min_variation_sale_price',
                'value'         => 0,
                'compare'       => '>',
                'type'          => 'numeric'
            )
        )
    );
    
    query_posts( $args );
    

    The code is placed in a copy of archive-product.php which I renamed archive-product_sale.php and made as a page template.

    0 讨论(0)
提交回复
热议问题