Are you a GenerateCustomer?

Do you have an active GP Premium or GenerateBlocks Pro license key?

Create a GenerateSupport account for GeneratePress and GenerateBlocks support in one dedicated place.

Create an account
Already have a GenerateSupport account? Login

Just browsing?

Feel free to browse the forums. Support for our free versions is provided on WordPress.org (GeneratePress, GenerateBlocks).

Want to become a premium user? Learn more below.

Query Loop Logic and Sorting

  • 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: 4

    So 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

  • Hi there,

    is there just the one custom taxonomy ?

  • Hi David,

    Yes, only one. Taxonomy key “main-category” made in ACF

    Thanks

  • 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.

  • 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 taxonomy

    Scenario 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.

  • 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 in main-category AND product_cat
    if less the 4 posts are returned we query additional product_cat posts excluding posts from first query.
    if no posts are found we return just posts from the current product_cat
    We dedupe and exclude current posts throughout.

  • YOU ARE GOD, David! Working like a Swiss watch! Thank you so much for your time and effort!

    Best regards!
    J.

  • 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 🙂

Viewing 8 posts - 1 through 8 (of 8 total)
  • You must be logged in to reply to this topic.