1
votes

I am trying to make a page, (default woocommerce archive style), that it will show only the products that are in Sale. Here to mention, that i have only, variable products and not simple.

I tried to make my custom shortcode

global $woocommerce_loop;
    $atts = shortcode_atts( array(
        'per_page' => '-1',
        'columns'  => '4',
        'orderby'  => 'title',
        'order'    => 'asc'
    ), $atts );

    // Get products on sale
    $product_ids_on_sale = wc_get_product_ids_on_sale();

    $meta_query = WC()->query->get_meta_query();
    $args = array(
        'posts_per_page'    => $atts['per_page'],
        'orderby'           => $atts['orderby'],
        'order'             => $atts['order'],
        'no_found_rows'     => 1,
        'post_status'       => 'publish',
        'post_type'         => 'product',
        'meta_query'        => $meta_query,
        'post__in'          => array_merge( array( 0 ), $product_ids_on_sale )
    );
    ob_start();
    $products = new WP_Query( apply_filters( 'woocommerce_shortcode_products_query', $args, $atts ) );
    $columns = absint( $atts['columns'] );
    $woocommerce_loop['columns'] = $columns;
    if ( $products->have_posts() ) : 

        woocommerce_product_loop_start();

            while ( $products->have_posts() ) : $products->the_post(); 

                wc_get_template_part( 'content', 'product' ); 

            endwhile; // end of the loop. 

         woocommerce_product_loop_end(); 

     endif;
    wp_reset_postdata();
    return '<div class="woocommerce columns-' . $columns . '">' . ob_get_clean() . '</div>';

but as a result i get only 2 products.

Any help or ideas?

4

4 Answers

3
votes

Why are you trying to create a new shortcode? Woocommerce has provided its own shortcode to show the products on sale in its own archival style :

[sale_products per_page="12"]

You can see the whole list here

3
votes

I found out a temporary solution in this by creating a custom shortcode. I don't know why i don't get all the sale products with the default woocommerce shortcode.

This worked for me:

function variable_sale_products( $atts ) { global $woocommerce, $product;

    $args = array(
        'post_type' => 'product',
        'post_status' => 'publish',
        'posts_per_page' => -1
    );

    ob_start();
    $loop = new WP_Query( $args );

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

        while ( $loop->have_posts() ) : $loop->the_post();
            $id = get_the_ID();
            $_product = wc_get_product( $id );

            if($_product->is_on_sale()){    
                wc_get_template_part( 'content', 'product' );
            }
        endwhile;

        woocommerce_product_loop_end(); 
    }
    wp_reset_postdata();
    return '<div class="woocommerce columns-4">' . ob_get_clean() . '</div>';
}
add_shortcode( 'variation_sale_product', 'variable_sale_products' );

If you have any other suggestion i'd like to hear from you

1
votes

Try to expand $args (this code adds sale simple and variable products):

$args = array(
        'posts_per_page'   => -1,
        'post_type'  => 'product',
        'meta_key' => 'total_sales',
        'orderby' => 'meta_value_num',
        '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'
            )
        )
      );
0
votes

I tried [sale_products per_page="12"] , but it was showing only only one product.

Below is the steps I did to show all the products on sale :

1- go to WooCommerce -> Status -> Tools tab and click the button next to generate lookup tables and give it some time to complete before checking again. If this didn't work so proceed with the next step.

2- Update the shortode to be [sale_products per_page="32" paginate="true" columns="4" orderby="random"]. Again if this didn't work implement the next step.

3- This is not logical but what I did is that I removed the "sale price" of the item which appears in the on sale page. After that all other items appeared !!

Hope this helps anybody