Taxonomy Archive: Display only one post per term from separate custom taxonomy

I am having trouble coming up with a solution for product catalog I am building using custom post types and 4 custom taxonomies. The product catalog is separated by “model”, but each “model” can have up to 15 “product” variations. Each “product” has different attributes and I need to be able to filter a list of products based on these attributes.

Structurally, I have things organized like so:

Read More
  • Product (Custom Post Type)
  • Model (Taxonomy)
  • Size (Taxonomy)
  • Color (Taxonomy)
  • Features (Taxonomy)

With the exception of “Model”, each taxonomy is used as a way to filter the products shown. I am using the Query Multiple Taxonomies plugin to help me filter the attributes for each product. This works great. It allows me to use the default WordPress template hierarchy and make all my changes to a taxonomy.php file.

Now here is where I get lost. I would like to limit the results that are shown so only 1 of each model is shown, even though the filtering may return multiple products per model.

I am currently using The Loop and get_the_terms() to create an array, and then using the array_unique() function to save only one instance of each model name to an array. Here is the code I have for that portion:

$modelSlugs = array();

while (have_posts()) : the_post();

// Gather the model names assigned to each product
$terms = get_the_terms( $post->ID, 'models' );
if ( $terms && ! is_wp_error( $terms ) ) : 
    $term = array_pop($terms);
    $modelSlugs[] = $term->slug;
endif;                               

endwhile;    

$modelList = array_unique($modelSlugs);

This will give me only one of each model slug (or name), which is good, but I also need to show a product thumbnail and use the permalink to link to the single product page. I know I can generate additional queries based on each slug, but that sounds like it is a performance nightmare.

The more I think about it, I can’t help think this is the wrong way to go about this. I know the returned $wp_query object has everything I could possibly need, I am just not sure what tricks to use to ensure I only show one post for each model. Is there a way to prepare or manipulate the returned WP_Query object before running the loop, or is there something I can do inside of the loop to limit how many products are displayed?

Related posts

1 comment

  1. After much pounding on the keyboard, I have figured it out. It may not be the best way to accomplish this, but it works and doesn’t require any additional DB queries.

    I used the code above to generate a list of the models I needed to display.

    I then used this code to make everything happen.

    foreach ($modelList as $model) :
    
    $count = 0;
    echo '<h2>' . $model . '</h2>';
    
    // Run the loop again to show the products
    while (have_posts()) : the_post();
    
        // Check that the model name for the post is the same as the model 
        if ( has_term( $model, 'models') ) :
    
            // Show only first item in loop
            if ($count == 0) :
    
                get_template_part( 'content', 'model' );                                                            
    
            endif;
    
            $count++;
    
        endif; //has_term                   
    
    endwhile;
    
    endforeach;
    

    Let me explain a little here:

    I created a foreach loop for the model list, then inside I ran the standard loop to show all the posts. To make sure posts were grouped by model name, I used has_term() to make sure the model name of the posts matched the item in the array. Then I added a counter to the while loop to make sure only the first post was shown.

Comments are closed.