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
- Post A
Tag 2
- Post B
- Post B
But it’s displaying like this:
Tag 1
- Post A
- Post C
- Post A
Tag 2
- Post B
- 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
- get associated posts (run
- for each tag
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.
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!