I'm trying to display products in Woocommerce Related Products according to custom taxonomies, created with CPT UI. I tried this :
add_filter( 'woocommerce_output_related_products_args', 'prfx_change_related_products_count' );
function prfx_change_related_products_count( $args ) {
// Current post as global
global $post;
$terms = get_the_terms( $post->ID, 'artists' );
// Empty array
$ids = array();
foreach ( $terms as $term ) {
array_push($ids, $term->term_id);
}
$args['tax_query'] = array(
array(
'taxonomy' => 'artists',
'terms' => $ids,
'field' => 'term_id',
'include_children' => true,
'operator' => 'IN'
)
);
return $args;
}
The code comes from this previous post Display Woocommerce Related Products By Custom Taxonomy but it doesn't seem to work.
Ideally i would like 6 products to be displayed according to 4 custom taxonomies:
artists > labels > genre > formats.
For example if there are only 2 products from the same artists then the rest would be randomly chosen from labels and so on.
Related
In a woocommerce installation I added custom taxonomies for products. One of them is season with a term 'sale'.
I want to exclude these sale items from the shop page. So I used below function, but it doesn't seem to work. Is this function actually working for a custom taxonomy?
Source code: https://woocommerce.com/document/exclude-a-category-from-the-shop-page/
add_action( 'woocommerce_product_query', 'custom_pre_get_posts_query' );
function custom_pre_get_posts_query( $q ) {
global $woocommerce;
$tax_query = (array) $q->get( 'tax_query' );
$tax_query[] = array(
'taxonomy' => 'season', // taxonomy
'field' => 'slug',
'terms' => array( 'sale' ), //slug taxonomies
'operator' => 'NOT IN'
);
$q->set( 'tax_query', $tax_query );
}
Please don't judge this question harshly.
I have tried showing in Related Products only products from the same category in which the user is viewing the product right now, and by product tags (if applicable). But nothing has changed for me.
It turns out that WooCommerce already displays recommended products from the same category and by the same tags by default.
Below you will find the answer to this question. But let this code remain here simply as a sample code.
function related_products_by_current_category( $related_posts, $product, $args ) {
global $post;
$cat = $product->get_category_ids();
$tags = wp_get_post_terms( $post->ID, "product_tag" );
foreach ( $tags as $tag ) {
$tags_array[] .= $tag->term_id;
}
$related_posts = new WP_Query(
array(
'orderby' => 'rand',
'posts_per_page' => 4,
'post__not_in' => array($post->ID),
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'product_cat',
'field' => 'id',
'terms' => $cat
)
array(
'taxonomy' => 'product_tag',
'field' => 'id',
'terms' => $tags_array
)
)
)
);
return $related_posts;
}
add_filter( 'woocommerce_related_products', 'related_products_by_current_category', 999, 3 );
WooCommerce already fetches related products based on the same terms( categories and tags )
If you want to get more control over the related products by categories and tags, you can use these two filters
apply_filters( 'woocommerce_get_related_product_cat_terms', wc_get_product_term_ids( $product_id, 'product_cat' ), $product_id );
apply_filters( 'woocommerce_get_related_product_tag_terms', wc_get_product_term_ids( $product_id, 'product_tag' ), $product_id );
These filters return the current product categories | tags IDs which will be used to get related products. you can use these filters to return specific terms IDs based on the given product ID .
In my wooCommerce platform, I do not want to show products that do not have a category selected. I mean which products categories is empty that's products are not display in my site.
Is it any way to do that?
There are different ways to retrieve products, and if you want to exclude products which have no category assigned to from everywhere in your site, then you will need to address all of them.
WP_Query
You can hook into the pre_get_posts action and modify the tax_query arg in order to exclude products in the uncategorized product category (only when the query post type is product). I'm in fact assuming uncategorized being the slug of the default product category (you will need to amend it to your specific configuration). E.g.:
function remove_uncategorized_products( $query ) {
if ( is_admin() ) {
return;
}
if ( 'product' !== $query->get( 'post_type' ) ) {
return;
}
$tax_query = (array) $query->get( 'tax_query' );
$tax_query[] = array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array( 'uncategorized' ),
'operator' => 'NOT IN',
);
$query->set( 'tax_query', $tax_query );
}
add_action( 'pre_get_posts', 'remove_uncategorized_products' );
WC_Query
Similar to WP_Query, you can hook into the woocommerce_product_query action to modify the query. E.g.:
function custom_pre_get_posts_query( $q ) {
$tax_query = (array) $q->get( 'tax_query' );
$tax_query[] = array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array( 'uncategorized' ),
'operator' => 'NOT IN'
);
$q->set( 'tax_query', $tax_query );
}
add_action( 'woocommerce_product_query', 'custom_pre_get_posts_query' );
WC_Product_Query (used by wc_get_products)
In this case, we can't change the query args to exclude certain product categories. We can instead loop through each product returned by the query and check its category. E.g.:
function filter_uncategorized_products_out( $results, $args ) {
$products = array();
foreach ( $results as $p ) {
$is_uncategorized = false;
$terms = get_the_terms( $p->get_id(), 'product_cat' );
foreach ( $terms as $term ) {
if ( 'uncategorized' === $term->slug ) {
$is_uncategorized = true;
}
}
if ( ! $is_uncategorized ) {
$products[] = $p;
}
}
return $products;
}
add_filter( 'woocommerce_product_object_query', 'filter_uncategorized_products_out', 10, 2 );
Please note that there are other ways to retrieve products (for example using $wpdb directly). You might need to check all the pages of your site to see if you have covered them all.
I want to display related products based on Custom taxonomy. Is there a way to force related products to be displayed based on Custom taxonomy?
add_filter( 'woocommerce_output_related_products_args', 'prfx_change_related_products_count' );
function prfx_change_related_products_count( $args ) {
// Current post as global
global $post;
$terms = get_the_terms( $post->ID, 'your_custom_taxonomy' );
// Empty array
$ids = array();
foreach ( $terms as $term ) {
array_push($ids, $term->term_id);
}
$args['tax_query'] = array(
array(
'taxonomy' => 'your_custom_taxonomy',
'terms' => $ids,
'field' => 'term_id',
'include_children' => true,
'operator' => 'IN'
)
);
return $args;
}
I have multiple categories apllied to product, but woocommerce breadcrumbs choose only one line to show. I want to follow his line to show related products based on category shown in breadcrumbs.
Woocommerce breadcrumb.php file has
foreach ( $breadcrumb as $key => $crumb ) {
}
I want to know from where $breadcrumb goes to get same $crumb.
This solution for those who has product in several categories.
I found wc_get_product_terms(), this is how breadcrumbs created. So if you want to display related products based on category shown in breadcrumbs, you can do similar to this:
$term = wc_get_product_terms($product->get_id(), 'product_cat', array('orderby' => 'parent', 'order' => 'DESC'));
$args = array(
'post_type' => 'product',
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'id',
'terms' => $term[0]->term_id
),
)
);
$products = new WP_Query($args);
But I found a better way with yoast seo plugin:
$primary_term_product_id = yoast_get_primary_term_id('product_cat');
and then use $primary_term_product_id instead of $term[0]->term_id.
This solution for those who has product in several categories.