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
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