I have create a loop with a custom query. This query contains a php parameters that i m getting from url with GET method. This the code at my loop page:
$cat = get_queried_object();
echo '<h1 class="childcatdes">'. $cat->name . '</h1>';
echo '<p class="childcatdescr">'. $cat->description . '<br><br></p>';
do_action( 'woocommerce_before_single_product' );
$posts_per_page = 12;
$paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
$product_args = array(
'post_type' => 'product',
'posts_per_page' => $posts_per_page,
'paged' => $paged,
'page' => $paged,
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'product_cat',
'field' => 'name',
'terms' => $cat->name,
),
array(
'taxonomy' => 'manufacturers',
'field' => 'slug',
'terms' => $_GET['filter_manufacturers'],
'operator' => 'IN'
)
),
'orderby' => 'name',
'order' => 'ASC',
);
$custom_query = new WP_Query( $product_args );
if($custom_query->have_posts()) {
echo '<ul';
while ($custom_query->have_posts() ) : $custom_query->the_post();
echo '<li>';
$link = get_the_permalink();
echo '' . get_the_title() . '';
echo '</li>';
endwhile;
echo '</ul>';
}
else {
echo 'No post found.';
}
?>
<nav class="pagination">
<?php pagination_bar( $custom_query); ?>
</nav>
And i use this code to my functions.php file for the function pagination_bar
function pagination_bar( $custom_query) {
$total_pages = $custom_query->max_num_pages;
$big = 999999999; // need an unlikely integer
if ($total_pages > 1){
$current_page = max(1, get_query_var('paged'));
echo paginate_links(array(
'base' => preg_replace('/\?.*/', '/', get_pagenum_link(1)) . '%_%',
'current' => $current_page,
'format' => 'page/%#%/',
'total' => $custom_query->max_num_pages,
'add_args' => array(
'filter_manufacturers' => $_GET['filter_manufacturers'],
)
));
}
}
The problem is that the pagination (even if it counts the posts correct at first page) is not working correct. I 'm getting 404 error at second page.
Related
I'm trying to show 10 posts per page with pagination on WordPress and the first page return 125 posts instead of 10 and the rest of the pages return 10 posts as requested, please assist :)
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$output = array();
global $post;
$args = array('nopaging' => false, 'paged' => $paged, 'posts_per_page' => 10, 'post_type' => 'post', 'order'=> 'DES', 'orderby' => 'date');
$postslist = new WP_Query( $args );
if ( $postslist->have_posts() ) :
while ( $postslist->have_posts() ) : $postslist->the_post();
array_push($output, array("timestamp" => get_the_date('U'),"img_url" => get_the_post_thumbnail_url(), "title" => get_the_title(), "text" => get_the_content()));
endwhile;
wp_reset_postdata();
endif;
Here is the sample code which you can use for the pagination:
<?php
/**
* Looping through the content
*/
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
$loop = new WP_Query (array(
'post_type' => 'custom_portfolio',
'orderby' => 'post_id',
'posts_per_page' => 10,
'paged' => $paged,
'order' => 'DESC'
)); ?>
<?php while ($loop -> have_posts()) : $loop -> the_post(); ?>
<?php endwhile; ?><?php wp_reset_query(); ?><?php wp_reset_postdata(); ?>
And here is the part for the pagination:
<!-- Pagination -->
<div class="pagination">
<?php
echo paginate_links( array(
'base' => str_replace( 999999999, '%#%', esc_url( get_pagenum_link( 999999999 ) ) ),
'total' => $loop->max_num_pages,
'current' => max( 1, get_query_var( 'paged' ) ),
'format' => '?paged=%#%',
'show_all' => false,
'type' => 'plain',
'end_size' => 2,
'mid_size' => 1,
'prev_next' => true,
'prev_text' => sprintf( '<i></i> %1$s', __( 'Previous Page', 'text-domain' ) ),
'next_text' => sprintf( '%1$s <i></i>', __( 'Next Page', 'text-domain' ) ),
'add_args' => false,
'add_fragment' => '',
) );
?>
</div>
Here is a good start for you, just adopt as you want.
The sticky posts was the problem, I have excluded the sticky_posts from the query, and it fixed the problem
'ignore_sticky_posts' => 1
I've created a custom shortcode to display products with a minimum stock amount and would like to add pagination to the results as well as calling the woocommerce-ordering dropdown to be displayed on the page.
Here's the shortcode:
// Minimum Stock Shortcode
add_shortcode( 'minimum_stock', 'minimum_stock_shortcode' );
function minimum_stock_shortcode( $atts ) {
global $woocommerce_loop;
// Attributes
$atts = shortcode_atts(
array(
'limit' => '40',
'columns' => '5',
'orderby' => 'title',
'order' => 'asc',
'category' => '',
'cat_operator' => 'IN',
'stock' => '',
),
$atts, 'minimum_stock'
);
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'posts_per_page' => $atts['limit'],
'orderby' => $atts['orderby'],
'order' => $atts['order'],
'meta_query' => array(
array(
'key' => '_stock',
'value' => $atts['stock'],
'compare' => '>='
)
),
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $atts['category'],
)
)
);
ob_start();
$products = new WP_Query( $args );
$woocommerce_loop['columns'] = $atts['columns'];
if ( $products->have_posts() ) : ?>
<?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">' . ob_get_clean() . '</div>';
}
Any help would be very much appreciated!
Kind regards,
JP
Okay, so I've got pagination working and tidied things up a bit (it was throwing some errors in the debug log), the code now looks like this:
// Minimum Stock Shortcode
add_shortcode( 'minimum_stock', 'minimum_stock_shortcode' );
function minimum_stock_shortcode( $atts ) {
global $product, $woocommerce, $woocommerce_loop;
// Attributes
$atts = shortcode_atts(
array(
'limit' => '40',
'columns' => '5',
'orderby' => 'title',
'order' => 'asc',
'category' => '',
'cat_operator' => 'IN',
'stock' => '',
),
$atts, 'minimum_stock'
);
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'posts_per_page' => $atts['limit'],
'orderby' => $atts['orderby'],
'order' => $atts['order'],
'paged' => $paged,
'meta_query' => array(
array(
'key' => '_stock',
'value' => $atts['stock'],
'compare' => '>='
)
),
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $atts['category'],
)
)
);
if ( isset( $ordering_args['meta_key'] ) ) {
$args['meta_key'] = $ordering_args['meta_key'];
}
ob_start();
$products = new WP_Query( $args );
$woocommerce_loop['columns'] = $atts['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' ); ?>
<?php endwhile; // end of the loop. ?>
<?php woocommerce_product_loop_end(); ?>
<?php endif;
if($products->max_num_pages>1){
?>
<nav class="woocommerce-pagination">
<?php echo paginate_links( apply_filters(
'woocommerce_pagination_args', array(
'base' => esc_url( str_replace( 999999999, '%#%', remove_query_arg( 'add-to-cart', get_pagenum_link( 999999999, false ) ) ) ),
'format' => '',
'current' => max( 1, get_query_var( 'paged' ) ),
'total' => $products->max_num_pages,
'prev_text' => '←',
'next_text' => '→',
'type' => 'list',
'end_size' => 3,
'mid_size' => 3
)
)
);
?>
</nav>
<?php }
woocommerce_reset_loop();
wp_reset_postdata();
$return = '<div class="woocommerce columns-' . $atts['columns'] . '">' . ob_get_clean() . '</div>';
// Remove ordering query arguments
WC()->query->remove_ordering_args();
return $return;
}
Does anyone know how I can now call the woocommerce-ordering dropdown?
I've tried adding:
<?php do_action( 'woocommerce_before_shop_loop' ); ?>
But this doesn't seem to work, when I check the page it does have the 'woocommerce-notices-wrapper' but there's no sign of the 'woocommerce_catalog_ordering' that I thought should also be called with 'woocommerce_before_shop_loop'.
Any and all help will be very much appreciated :)
Update:
I found this question Adding 'sort by' drop down on custom page using woocommerce short code which gave me the answer I needed to add the woocommerce-ordering dropdown.
Here's my updated code:
// Minimum Stock Shortcode
add_shortcode( 'minimum_stock', 'minimum_stock_shortcode' );
function minimum_stock_shortcode( $atts ) {
global $woocommerce_loop;
// Attributes
$atts = shortcode_atts(
array(
'limit' => '40',
'columns' => '5',
'orderby' => 'date',
'order' => 'desc',
'category' => '',
'cat_operator' => 'IN',
'stock' => '',
), $atts );
if ( ! $atts['category'] ) {
return '';
}
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
// Default ordering args
$ordering_args = WC()->query->get_catalog_ordering_args( $atts['orderby'],
$atts['order'] );
$orderby = 'date';
$order = 'desc';
if ( isset( $_GET['orderby'] ) ) {
$getorderby = $_GET['orderby'];
}
if ($getorderby == 'date') {
$orderby = 'date';
$order = 'desc';
} elseif ($getorderby == 'sku_desc') {
$orderby = 'meta_value';
$order = 'desc';
$meta_key = '_sku';
} elseif ($getorderby == 'sku_asc') {
$orderby = 'meta_value';
$order = 'asc';
$meta_key = '_sku';
}
$args = array(
'post_type' => array( 'product', 'product_variation' ),
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'posts_per_page' => $atts['limit'],
'orderby' => $orderby, // $ordering_args['orderby'],
'order' => $order, // $ordering_args['order'],
'paged' => $paged,
'meta_query' => array(
array(
'key' => '_stock',
'value' => $atts['stock'],
'compare' => '>='
)
),
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $atts['category'],
)
)
);
if ( isset( $ordering_args['meta_key'] ) ) {
$args['meta_key'] = $ordering_args['meta_key'];
}
ob_start();
$products = new WP_Query( $args );
$woocommerce_loop['columns'] = $atts['columns'];
if ( $products->have_posts() ) : ?>
<div style="width:100%;">
<div style="float:right">
<form class="woocommerce-ordering" method="get">
<select name="orderby" class="orderby">
<?php
$catalog_orderby = apply_filters( 'woocommerce_catalog_orderby', array(
'date' => __( 'Sort by latest', 'woocommerce' ),
'sku_asc' => __( 'A-Z / Low to High Numbers', 'woocommerce' ),
'sku_desc' => __( 'Z-A / High to Low Numbers', 'woocommerce' )
) );
foreach ( $catalog_orderby as $id => $name )
echo '<option value="' . esc_attr( $id ) . '" ' . selected( $getorderby, $id, false ) . '>' . esc_attr( $name ) . '</option>';
?>
</select>
<?php
// Keep query string vars intact
foreach ( $_GET as $key => $val ) {
if ( 'orderby' === $key || 'submit' === $key )
continue;
if ( is_array( $val ) ) {
foreach( $val as $innerVal ) {
echo '<input type="hidden" name="' . esc_attr( $key ) . '[]" value="' . esc_attr( $innerVal ) . '" />';
}
} else {
echo '<input type="hidden" name="' . esc_attr( $key ) . '" value="' . esc_attr( $val ) . '" />';
}
}
?>
</form>
</div>
</div>
<div style="clear:both;"></div>
<?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 endif;
if($products->max_num_pages>1){
?>
<nav class="woocommerce-pagination">
<?php echo paginate_links( apply_filters(
'woocommerce_pagination_args', array(
'base' => esc_url( str_replace( 999999999, '%#%', remove_query_arg( 'add-to-cart', get_pagenum_link( 999999999, false ) ) ) ),
'format' => '',
'current' => max( 1, get_query_var( 'paged' ) ),
'total' => $products->max_num_pages,
'prev_text' => '←',
'next_text' => '→',
'type' => 'list',
'end_size' => 3,
'mid_size' => 3
)
)
);
?>
</nav>
<?php }
woocommerce_reset_loop();
wp_reset_postdata();
$return = '<div class="woocommerce columns-' . $atts['columns'] . '">' . ob_get_clean() . '</div>';
// Remove ordering query arguments
WC()->query->remove_ordering_args();
return $return;
}
I hope someone might find this helpful :)
Kind regards,
JP
I am making user dashboard and I create a dashboard widget for category. Now I want to show category if current user's post is attached to them.
Currently I am able to see all categories.
Here is my function
function user_categories() {
wp_add_dashboard_widget(
'wp_widget_category', // Widget slug.
'Categories', // Title.
'my_dashboard_category' // Display function.
);
function my_dashboard_category() {
if ( is_user_logged_in() ):
$current_user = wp_get_current_user();
if ( ($current_user instanceof WP_User) ) {
?>
<?php
$args = array(
'type' => 'recipes',
'child_of' => 0,
'parent' => '',
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => 1,
'author' => $current_user->ID,
'hierarchical' => 1,
'exclude' => '',
'include' => '',
'number' => '',
'taxonomy' => 'recipe_categories',
'pad_counts' => false );
$categories = get_categories($args);
foreach ($categories as $category) {
$url = get_term_link($category);?>
<div class="submitted_recipe">
<a href="<?php echo $url;?>"><?php echo do_shortcode(sprintf('[wp_custom_image_category size="large_blog" term_id="%s"]',$category->term_id)); ?>
<h2><?php echo $category->name; ?></h2>
</a>
</div>
<?php
}
?>
<?php
}
endif;
}
}
add_action( 'wp_dashboard_setup', 'user_categories' );
You need to query all user posts in each categorie, if it's not empty then include this category. try this revised code
function user_categories() {
wp_add_dashboard_widget(
'wp_widget_category', // Widget slug.
'Categories', // Title.
'my_dashboard_category' // Display function.
);
function my_dashboard_category() {
if ( is_user_logged_in() ):
$current_user = wp_get_current_user();
if ( ($current_user instanceof WP_User) ) {
?>
<?php
$args = array(
'child_of' => 0,
'parent' => '',
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => 1,
'hierarchical' => 1,
'exclude' => '',
'include' => '',
'number' => '',
'taxonomy' => 'recipe_categories',
'pad_counts' => false );
$categories = get_categories($args);
foreach ($categories as $category) {
$posts_query = new WP_Query( array(
'post_type' => 'recipes',
'author' => $current_user->ID,
'tax_query' => array(
array('taxonomy' => 'recipe_categories',
'field' => 'slug',
'terms' => $category->slug)
),
'fields' => 'ids'
) );
$ids = $posts_query->posts;
if (!empty ($ids)) {
$url = get_term_link($category);?>
<div class="submitted_recipe">
<a href="<?php echo $url;?>"><?php echo do_shortcode(sprintf('[wp_custom_image_category size="large_blog" term_id="%s"]',$category->term_id)); ?>
<h2><?php echo $category->name; ?></h2>
</a>
</div>
<?php
}
}
?>
<?php
}
endif;
}
}
add_action( 'wp_dashboard_setup', 'user_categories' );
I'm moving a standard WordPress theme into Twig templates using the Timber plugin.
My goal is to list a custom post type called cpt_shows (events) by date but have them listed and grouped by artist. For example:
Artist A
event - April 1
event - May 1
event - June 1
Artist B
event - April 1
event - May 1
event - June 1
Artist C
event - April 1
event - May 1
event - June 1
I had this working without using twig with the following code in my original template:
$today = current_time('Ymd');
$args = array(
'orderby' => 'post_title',
'category_name' => 'events',
'exclude' => 28
);
$cats = get_categories( $args );
foreach( $cats as $cat ) :
$args = array(
'post_type' => 'cpt_shows',
'meta_query' => array(
array(
'key' => 'date',
'compare' => '>=',
'value' => $today,
'type' => 'NUMERIC,'
)
),
'meta_key' => 'date',
'orderby' => 'meta_value',
'order' => 'ASC',
'posts_per_page' => -1,
'category__in' => array( $cat->term_id ),
'ignore_sticky_posts' => 1
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
echo '<h2><a href="' . get_category_link( $cat->term_id ) . '" title="' . sprintf( __( "View all posts in %s" ), $cat->name ) . '" ' . '>' . $cat->name.'</a></h2> ';
while( $query->have_posts() ) : $query->the_post();
?>
<?php the_title(); ?><br>
<?php
endwhile;
wp_reset_postdata();
}
endforeach;
What I can't wrap my head around is how to move this into my Twig template because i have templating in my logic code, specifically the 'category__in' => array( $cat->term_id ), is being set in the loop. I've tried things in Twig like
{% for cat in categories %}
{% for post in loopSetupinContext %}
without success. Is there a better way to do this intially? In shortL i have a solution for my output but i'm unsure how to move it into Timber/Twig.
Any help is greatly appreciated.
Here is an example of what I meant in the comments.
I did not test the code, so it could contain some syntax errors. I changed the Twig_SimpleFilter to Twig_SimpleFuction.
function add_to_twig($twig) {
/* this is where you can add your own fuctions to twig */
$twig->addExtension(new Twig_Extension_StringLoader());
$twig->addFunction(new Twig_SimpleFunction('events', 'events_listing'));
return $twig;
}
function events_listing() {
$today = current_time('Ymd');
$args = array(
'orderby' => 'post_title',
'category_name' => 'events',
'exclude' => 28
);
$cats = get_categories( $args );
//init the array
$data = array();
foreach( $cats as $cat ) {
$args = array(
'post_type' => 'cpt_shows',
'meta_query' => array(
array(
'key' => 'date',
'compare' => '>=',
'value' => $today,
'type' => 'NUMERIC,'
)
),
'meta_key' => 'date',
'orderby' => 'meta_value',
'order' => 'ASC',
'posts_per_page'=> -1,
'category__in' => array( $cat->term_id ),
'ignore_sticky_posts' => 1
);
$query = new WP_Query( $args );
if ($query->have_posts()) {
//Prepare the array to keep track of the category
//And init an extra array for keeping the posts together
$data[$cat->term_id] = array(
'category' => array(
'url' => get_category_link( $cat->term_id ),
'title' => sprintf( __( "View all posts in %s" ), $cat->name),
'text' => $cat->name,
),
'posts' => array(),
);
while( $query->have_posts() ){
$query->the_post();
//append the post to the array
$data[$cat->term_id]['posts'][] = array(
'url' => the_permalink(),
'text' => the_title(),
);
}
wp_reset_postdata();
}
}
return $data;
}
twig
{% for event in events() %}
<h2>{{ event.category.text }}</h2>
{% for post in event.posts %}
{{ post.text }}<br />
{% endfor %}
{% endfor %}
Ok. Looking into Timber more I figured this out, however, I'm still not sure this is the best approach so please comment if not.
Instead of trying to put this in my php template page (archive.php), I made it a function and added a filter in functions.php.
function add_to_twig($twig) {
/* this is where you can add your own fuctions to twig */
$twig->addExtension(new Twig_Extension_StringLoader());
$twig->addFilter(new Twig_SimpleFilter('events', 'events_listing'));
return $twig;
}
function events_listing() {
$today = current_time('Ymd');
$args = array(
'orderby' => 'post_title',
'category_name' => 'events',
'exclude' => 28
);
$cats = get_categories( $args );
foreach( $cats as $cat ) :
$args = array(
'post_type' => 'cpt_shows',
'meta_query' => array(
array(
'key' => 'date',
'compare' => '>=',
'value' => $today,
'type' => 'NUMERIC,'
)
),
'meta_key' => 'date',
'orderby' => 'meta_value',
'order' => 'ASC',
'posts_per_page' => -1,
'category__in' => array( $cat->term_id ),
'ignore_sticky_posts' => 1
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
echo '<h2><a href="' . get_category_link( $cat->term_id ) . '" title="' . sprintf( __( "View all posts in %s" ), $cat->name ) . '" ' . '>' . $cat->name.'</a></h2> ';
while( $query->have_posts() ) : $query->the_post();
?>
<?php the_title(); ?><br>
<?php
endwhile;
wp_reset_postdata();
}
endforeach;
}
And then call it in my Twig template like this:
{{ post.content|events }}
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;