Skip to content
Advertisement

WordPress how to display all posts based on tags

I have 3 tags:

  • Tag 1
  • Tag 2
  • Tag 3

I need to display all of the posts in my custom post type and specified term. They need to be sorted by tag and hiding the tags that are not being used like this:

  • Tag 1

    • Post A
    • Post C
  • Tag 2

    • Post B

But it’s displaying like this:

  • Tag 1

    • Post A
    • Post C
  • Tag 2

    • Post B
  • Tag 3

    • (Empty)

Tag 3 is being displayed even though there are no posts currently using the tags…

Here is the code I’m using:

// These 3 variables change dynamically depending on page slug.
$cpt = houses;
$tax = type;
$term = small;

$args = array(
'posts_per_page'    => -1,
'orderby'           => 'name',
'order'             => 'ASC',
'post_type'         => $cpt,
'tax_query'         => array(
   array(
   'taxonomy'      => $tax,
   'field'         => 'name',
   'terms'         => $term
   )
 )
);

$tags = get_tags($args); // Tag 1, Tag 2, Tag 3
$posts = get_posts($args);

foreach($tags as $tag)
{
  ?>
    <h5><?php echo $tag->name.' (Tag)'; ?></h5>
  <?php
  foreach($posts as $post)
  {
    if( has_tag( $tag ) )
    {
    ?>
      <a href="<?php echo the_permalink();?>"><?php echo the_title().' (Post)';?></a><br>
    <?php
    }
  }
  ?>
  <hr>
  <?php
}
?>

I appreciate the help!

Advertisement

Answer

Your code logic would be something like this:

  • get_tags
    • for each tag
      • get associated posts (run get_posts here)
      • Only if there is any post
        • echo the title of the tag
        • for each associated post (run a foreach loop for posts here)
          • echo the title of the post

So you could move your get_posts query inside the foreach($tags as $tag) and use $tag argument to see if there are any post(s) associated with that tag.

Note that in the $posts_args i used an extra argument called tag which will do the trick for you in the tags foreach loop. The value of the tag argument is the tag slug.

Tag arguments you could pass into your queryDocs

Also by using get_tags function, you don’t have to specify orderby or order, since the default value for ‘orderby’ is ‘name’, and default value for ‘order’ is ‘ASC’, so you don’t need to pass them as arguments.


So the entire code would be something like this:

$cpt = houses;
$tax = type;
$term = small;

$posts_args = array(
  'posts_per_page'    => -1,
  'orderby'           => 'name',
  'order'             => 'ASC',
  'post_type'         => $cpt,
  'tag'               => $tag->slug,
  //OR
  //'tag_slug__in'      => array($tag->slug),
  'tax_query'         => array(
    array(
      'taxonomy'      => $tax,
      'field'         => 'name',
      'terms'         => $term
    )
  )
);

$tags = get_tags(); // Tag 1, Tag 2, Tag 3

foreach ($tags as $tag) {

  $posts = get_posts($posts_args);

  if ($posts) { ?>

    <h5><?php echo $tag->name . ' (Tag)'; ?></h5>

    <?php

    foreach ($posts as $post) { ?>

      <a href="<?php echo the_permalink(); ?>"><?php echo the_title() . ' (Post)'; ?></a><br>

    <?php

    }

    ?>

    <hr>

<?php

  }

}

?>

Which will output this:

Tag 1
  Post A
  Post C
--------
Tag 2
  Post B 

Let me know if you could get it to work!

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement