wp_get_post_terms of cpt but not duplicates if they are used more than once in the loop

I have a CPT ‘media_blog’ with the taxonomy ‘media_blog_category’. I have two loops on the page that match the pagination for this CPT. I have the first loop just of the terms used in the posts. There are multiple terms assigned to each post. I want to show the list of terms used on the posts but not show duplicates of posts with the same terms.

This is what I have so far and it’s very close, it does not show duplicates of the same term used on the posts, but it also does not show other terms on posts that have more than one term. I’m going pretty nuts at this point:

if ( is_post_type_archive( 'media_blog' ) ) :

        global $post;
        global $wp_query;

        $args = array(
            'post_type'      => 'media_blog',
            'posts_per_page' => 16, // same as the pre_get_posts
            'post_status'    => 'publish',
            'paged'          => get_query_var( 'paged' ),
        );


    $wp_query = new WP_Query( $args );

    if ( have_posts() ) : 

        echo '<ul class="filter">';

            echo '<li class="current-menu-item"><a href="#" data-filter="*">' . __( 'All' ) . '</a></li>';

                $term_list = wp_get_post_terms( $post->ID, 'media_blog_category', array( 'fields' => 'all' ) );

                foreach( $term_list as $term ) :

                    $dupe = 0;

                    while ( have_posts() ) : the_post(); 

                    if ( $dupe == 0 ) :

                        echo '<li><a href="#" data-filter=".media_blog_category-' . $term->slug . '">' . $term->name . '</a></li>';

                        $dupe++;

                    endif; //dupe

                    endwhile;

                endforeach; //term_list


        echo '</ul>';

    endif; //WP_Query

    wp_reset_query();       

    endif; //media_blog

1 Answer
1

Fix the duplicate checking logic:

Your duplicate checking logic is wrong. You needed to keep the terms in an array and then check if the term already exist in the array to determine if it’s a duplicate.

So instead of if ( $dupe == 0 ) : condition and wrong loop nesting, it’ll be like:

if ( have_posts() ) : 
    echo '<ul class="filter">';
        echo '<li class="current-menu-item"><a href="#" data-filter="*">' . __( 'All' ) . '</a></li>';     
        $unique_terms = array(); // instead of $dupe = 0;
        while ( have_posts() ) : the_post();
            $term_list = wp_get_post_terms( $post->ID, 'media_blog_category', array( 'fields' => 'all' ) );
            foreach( $term_list as $term ) :
                if( ! in_array( $term->term_id, $unique_terms ) ):
                    array_push( $unique_terms, $term->term_id );
                    echo '<li><a href="#" data-filter=".media_blog_category-' . $term->slug . '">' . $term->name . '</a></li>';
                endif;
            endforeach; //term_list
        endwhile;
    echo '</ul>';
endif; //WP_Query

This should work as you’ve wanted.

A better solution:

Your CODE will work after fixing with the above logic. However, you can make it more efficient with the following CODE:

if ( is_post_type_archive( 'media_blog' ) ) :
    $args = array(
        'post_type'      => 'media_blog',
        'posts_per_page' => 16, // same as the pre_get_posts
        'post_status'    => 'publish',
        'paged'          => get_query_var( 'paged' ),
        'fields'         => 'ids' // for this specific case, all you need are the IDs
    );
    $wp_query = new WP_Query( $args );
    if ( have_posts() ) :
        echo '<ul class="filter">';
            echo '<li class="current-menu-item"><a href="#" data-filter="*">' . __( 'All' ) . '</a></li>';
                $term_list = wp_get_object_terms( $wp_query->get_posts(), 'media_blog_category' );
                foreach( $term_list as $term ) :
                    echo '<li><a href="#" data-filter=".media_blog_category-' . $term->slug . '">' . $term->name . '</a></li>';
                endforeach; //term_list
        echo '</ul>';
    endif; //WP_Query
    wp_reset_query();
endif; //media_blog

Leave a Comment