I have a custom archive-product template for displaying my product categories with headers in the shop front page. It also allows me to hide certain categories from the shop page. These edits were applied to the newest version of the archive-product.php. The problem is that when I go to the specific category page, no products are shown, it is just blank. If I revert the archive-product template back to default, the product category pages are then populated. Below is the php added to the template, is there something that seems to be wrong with it?
Thanks!
<?php
if ( woocommerce_product_loop() ) {
/**
* Hook: woocommerce_before_shop_loop.
*
* #hooked woocommerce_output_all_notices - 10
* #hooked woocommerce_result_count - 20
* #hooked woocommerce_catalog_ordering - 30
*/
do_action( 'woocommerce_before_shop_loop' );
/* Category - SubCategory START */
$term = get_queried_object();
$parent_id = empty( $term->term_id ) ? 0 : $term->term_id;
$excludedCats = array(47);
$product_categories = get_categories( array( 'taxonomy' => 'product_cat', 'child_of' => $parent_id, 'exclude' => $excludedCats) );
$i = 1;
foreach ($product_categories as $product_category) {
echo '<h2>'.$product_category->name.'</h2>';
woocommerce_product_loop_start(); //open ul
$args = array(
'posts_per_page' => -1,
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $product_category->slug
),
),
'post_type' => 'product',
'orderby' => 'menu_order',
'order' => 'asc',
);
$cat_query = new WP_Query( $args );
while ( $cat_query->have_posts() ) : $cat_query->the_post();
wc_get_template_part( 'content', 'product' );
endwhile; // end of the loop.
wp_reset_postdata();
woocommerce_product_loop_end(); //close ul
if ( $i < count($product_categories) )
echo '<div class="content-seperator"></div>';
$i++;
}//foreach
- Try using following code and let me know if it works
$obj = get_queried_object();
if(is_shop()){
$parent_id = empty( $obj->parent ) ? 0 : $obj->parent;
}else if(is_product_category()){
$obj = get_queried_object();
$parent_id = empty( $obj->term_id ) ? 0 : $obj->term_id;
$cat_slug = empty( $obj->slug ) ? 0 : $obj->slug;
}
$excludedCats = array(47);
if($parent_id != 0){
$product_categories = get_terms( array( 'taxonomy' => 'product_cat','slug'=>$cat_slug,'exclude' => $excludedCats) );
}else{
$product_categories = get_terms( array( 'taxonomy' => 'product_cat', 'exclude' => $excludedCats) );
}
$i = 1;
foreach ($product_categories as $product_category) {
echo '<h2>'.$product_category->name.'</h2>';
woocommerce_product_loop_start(); //open ul
$args = array(
'posts_per_page' => -1,
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $product_category->slug
),
),
'post_parent' => $product_category->parent,
'post_type' => 'product',
'orderby' => 'menu_order',
'order' => 'asc',
);
$cat_query = new WP_Query( $args );
while ( $cat_query->have_posts() ) : $cat_query->the_post();
wc_get_template_part( 'content', 'product' );
endwhile;
wp_reset_postdata();
woocommerce_product_loop_end();
if ( $i < count($product_categories) )
echo '<div class="content-seperator"></div>';
$i++;
}
Related
I am developing a woocommerce website, and i want to show product list according to a category on the product-category page i.e: www.wesiteName.com/product-category/ladies. I want to show all the ladies products on this link but how? My code didn't work.
I am using this function woocommerce_page_title() to get category name but it print the category name but didn't pass name in wp query don't know why.
if (is_product_category()) :
$title = woocommerce_page_title();
$args = array(
'post_type' => 'product',
'posts_per_page' => 12,
'product_cat' => $title,
'orderby' => 'post_title',
'order' => 'DESC',
);
$loop = new WP_Query( $args );
endif;
It shows all the products from all categories. I just want to show a particular product list according to a category.
Try this code.
$args = array(
'number' => $number,
'orderby' => 'title',
'order' => 'ASC',
'hide_empty' => $hide_empty,
'include' => $ids
);
$product_categories = get_terms( 'product_cat', $args );
$count = count($product_categories);
if ( $count > 0 ){
foreach ( $product_categories as $product_category ) {
echo '<h4><a href="' . get_term_link( $product_category ) . '">' .
$product_category->name . '</a></h4>';
$args = array(
'posts_per_page' => -1,
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
// 'terms' => 'white-wines'
'terms' => $product_category->slug
)
),
'post_type' => 'product',
'orderby' => 'title,'
);
$products = new WP_Query( $args );
echo "<ul>";
while ( $products->have_posts() ) {
$products->the_post();
?>
<li>
<a href="<?php the_permalink(); ?>">
<?php the_title(); ?>
</a>
</li>
<?php
}
echo "</ul>";
}
}
Hope its working for you
I have at least 4 Parent Categories and each parent category has a sub-category.
The categories in WordPress looks like this:
Lidingö (Parent Category)
Direktåtkomst Förrådslänga(SubCategory)
7 kvm (product)
6 kvm (product)
Entréplan (SubCategory)
1 kbm (product)
1.5 kvm (product)
Nacka (Parent Category)
Sample(SubCategory)
aa (product)
bbb (product)
I want to query the products in WordPress and they should be grouped by categories.
This is my current code:
<?php
$args = array(
'post_type' => 'product',
array(
'taxonomy' => 'product_cat'
),
'posts_per_page' => 6,
);
$loop = new WP_Query( $args );
if ( $loop->have_posts() ) {
while ( $loop->have_posts() ) : $loop->the_post();
echo woocommerce_template_single_title();
endwhile;
} else {
echo __( 'No products found' );
}
wp_reset_postdata();
?>
I think the code above is not correct because the same products are being displayed for every pagination.
Do you have any idea what is the correct query to group all woocommerce products by category? Thanks
First you need to overwrite this woocommerce template to your current theme as you have to use custom loop to get products by category.
Just copy that template of woocommerce to your current_theme->create folder name (Woocommerce) -> Paste template to that folder.
Use Below Code:
$parent_terms= get_terms( array( 'taxonomy' => 'product_cat', 'parent' => 0 ) );
if($parent_terms= )
{
foreach( $parent_terms as $parent_term )
{
$child_terms = get_terms( array( 'taxonomy' => 'product_cat', 'parent' => $parent_term->term_id ) );
if($child_terms)
{
foreach( $child_terms as $child_term )
{
$product_args=
array(
'posts_per_page' => 50,
'post_type' => 'my_custom_type',
'posts_per_page' => 6,
'cat' => $child_term->term_id
);
$product_query = new WP_Query( $product_args );
while($product_query->have_posts()) : $product_query->the_post();
{
Here you will get product detail so you can display product details as you wanted
}
}
}
}
}
Your query is asking for all products that belong to the product category taxonomy - that is, all of them.
You need to narrow the search by adding the category you wish to search to the arguments. For example, if you wanted to search via the category slug, you would use:
$args = array(
'post_type' => 'product',
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => 'category-slug1'
),
'posts_per_page' => 6,
);
To loop through all the categories on one page, you'll want something like this:
$my_categories = get_terms( 'TERM_NAME_HERE' );
$my_categories_count = count( $my_categories );
if ( $my_categories_count > 0 && is_array( $my_categories ) ) {
echo '<div class="wrap">';
foreach ( $my_categories as $single_cat ) { ?>
<h2><?php echo $single_cat->name; ?></h2>
<?php
$cat_posts_args = array(
'post_type' => 'product',
'order' => 'ASC',
'orderby' => 'date',
'post_status' => 'publish',
'posts_per_page' => -1,
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'id',
'terms' => $single_cat->term_id,
'include_children' => false
)
)
);
$cat_posts = new WP_Query( $cat_posts_args );
if ( $cat_posts->have_posts() ) :
echo '<p>';
while ( $cat_posts->have_posts() ) : $cat_posts->the_post(); ?>
<span><?php the_title(); ?></span>: <?php echo get_the_excerpt(); ?><br>
<?php endwhile;
echo '</p>';
else :
if ( !$parent ) echo '<p>No products found.</p>';
endif;
wp_reset_postdata();
} // end foreach
echo '</div>';
}
On the main shop page (archive-product.php) on my Woocommerce shop, I want to be able to display all the products but separate them by categories. So I would need to be able to create a loop for each product category.
For a visual reference, this is what I'm trying to achieve: for reference
Each gray block represents a new category and will loop through the products in that category.
Is there a way to achieve this?
Well as you mentioned in the comment, if you don't need any pagination, to list all products leading by their category you can first loop through the categories using get_terms() function and get whatever information you need on each iteration ( e.g: category name ), and then create one custom query per category and show the query's products, something like this will get you what you're trying to do:
<?php
foreach( get_terms( array( 'taxonomy' => 'product_cat' ) ) as $category ) :
$products_loop = new WP_Query( array(
'post_type' => 'product',
'showposts' => -1,
'tax_query' => array_merge( array(
'relation' => 'AND',
array(
'taxonomy' => 'product_cat',
'terms' => array( $category->term_id ),
'field' => 'term_id'
)
), WC()->query->get_tax_query() ),
'meta_query' => array_merge( array(
// You can optionally add extra meta queries here
), WC()->query->get_meta_query() )
) );
?>
<h2 class="category-title"><?php echo $category->name; ?></h2>
<?php
while ( $products_loop->have_posts() ) {
$products_loop->the_post();
/**
* woocommerce_shop_loop hook.
*
* #hooked WC_Structured_Data::generate_product_data() - 10
*/
do_action( 'woocommerce_shop_loop' );
wc_get_template_part( 'content', 'product' );
}
wp_reset_postdata(); ?>
<?php endforeach; ?>
Try this code on your page template. It will get result for Woocommerce Separate Product Loops for Each Category.
$taxonomy = 'product_cat';
$orderby = 'name';
$show_count = 0; // 1 for yes, 0 for no
$pad_counts = 0; // 1 for yes, 0 for no
$hierarchical = 1; // 1 for yes, 0 for no
$title = '';
$empty = 0;
$args = array(
'taxonomy' => $taxonomy,
'orderby' => $orderby,
'show_count' => $show_count,
'pad_counts' => $pad_counts,
'hierarchical' => $hierarchical,
'title_li' => $title,
'hide_empty' => $empty
);
$all_categories = get_categories( $args );
foreach ($all_categories as $cat) {
if($cat->category_parent == 0) {
$category_id = $cat->term_id;
echo '<br />'. $cat->name .'';
//get product
$args = array(
'post_type' => 'product',
'product_cat' => $cat->name,
'posts_per_page' => $count,
'paged' => $paged,
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
?>
<span class="title"><h2> <?php the_title(); ?> </h2></span>
<?php
}
wp_reset_postdata();
}
}
}
The aim is to display 4 products on the product page however remove the current product from the filter. At present I am pulling through products with related brands and categories, however this is also pulling through the current product to the related products...
Current related.php file for Woocommerce contains the following:
if ( ! $related = $product->get_related( $posts_per_page ) ) {
return;
}
$brands_array = array(0);
$cats_array = array(0);
$cur_product_id = $product->id;
// get categories
$terms = wp_get_post_terms( $product->id, 'product_brand' );
$category_terms = wp_get_post_terms( $product->id, 'product_cat' );
// select only the category which doesn't have any children
foreach ( $terms as $term ) {
$brands_array[] = $term->term_id;
}
foreach ( $category_terms as $category_term ) {
$cats_array[] = $category_term->term_id;
}
$final_array = array_merge($brands_array, $cats_array);
$filtered_array = array_filter($final_array, "test_odd");
function test_odd($var)
{
return($var & 1);
}
var_dump($final_array);
$args = apply_filters( 'woocommerce_related_products_args', array(
'post_type' => 'product',
'ignore_sticky_posts' => 1,
'no_found_rows' => 1,
'posts_per_page' => 4,
'columns' => 4,
'orderby' => $orderby,
'tax_query' => array(
array(
'taxonomy' => 'product_brand',
'field' => 'id',
'terms' => $final_array
),
)
));
$products = new WP_Query( $args );
$woocommerce_loop['name'] = 'related';
$woocommerce_loop['columns'] = apply_filters( 'woocommerce_related_products_columns', $columns );
if ( $products->have_posts() ) : ?>
<div class="related products">
<h2><?php _e( 'Related Products', 'woocommerce' ); ?></h2>
<?php echo $filtered_array ?>
<?php woocommerce_product_loop_start();
while ( $products->have_posts() ) : $products->the_post();
wc_get_template_part( 'content', 'product' ); ?>
<?php endwhile; // end of the loop. ?>
<?php woocommerce_product_loop_end(); ?>
</div>
<?php endif;
wp_reset_postdata();
How do I go about filtering the current product from the array of products that are shown on the product page?
Thanks
To exclude current product, the missing argument in your WP_Query is 'post__not_in' (array). So your $args array is going to be:
$args = apply_filters( 'woocommerce_product_related_posts_query', array(
'post_type' => 'product',
'ignore_sticky_posts' => 1,
'post__not_in' => array( $product->get_id() ), // <==== HERE
'no_found_rows' => 1,
'posts_per_page' => 4,
'columns' => 4,
'orderby' => $orderby,
'tax_query' => array(
array(
'taxonomy' => 'product_brand',
'field' => 'id',
'terms' => $final_array
),
)
));
$products = new WP_Query( $args );
// . . .
See: woocommerce_product_related_posts_query replace woocommerce_related_products_args since WooCommerce 3+ (thanks to #strarsis).
all products are displayed. "posts_per_page" is not working. I try to limit products to 12 by page, but it shows all products.
Looks like my code is fine, but it isn't working.
Whats wrong with my code?
Can someone enlighten me, please?
Here's my code:
<?php
$meta_query = array();
$meta_query[] = array('key' => '_visibility','value' => array('visible', 'catalog'),'compare' => 'IN');
$meta_query[] = array('key' => '_stock_status','value' => 'instock','compare' => '=');
if($min_price !='' && $max_price !=''){
$meta_query[] = array('key' => '_price','value' => array($min_price, $max_price),'compare' => 'BETWEEN','type' => 'NUMERIC');
}
if($orderbym != '')
{
$mkey = '_price';
}
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$query_args = array(
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => 10,
'paged' => $paged,
'ignore_sticky_posts' => 1,
'orderby' => $orderby,
'order' => $order,
'posts_per_page' => -1,
'meta_query' => $meta_query,
'meta_key' => $mkey,
'tax_query' => array(
array(
'taxonomy' => 'product_type',
'field' => 'slug',
'terms' => 'bundle',
),
$product_catar
),
);
global $woocommerce_loop;
$products = new WP_Query( apply_filters( 'woocommerce_shortcode_products_query', $query_args));
$columns = '2';
$woocommerce_loop['columns'] = $columns;
ob_start();
if($products->have_posts()){
woocommerce_product_loop_start();
while ( $products->have_posts() ) {
$products->the_post();
wc_get_template_part( 'content', 'product' );
}
woocommerce_product_loop_end();
}else{
_e( 'No product matching your criteria.' );
}
woocommerce_reset_loop();
wp_reset_postdata();
echo '<div class="woocommerce columns-' . $columns . '">' . ob_get_clean() . '</div>';
?>
What comes to my mind is that the filter is maybe overwriting the query args. See what you get by doing
var_dump(apply_filters( 'woocommerce_shortcode_products_query', $query_args)) ;
My guess is you'll get different query args