-
S3ratin
Hello again,
I’ve made a Query Loop section for the product page with the next logic:
1. Taxonomy: Product Categories > Current post terms
2. Taxonomy: Party Theme (custom taxonomy) > Current post terms
3. Exclude Posts: Exclude current post
4. Post per page: 4So right now, when I’m on the product page Spiderman Cake Topper, and I have other 4 unique products (not product variations) that belong to the same product category taxonomy and custom taxonomy > my section “Buy similar products” will be populated with these 4 products, and that’s perfectly fine.
But if I’m on the product page, Godzilla cake topper and that is the only product in the whole store > my section will be empty and blank.
So, because our taxonomy product category has lots of other “cake toppers” I want to make the next logic:
1. Check the current product page and find its taxonomies
2. If nothing exists, then take other products only from the Product category taxonomy
3. Populate “Post per page”Can you please help me to achieve with GB query loop?
Here you can find the correct page right now: Link
Here is the page with the issue currently: Link -
David
Hi there,
is there just the one custom taxonomy ?
-
S3ratin
Hi David,
Yes, only one. Taxonomy key “main-category” made in ACF
Thanks
-
David
Ok, so it requires some PHP:
add_filter('generateblocks_query_loop_args', function ($query_args, $attributes) { if (!is_admin() && is_single() && !empty($attributes['className']) && strpos($attributes['className'], 'related-tax') !== false) { global $post; $current_post_id = $post->ID; // Get the terms of the current post for 'main-category' $main_category_terms = wp_get_post_terms($current_post_id, 'main-category', array('fields' => 'ids')); // Initialize additional_args $additional_args = array(); if (!empty($main_category_terms)) { // Initial query args for 'main-category' $main_category_query_args = array( 'post_type' => $query_args['post_type'], 'posts_per_page' => 1, // We only need to check if there are any posts 'post__not_in' => array($current_post_id), 'tax_query' => array( array( 'taxonomy' => 'main-category', 'field' => 'term_id', 'terms' => $main_category_terms, ), ), ); // Check if there are posts with the same 'main-category' terms $main_category_query = new WP_Query($main_category_query_args); if ($main_category_query->have_posts()) { // If there are posts, set the tax_query for 'main-category' $additional_args['tax_query'] = array( array( 'taxonomy' => 'main-category', 'field' => 'term_id', 'terms' => $main_category_terms, ), ); } else { // If no posts are found with 'main-category' terms, get the terms for 'product_cat' $product_cat_terms = wp_get_post_terms($current_post_id, 'product_cat', array('fields' => 'ids')); if (!empty($product_cat_terms)) { $additional_args['tax_query'] = array( array( 'taxonomy' => 'product_cat', 'field' => 'term_id', 'terms' => $product_cat_terms, ), ); } } // Clean up wp_reset_postdata(); } // Merge the additional_args with the existing query_args $query_args = array_merge($query_args, $additional_args); } return $query_args; }, 10, 2);
And in the Query Loop block, select its Grid Block and in Advanced > Additional CSS Classes add:
related-tax
, that will apply the above filter to that query.What the PHP does is run its own mini query to check if the current main-category post terms has a match. If it does it passes that tax_query paremeter into the query loop. If it does not then it passes the
product_cat
tax query args into the query loop. -
S3ratin
Thank you for providing the code. Unfortunately, at the moment, the section is displaying every product from the custom taxonomy “main-category,” including different types of products. I need to filter them with the second taxonomy “product category.”
To clarify, for example, let’s consider my custom taxonomy as “brand.” If a customer comes via Google with the keyword “brand + product type” and is not satisfied with the design of the product, I want to suggest the following:
Brand A = current custom taxonomy
Product type A = current product taxonomyScenario 1: “Brand A + Product type A” should populate 4 posts.
If “Brand A + Product type A” doesn’t have enough products to populate the section “Similar products,” then:Scenario 2: “Brand A + Product type A” should populate 1 post, but to populate the other 3 posts, the condition for the brand should be removed, and other products from “Product type A” should be shown.
In conclusion, the product type is crucial for the customer. If someone arrives via my Google Ads looking for birthday invitations, I don’t want to display backpacks to them. Only when “Brand A” lacks enough products from the same product category, I want to show them the same product category from other brands (Brand B, Brand C, Brand D, etc).
I hope this helps to better understand my needs.
-
David
Complicated one
And you may need to reach out to the brains on StackOverflow to write that kinda of query.
The best i can muster is this:add_filter('generateblocks_query_loop_args', function ($query_args, $attributes) { if ( !is_admin() && !empty($attributes['className']) && strpos($attributes['className'], 'related-tax') !== false ) { global $post; $current_post_id = $post->ID; // Query posts that match both 'main-category' and 'product_cat' terms $main_category_terms = wp_get_post_terms($current_post_id, 'main-category', array('fields' => 'ids')); $product_cat_terms = wp_get_post_terms($current_post_id, 'product_cat', array('fields' => 'ids')); $additional_args = array( 'post__not_in' => array($current_post_id), 'posts_per_page' => 4, 'tax_query' => array( 'relation' => 'AND', array( 'taxonomy' => 'main-category', 'field' => 'term_id', 'terms' => $main_category_terms, ), array( 'taxonomy' => 'product_cat', 'field' => 'term_id', 'terms' => $product_cat_terms, ), ), ); $main_and_product_query = new WP_Query($additional_args); if ($main_and_product_query->have_posts()) { // If number of posts found is less than 4, find additional posts from 'product_cat' terms if ($main_and_product_query->found_posts < 4) { $remaining_posts_needed = 4 - $main_and_product_query->found_posts; $product_only_query_args = array( 'post_type' => $query_args['post_type'], 'posts_per_page' => $remaining_posts_needed, 'post__not_in' => array_merge(array($current_post_id), wp_list_pluck($main_and_product_query->posts, 'ID')), 'tax_query' => array( array( 'taxonomy' => 'product_cat', 'field' => 'term_id', 'terms' => $product_cat_terms, ), ), ); $product_only_query = new WP_Query($product_only_query_args); // Merge the additional posts if ($product_only_query->have_posts()) { $main_and_product_query->posts = array_merge($main_and_product_query->posts, $product_only_query->posts); } // Clean up wp_reset_postdata(); } // Limit the final result to 4 posts $query_args['post__in'] = wp_list_pluck(array_slice($main_and_product_query->posts, 0, 4), 'ID'); } else { // If no posts found with both terms, fallback to only 'product_cat' terms $query_args['tax_query'] = array( array( 'taxonomy' => 'product_cat', 'field' => 'term_id', 'terms' => $product_cat_terms, ), ); $query_args['posts_per_page'] = 4; } // Clean up wp_reset_postdata(); } return $query_args; }, 10, 2);
To break it down:
we query 4 posts that match current post terms inmain-category
ANDproduct_cat
if less the 4 posts are returned we query additionalproduct_cat
posts excluding posts from first query.
if no posts are found we return just posts from the currentproduct_cat
We dedupe and exclude current posts throughout. -
S3ratin
YOU ARE GOD, David! Working like a Swiss watch! Thank you so much for your time and effort!
Best regards!
J. -
David
I am sure there are much smarter guys then me that could trim that code back. But i am glad to hear it did work 🙂
- You must be logged in to reply to this topic.