1

I have this to retrieve a list of post typed named "works" based on a taxonomy called "works_year".

If I select more than 1 value of that taxonomy (works_year), that post are being duplicated on my front page.

Can I avoid that?

$years_loop = get_terms(
    array(
        'taxonomy'  => 'works_year',
        'orderby'   => 'slug',
        'order'     => 'DESC',
    )
);
foreach($years_loop as $year_loop_slug) :

$args = array(
    'post_type'       => 'works',
    'posts_per_page'  => -1,
    'tax_query'       => array(
        array(
            'taxonomy'  => 'works_year',
            'field'     => 'slug',
            'terms'     => array( $year_loop_slug->slug ),
            'operator'  => 'IN'
        )
    ),
);

$loop = new WP_Query($args);
while ($loop->have_posts()) : $loop->the_post();

//Show the Post

1 Answer 1

1

I see two ways to go about it, both quite similar.

A) You can collect IDs of displayed posts in an array and then exclude those with post__not_in query parameter like so:

$years_loop = get_terms(
    array(
        'taxonomy'  => 'works_year',
        'orderby'   => 'slug',
        'order'     => 'DESC',
        )
);

// array for displayed posts, we will update it with every loop
$displayed = [];

foreach($years_loop as $year_loop_slug) :
    $args = array(
        'post_type'       => 'works',
        'posts_per_page'  => -1,
        'post__not_in'    => array_unique( $displayed ),
        'tax_query'       => array(
            array(
                'taxonomy'  => 'works_year',
                'field'     => 'slug',
                'terms'     => array( $year_loop_slug->slug ),
                'operator'  => 'IN',
            )
        ),
    );
    $loop = new WP_Query($args);
    while ($loop->have_posts()) : $loop->the_post();

        // update array with currently displayed post ID
        $displayed[] = get_the_ID();

        //your output

    endwhile;
endforeach;

B) If you want to avoid using post__not_in parameter, which can have bad impact on your site's performance, you can check for the duplicates inside your loops:

$years_loop = get_terms(
    array(
        'taxonomy'  => 'works_year',
        'orderby'   => 'slug',
        'order'     => 'DESC',
        )
);

// array for displayed posts, we will update it with every loop
$displayed = [];

foreach($years_loop as $year_loop_slug) :
    $args = array(
        'post_type'       => 'works',
        'posts_per_page'  => -1,
        'tax_query'       => array(
            array(
                'taxonomy'  => 'works_year',
                'field'     => 'slug',
                'terms'     => array( $year_loop_slug->slug ),
                'operator'  => 'IN',
            )
        ),
    );

    $loop = new WP_Query($args);
    while ($loop->have_posts()) : $loop->the_post();
        // if the current post was already displayed, move on to the next iteration of this loop
        if ( in_array( get_the_ID(), $displayed ) ){
            continue;
        }
        // update array with currently displayed post ID
        $displayed[] = get_the_ID();

        //your output

    endwhile;
endforeach;

Code not tested, but you get the idea.

1
  • Thank you so much Levi Dulstein. I use the (B) solution, and didn't have to change anything on your code it worked perfectly! Again thanks for the quick answer and the both solutions!
    – cbtr
    Commented Nov 6, 2017 at 12:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.