Get posts from multiple terms but ensure they are unique

I have the loop below that is doing the following:

  1. Looping through all my custom taxonomy terms and seeing if the
    checkbox “category on homepage” is selected, it shuffles those
    selected.
  2. It then loops through those terms that are selected and pulls out 1 custom post at random for each of those terms.
  3. It then outputs a box with the term name and an image from the post selected.

The problem I’m having is that posts are tagged with multiple terms, so chances are it will select the same post across the different terms.

Read More

How can I ensure that the posts that are selected are unique?

<?php $terms = get_terms('project-categories', array(
    'orderby'    => 'rand',
    'hide_empty' => 1,
    )
 );
shuffle($terms);
foreach ( $terms as $term ) {
    if(get_field('category_on_homepage', 'project-categories_' . $term->term_id)) {
        if (in_array('Yes', get_field('category_on_homepage', 'project-categories_' . $term->term_id))) {

            $termid = $term->term_id;
            $termname = $term->name;
            $termslug = $term->slug;

            $args = array(
                'posts_per_page' => 1,
                'orderby' => 'rand',
                'post_type' => 'projects',
                'post_status' => 'publish',
                'tax_query' => array(
                    array(
                        'taxonomy' => 'project-categories',
                        'field' => 'id',
                        'terms' => $termid
                    )
                )
            );
            $projects = get_posts( $args );

            foreach ( $projects as $post ) {
                setup_postdata($post); ?>
                <a class="service" href="<?php echo $termslug; ?>">
                    <span class="service-image" style="background-image:url('<?php echo the_field('thumb_image'); ?>');"></span>
                    <span class="service-title"><?php echo $termname; ?></span>
                </a>

            <?php }
            wp_reset_postdata();
        }
    }

} ?> 

Related posts

Leave a Reply

1 comment

  1. Build an array of used post ids, then use the post__not_in query parameter to exclude the used posts from future queries.

    <?php
    
        $terms = get_terms('project-categories', array(
            'orderby'    => 'rand',
            'hide_empty' => 1
            )
        );
    
        $used_posts = array();
    
        shuffle($terms);
    
        foreach ( $terms as $term ) {
            if(get_field('category_on_homepage', 'project-categories_' . $term->term_id)) {
                if (in_array('Yes', get_field('category_on_homepage', 'project-categories_' . $term->term_id))) {
    
                    $termid = $term->term_id;
                    $termname = $term->name;
                    $termslug = $term->slug;
    
                    $args = array(
                        'posts_per_page' => 1,
                        'orderby' => 'rand',
                        'post_type' => 'projects',
                        'post_status' => 'publish',
                        'post__not_in' => $used_posts,
                        'tax_query' => array(
                            array(
                                'taxonomy' => 'project-categories',
                                'field' => 'id',
                                'terms' => $termid
                            )
                        )
                    );
                    $projects = get_posts( $args );
    
                    foreach ( $projects as $post ) {
                        setup_postdata($post);
                        array_push($used_posts, $post->ID);
    
                        ?>
                            <a class="service" href="<?php echo $termslug; ?>">
                                <span class="service-image" style="background-image:url('<?php echo the_field('thumb_image'); ?>');"></span>
                                <span class="service-title"><?php echo $termname; ?></span>
                            </a>
                        <?php
                    }
                    wp_reset_postdata();
                }
            }
        }
    ?>