-1

I have a custom post type "product", and two custom taxonomies: "productfamily" and "industry".

On my single product page, I need to show products that are in the same productfamily and industry.

Some products might be in a few different industries...and my related products section only needs to match one of the industries of the current post to show up.

Here's what I have so far...

$wp_query = new WP_Query(
        array(
            'posts_per_page' => '4',
            'post_type' => 'product',
            'tax_query' => array(
                'relation' => 'AND',
                        array(
                            'taxonomy' => 'productfamily',
                            'field'    => 'slug',
                            'terms'    => $prodfam,
                            'operator' => 'IN'
                        ),
                        array(
                            'taxonomy' => 'industry',
                            'field'    => 'term_id',
                            'terms'    => $prodindustry,
                            'operator' => 'IN'
                        ),
            ),
            'orderby' => 'title',
            'order' => 'ASC',
        )
    );

If I change the "AND" relation to "OR", it seems to partly work by showing products from the same "productfamily", but doesn't seem to be taking the "industry" into account at all.

How can I get this to show related products based off of my two custom taxonomies please? Thanks in advance for your help.

  • Please explain how you're getting `$prodindustry` and `$prodfam` and what are they? an array? an integer? a string? an array of strings? an array of integers? without knowing about these info, it's hard to find what mistake you're doing here. – Vijay Hardaha Sep 20 '22 at 20:52
  • @VijayHardaha Sorry, here's how : `global $post; $terms = wp_get_post_terms( $post->ID, 'productfamily' ); if($terms){ // post has course_type terms attached $prodfam = array(); foreach ($terms as $term){ $prodfam[] = $term->slug; } } $prodindustry = wp_get_post_terms( $post->ID, 'industry' ); if( $prodindustry ) { $prodindustry = array(); foreach( $prodindustry as $term ) { $prodindustry[] = $term->slug; } }` I have all of this in a shortcode function to then use within my template. – PurpleMonkeyDishwasher Sep 21 '22 at 12:40
  • Tested and doesn't work. – Michelle Aug 12 '23 at 17:30

1 Answers1

0

As you described in comment that you have slugs array in variables but in one of your tax query condition, you've used term_id to match with slug. that is incorrect.

You can directly use the terms ids instead of slugs since it's dynamic things. in function wp_get_post_terms you can pass array( 'fields' => 'ids' ) as 3rd param and it will give you array of ids. so you don't have make an extra loop.

Then you'll have to check both terms array if they both are empty of one of them or both of them as values? then you can check them individually and then add the tax query part if ids are available.

This is how you can write the code in a clean way with proper checks:

global $post;

// Get the terms ids array,
// we can pass 'fields' => 'ids' in 3rd param so we don't need to run the loop to collect ids.
$product_family_ids = wp_get_post_terms( $post->ID, 'productfamily', array( 'fields' => 'ids' ) );
$industry_ids       = wp_get_post_terms( $post->ID, 'industry', array( 'fields' => 'ids' ) );

// Prepare query args.
$query_args = array(
    'posts_per_page' => '4',
    'post_type'      => 'product',
    'orderby'        => 'title',
    'order'          => 'ASC',
    'tax_query'      => array(
        'relation' => 'AND',
    ),
);

// We need to check if both ids are not empty.
// if both empty we don't wanna run query.
if ( ! empty( $product_family_ids ) || ! empty( $industry_ids ) ) {

    // If product family terms are available.
    if ( ! empty( $product_family_ids ) ) {
        $query_args['tax_query'][] = array(
            'taxonomy' => 'productfamily',
            'field'    => 'term_id',
            'terms'    => (array) $product_family_ids,
            'operator' => 'IN',
        );
    }

    // If industry terms are available.
    if ( ! empty( $industry_ids ) ) {
        $query_args['tax_query'][] = array(
            'taxonomy' => 'industry',
            'field'    => 'term_id',
            'terms'    => (array) $industry_ids,
            'operator' => 'IN',
        );
    }

    $related_posts = new WP_Query( $query_args );

    if ( $related_posts->have_posts() ) {

        while ( $related_posts->have_posts() ) {

            $related_posts->the_post();

            /**
             * DO you thing here.
             */
        }
    }

    wp_reset_postdata();
}

Note: I have not tested the code so there might be syntax errors, if you use the code and find errors after using the code please let me know so that I could fix errors in my answers. Also, Make sure you have site backup and FTP access to fix the errors, Don't add code from WordPress backend

Vijay Hardaha
  • 2,411
  • 1
  • 7
  • 16