I am trying to list posts that do NOT have specific tags.

Currently, I am looping through each tag in a post, and if it's doesn't exist, list it. This works, except that it will list the same URL multiple times, if there are more than one tag.

// the query
$wpb_all_query = new WP_Query(array('post_type'=>'post', 'post_status'=>'publish', 'posts_per_page'=>-1)); ?>
<?php if ( $wpb_all_query->have_posts() ) : ?>

    <!-- the loop -->
    <?php while ( $wpb_all_query->have_posts() ) : $wpb_all_query->the_post(); ?>
        <?php $post_tags = get_the_tags(); ?>
        <?php foreach ($post_tags as $tag) : ?>
            <?php if ($tag->name != "Tag1" and $tag->name != "Tag2" and $tag->name != "Tag3"): ?>
                <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
            <?php endif; ?>

       <?php endforeach; ?> 
       <?php endwhile; ?>
    <!-- end of the loop -->

<?php wp_reset_postdata(); ?>
<?php endif; ?>

For instance, a post with tags Fun, and Learning will list twice in a row. I just want this listed once.

Is there a way I can quickly check all tags in a post instead of looping?

Edit: I tried adding all the tags to a string, and using strpos() but that seems to only check the first condition, and not the second/third:

<?php while ( $wpb_all_query->have_posts() ) : $wpb_all_query->the_post(); ?>
   <?php $alltags = ""; ?>
    <?php $post_tags = get_the_tags(); ?>
    <?php foreach ($post_tags as $tag) : ?>
     <?php $alltags .= $tag->name . " "; ?>
     <?php endforeach; ?>
      <?php if ((strpos($alltags, "SCA") == false) and (strpos($alltags, "SCAA") == false) and (strpos($alltags, "Tea and Coffee") == false)): ?>
    <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a> - <?php echo $alltags; ?></li>
    <?php endif; ?>
   <?php endwhile; ?>

I believe you can filter them out in your original WP_Query using Taxonomy Parameters. Then you can delete the for loop altogether.

$args = array(
    'post_type' => 'post',
    'posts_per_page' =>-1,
    'tax_query' => array(
            'taxonomy' => 'post_tag',
            'field'    => 'slug',
            'terms'    => array('fun','learning'),
            'operator' => 'NOT IN',
$wpb_all_query = new WP_Query( $args );
  • So this would return the posts that are not tagged with "fun" or"learning", right? And would I add $args within array() or outside it in the new WP_Query? – BruceWayne May 10 '19 at 22:57
  • 1
    Yep, exactly. Add the slugs for any terms you want to exclude in the same array as 'fun' and 'learning'. The code I supplied replaces your original Wp_query, I used $args just because it's easier to read. – Michelle May 11 '19 at 23:19
  • Ah! I didn't realize you can add multiple "queries" (?) to that array, my bad. Thanks for this - I'm not able to test now but when I do, I'll be sure to comment/mark as answer as this looks to be the way to go. Thanks! :D – BruceWayne May 12 '19 at 3:21
  • Thanks! This works - except it doesn't seem to exclude terms with a space, i.e. array('fun', 'learning', 'other stuff)` is not filtering out posts tagged with other stuff. (This may be a new question, just mentioning here in case it's a quick fix. Do I need to tag the post with quotes?) – BruceWayne May 14 '19 at 15:49
  • (Ah, found the answer - the slug for that is other-stuff, so I can just use that in the array, not other stuff). – BruceWayne May 14 '19 at 16:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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