Reputation: 113
I would like to display related products in my single product page that are related to the subcategory and not the parent category. Now i have about 100 products and about 90 of them belong to the same parent category (they also belong to other parent categories). So in a single product page you can see pretty much any random product because of that big parent category. Is there a way to limit this? I did a research and i came accross some answers that were about version 1.6 of woocommerce... Now i use 3.2.6, so it didn't work.
Upvotes: 0
Views: 4908
Reputation: 41
I have overridden the Related product file to the child theme and add the below custom code
Override First related product: yourtheme/woocommerce/single-product/related.php
Code:
<?php
/**
* Related Products
*
* This template can be overridden by copying it to yourtheme/woocommerce/single-product/related.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see https://docs.woocommerce.com/document/template-structure/
* @package WooCommerce\Templates
* @version 3.9.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
global $product, $woocommerce_loop;
if ( empty( $product ) || ! $product->exists() ) {
return;
}
if ( ! $related = $product->get_related( $posts_per_page ) ) {
return;
}
// Get ID of current product, to exclude it from the related products query
$current_product_id = $product->get_id();
$cats_array = array(0);
// get categories
$terms = wp_get_post_terms( $product->get_id(), 'product_cat' );
// select only the category which doesn't have any children
foreach ( $terms as $term ) {
$children = get_term_children( $term->term_id, 'product_cat' );
if ( !sizeof( $children ) )
$cats_array[] = $term->term_id;
}
$args = apply_filters( 'woocommerce_related_products_args', array(
'post_type' => 'product',
'post__not_in' => array( $current_product_id ), // exclude current product
'ignore_sticky_posts' => 1,
'no_found_rows' => 1,
'posts_per_page' => 5,
'orderby' => $orderby,
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'id',
'terms' => $cats_array
),
)
));
$products = new WP_Query( $args );
$woocommerce_loop['name'] = 'related';
$woocommerce_loop['columns'] = apply_filters( 'woocommerce_related_products_columns', $columns );
if ( $products->have_posts() ) :
if ( $related_products ) : ?>
<section class="related products">
<?php
$heading = apply_filters( 'woocommerce_product_related_products_heading', __( 'Related products', 'woocommerce' ) );
if ( $heading ) :
?>
<h2 class="hrtechpro-title"><?php echo esc_html( $heading ); ?></h2>
<?php endif; ?>
<?php woocommerce_product_loop_start(); ?>
<?php while ( $products->have_posts() ) : $products->the_post(); ?>
<?php
wc_get_template_part( 'content', 'product' );
?>
<?php endwhile; wp_reset_postdata();?>
<?php woocommerce_product_loop_end(); ?>
</section>
<?php
endif;
endif;
wp_reset_postdata();
If you have try this code and working succesfull don't forgot to upvote this effort.
Upvotes: 0
Reputation: 4320
This is a possible duplicate of Woocommerce: Only show related products from same subcategory
Another workaround would be to overwrite the template file [your-theme]/woocommerce/single-product/related.php
The following is updated to work with Woocommerce 3.x
<?php
/**
* Related Products
*
* This template can be overridden by copying it to yourtheme/woocommerce/single-product/related.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see https://docs.woocommerce.com/document/template-structure/
* @author WooThemes
* @package WooCommerce/Templates
* @version 3.9.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
global $product, $woocommerce_loop;
if ( empty( $product ) || ! $product->exists() ) {
return;
}
if ( ! $related = $product->get_related( $posts_per_page ) ) {
return;
}
// Get ID of current product, to exclude it from the related products query
$current_product_id = $product->get_id();
$cats_array = array(0);
// get categories
$terms = wp_get_post_terms( $product->id, 'product_cat' );
// select only the category which doesn't have any children
foreach ( $terms as $term ) {
$children = get_term_children( $term->term_id, 'product_cat' );
if ( !sizeof( $children ) )
$cats_array[] = $term->term_id;
}
$args = apply_filters( 'woocommerce_related_products_args', array(
'post_type' => 'product',
'post__not_in' => array( $current_product_id ), // exclude current product
'ignore_sticky_posts' => 1,
'no_found_rows' => 1,
'posts_per_page' => $posts_per_page,
'orderby' => $orderby,
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'id',
'terms' => $cats_array
),
)
));
$products = new WP_Query( $args );
$woocommerce_loop['name'] = 'related';
$woocommerce_loop['columns'] = apply_filters( 'woocommerce_related_products_columns', $columns );
if ( $products->have_posts() ) : ?>
<section class="related products">
<?php
$heading = apply_filters( 'woocommerce_product_related_products_heading', __( 'Related products', 'woocommerce' ) );
if ( $heading ) :
?>
<h2><?php echo esc_html( $heading ); ?></h2>
<?php endif; ?>
<?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(); ?>
</section>
<?php endif;
wp_reset_postdata();
Upvotes: 0
Reputation: 623
you can use this code or adapted to work for you case,, hope its work.. Add it to your function.php
add_filter( 'woocommerce_product_related_posts', 'woocommerce_get_direct_related_products' );
function woocommerce_get_direct_related_products() {
global $woocommerce, $product;
// Related products are found from category
$cats_array = array(0);
// Get categories
$terms = wp_get_post_terms( $product->id, 'product_cat' );
//Select only the category which doesn't have any children
foreach ( $terms as $term ) {
$children = get_term_children( $term->term_id, 'product_cat' );
if ( !sizeof( $children ) )
$cats_array[] = $term->term_id;
}
// Don't bother if none are set
if ( sizeof( $cats_array ) == 1 ) return array();
// Meta query
$meta_query = array();
$meta_query[] = $woocommerce->query->visibility_meta_query();
$meta_query[] = $woocommerce->query->stock_status_meta_query();
$limit = 5;
// Get the posts
return array(
'orderby' => 'rand',
'posts_per_page'=> $limit,
'post_type' => 'product',
'fields' => 'ids',
'meta_query' => $meta_query,
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'id',
'terms' => $cats_array
)
)
);
}
Upvotes: 1