Create WooCommerce Page with products on sale - wordpress

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?

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

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

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'
)
)
);

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

Related

Hide out of stock products woocommerce query

Tying to hide out of stock products from a query
<?php
$args = array(
'post_type' => 'product',
'posts_per_page' => 16,
'product_cat' => 'crisps',
'orderby' => 'rand',
'meta_query' => array (
'key' => '_stock_status',
'value' => 'instock'
)
);
$loop = new WP_Query( $args );
if ( $loop->have_posts() ) {
while ( $loop->have_posts() ) : $loop->the_post();
wc_get_template_part( 'content', 'product' );
endwhile;
} else {
echo __( 'No products found' );
}
wp_reset_postdata();
?>
however the out of stock products are still showing
any help
Try
'meta_query' => array (
array(
'key' => '_stock_status',
'value' => 'instock'
),
)

woocommerce product shortcodes template

As I know
[products limit=”4″ columns=”4″ on_sale=”true” ] will show all on sale products,
[products limit=”3″ columns=”3″ best_selling=”true” ] will show best selling products,
If I were not wrong, both of the shortcodes would call the content-product.php file to display the products.
My question is how can I make different product shortcodes call different php template files to show the related products instead of calling the same file that is content-product.php?
For example,
on sale shortcodes call content-product-1.php
best selling shortcodes call content-product-2.php
Thank you!
Create our own shortcode to display the specific products and our our own template as below,
for example, wc_get_template_part( 'content', 'product-test' );
add_shortcode( 'sale_products_test', 'sale_products' );
function sale_products( $atts ){
global $woocommerce_loop, $woocommerce;
extract( shortcode_atts( array(
'per_page' => '12',
'columns' => '3',
'orderby' => 'title',
'category' => 'clearance',
'order' => 'asc'
), $atts ) );
// Get products on sale
$product_ids_on_sale = woocommerce_get_product_ids_on_sale();
$meta_query = array();
$meta_query[] = $woocommerce->query->visibility_meta_query();
$meta_query[] = $woocommerce->query->stock_status_meta_query();
$args = array(
'posts_per_page'=> $per_page,
'orderby' => $orderby,
'order' => $order,
'no_found_rows' => 1,
'post_status' => 'publish',
'post_type' => 'product',
'orderby' => 'date',
'order' => 'ASC',
'meta_query' => $meta_query,
'post__in' => $product_ids_on_sale,
'tax_query' => array( array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $category,
)),
);
ob_start();
$products = new WP_Query( $args );
$woocommerce_loop['columns'] = $columns;
if ( $products->have_posts() ) : ?>
<?php woocommerce_product_loop_start(); ?>
<?php while ( $products->have_posts() ) : $products->the_post(); ?>
<?php wc_get_template_part( 'content', 'product-test' ); ?>
<?php endwhile; // end of the loop. ?>
<?php woocommerce_product_loop_end(); ?>
<?php endif;
wp_reset_postdata();
return ob_get_clean();
}
Not Possible. This type of shortcode require to use wp_query and fetch data your requirement wise

Dynamic call of shortcode with parameters

I have this function:
function test_q($atts){
$args = shortcode_atts(array(
'post_type' => 'product',
'columns' => 4,
'posts_per_page' => 12,
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array( 'mugs' ),
),
array(
'taxonomy' => 'product_tag',
'field' => 'slug',
'terms' => array( 'football' ),
),
),
), $atts);
$loop = new WP_Query( $args );
if ( $loop->have_posts() ) {
woocommerce_product_loop_start();
while ( $loop->have_posts() ) : $loop->the_post();
wc_get_template_part( 'content', 'product' );
endwhile;
woocommerce_product_loop_end();
} else {
echo __( 'No products found' );
}
woocommerce_reset_loop();
wp_reset_postdata();
return '<div class="woocommerce columns-' . $columns . '">' . ob_get_clean() . '</div>';
}
add_shortcode('testasd', 'test_q');
I want to pass dynamic parameters to 'mugs' and 'football' with the shortcode. I am filtering products by category and tag. This function is working fine but I want to pass those two parameters through shortcode to make it dynamic.
I need to call this shortcode each time with different 'mugs' and 'football' term. For example 't-shirts' and 'basketball'. How will i do that?
You can do it easily via extracting the shortcode and passing the values via $atts from the shortcode.
After your arguments , you can pass it like the following ,
if($args['tax_query']['taxonomy'] == 'product_cat'){
$args['tax_query']['terms'] = $atts['terms_cat'];
}
if($args['tax_query']['taxonomy'] == 'product_tag'){
$args['tax_query']['terms'] = $atts['terms_tag'];
}
Then add 2 parameters in the shortcode,
[testasd terms_cat='t-shirts' terms_tag='basketball']

How to display recent posts by category name in WordPress using shortcode

I want to show the recent posts by category name using shortcode like:
[recent-posts posts="10" category="thecategoryname"]
My code below display the recent posts but I don't know how to display them by category in shortcode in the format above.
function recent_posts_function($atts){
extract(shortcode_atts(array(
'posts' => 1,
), $atts));
$return_string = '<ul>';
query_posts(array('orderby' => 'date', 'order' => 'DESC' , 'showposts' => $posts));
if ( have_posts() ) :
while ( have_posts() ) : the_post();
$return_string .= '<li>'.get_the_title().'</li>';
endwhile;
endif;
$return_string .= '</ul>';
wp_reset_query();
return $return_string;
}
function register_shortcodes(){
add_shortcode('recent-posts', 'recent_posts_function');
}
add_action( 'init', 'register_shortcodes');
Example for your shortcode attributes:
// Attributes
extract( shortcode_atts(
array(
'category' => 'thecategoryname',
'posts' => '10',
), $atts )
);
Additionally, you need to add category_name to your query and how many posts per page.
Example (from your code above - modified):
query_posts(
array(
'orderby' => 'date',
'order' => 'DESC' ,
'posts_per_page' => $posts,
'category_name' => $category
)
);

How to get category listing of most popular products in woocommerce

How can I list out the top 5 most popular category(or category of most popular products) on my wordpress site home page.
I have used woocommerce plugin for products.
Thanks in advance for any suggestion or solution.
Since none of the answers is a solution to the author's question, here is what I came up with. This is a shortcode snippet that lists popular products by categories. By popular I mean most sold products ( as in total sales).
function bestselling_products_by_categories( $atts ){
global $woocommerce_loop;
extract(shortcode_atts(array(
'cats' => '',
'tax' => 'product_cat',
'per_cat' => '5',
'columns' => '5',
'include_children' => false,
'title' => 'Popular Products',
'link_text' => 'See all',
), $atts));
if(empty($cats)){
$terms = get_terms( 'product_cat', array('hide_empty' => true, 'fields' => 'ids'));
$cats = implode(',', $terms);
}
$cats = explode(',', $cats);
if( empty($cats) )
return '';
ob_start();
foreach($cats as $cat){
// get the product category
$term = get_term( $cat, $tax);
// setup query
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'posts_per_page' => $per_cat,
'meta_key' => 'total_sales',
'orderby' => 'meta_value_num',
'tax_query' => array(
array(
'taxonomy' => $tax,
'field' => 'id',
'terms' => $cat,
'include_children' => $include_children,
)
),
'meta_query' => array(
array(
'key' => '_visibility',
'value' => array( 'catalog', 'visible' ),
'compare' => 'IN'
)
)
);
// set woocommerce columns
$woocommerce_loop['columns'] = $columns;
// query database
$products = new WP_Query( $args );
$woocommerce_loop['columns'] = $columns;
if ( $products->have_posts() ) : ?>
<?php if ( shortcode_exists('title') ) : ?>
<?php echo do_shortcode('[title text="'. $title .'" link="' . get_term_link( $cat, 'product_cat' ) . '" link_text="' . $link_text . '"]'); ?>
<?php else : ?>
<?php echo '<h2>'. $title .'</h2>'; ?>
<?php endif; ?>
<?php woocommerce_product_loop_start(); ?>
<?php while ( $products->have_posts() ) : $products->the_post(); ?>
<?php woocommerce_get_template_part( 'content', 'product' ); ?>
<?php endwhile; // end of the loop. ?>
<?php woocommerce_product_loop_end(); ?>
<?php endif;
wp_reset_postdata();
}
return '<div class="woocommerce columns-' . $columns . '">' . ob_get_clean() . '</div>';
} add_shortcode( 'custom_bestselling_product_by_categories', 'bestselling_products_by_categories' );
You can use this by calling it as:
<?php echo do_shortcode('[custom_bestselling_product_by_categories cats="' . $term->term_id . '"]'); ?>
This shortcode has some options:
cats : the category ID or comma-separated IDs to retrieve the products from.
tax : the taxonomy to get the products from, default is product_cat
per_cat : number of products to retrieve
columns : number of columns to display
include_children : if false only direct children of the category will be displayed, if true then children of children will be displayed
title : title to display
link_text : the link text linked to the store
Notice that this snippet assumes you have a shortcode named title and it takes a few other parameters such as link and link_text arguments. You can always change this according to your theme.
Hope it helps.
I recommend you to check this page.
http://docs.woothemes.com/document/woocommerce-shortcodes/
array(
'per_page' => '12',
'columns' => '4',
'orderby' => 'title',
'order' => 'asc',
'category' => ''
)
[product_category category="appliances"]
array(
'per_page' => '12',
'columns' => '4',
'orderby' => 'title',
'order' => 'asc'
)
[top_rated_products per_page="12"]
Or you can use this plugin : https://wordpress.org/plugins/sp-woocommerce-best-selling-products-by-category/
Popular might be in many cases like most viewing, top selling. So i listed products by top selling. This way you can get top selling products and by this you can get category listing.
$query_args = array(
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'posts_per_page' => '10',
'columns' => '4',
'fields' => 'ids',
'meta_key' => 'total_sales',
'orderby' => 'meta_value_num',
'meta_query' => WC()->query->get_meta_query()
);
$best_sell_products_query = query_posts($query_args);
return $best_sell_products_query;

Resources