5

I have a custom post type with tags included as a taxonomy, I am trying to display a list of all the tags that are in the custom post type only. I initially used:

wp_tag_cloud();

which generates the list of tags with links fine but it shows the tags of the normal posts with it. I tried to query the posts like this:

query_posts( array( 'post_type' => 'archive' ) );
if ( have_posts() ) : 
    while ( have_posts() ) : 
        the_post();
        the_tags('<ul><li>','</li><li>','</li></ul>');
        wp_reset_query();
    endwhile; 
endif;

but it shows the tags in duplicate loads. e.g if I had the tag as test, it would say test,test,test and so on.

This is the code that declares the tags

'taxonomies' => array('post_tag')

Does anybody know a way of displaying a list of tags that are specific to my custom post type only?

4 Answers 4

6

The above solutions work correctly but aren't exactly optimized. Here's a method that queries that database ONCE for the data you're looking for, and gives you a list of term objects. It can accept a post_type argument, and if one is not supplied, will use the post_type of the current global $post object.

function post_type_tags( $post_type = '' ) {
    global $wpdb;

    if ( empty( $post_type ) ) {
        $post_type = get_post_type();
    }

    return $wpdb->get_results( $wpdb->prepare( "
        SELECT COUNT( DISTINCT tr.object_id ) 
            AS count, tt.taxonomy, tt.description, tt.term_taxonomy_id, t.name, t.slug, t.term_id 
        FROM {$wpdb->posts} p 
        INNER JOIN {$wpdb->term_relationships} tr 
            ON p.ID=tr.object_id 
        INNER JOIN {$wpdb->term_taxonomy} tt 
            ON tt.term_taxonomy_id=tr.term_taxonomy_id 
        INNER JOIN {$wpdb->terms} t 
            ON t.term_id=tt.term_taxonomy_id 
        WHERE p.post_type=%s 
            AND tt.taxonomy='post_tag' 
        GROUP BY tt.term_taxonomy_id 
        ORDER BY count DESC
    ", $post_type ) );
}

So if you called post_type_tags( 'archive' ), for instance, you'd get a list of term objects for post_tag in descending order of popularity for 'archive' post types.

You can then emit your list of links like so:

$archive_tags = post_type_tags( 'archive' );

foreach( $archive_tags as $tag ) {
    echo '<a href="' . get_tag_link( $tag->term_id ). '">' . esc_html( $tag->name ) . '</a>';
}
1
  • Just perfect! Please accept this answer
    – rAjA
    Apr 3, 2017 at 3:21
-1
query_posts( 'post_type'=> 'custom_post_type_name' );
     if ( have_posts() ) : while ( have_posts() ) : the_post();
     $custom_post_tags = get_the_tags();
     if ( $custom_post_tags  ) {
        foreach( $custom_post_tags as $tag ) {
           $tags_arr[] = $tag -> name; 
        }
     }
     endwhile; endif;
     if( $tags_arr ) {
         $uniq_tags_arr = array_unique( $tags_arr );
         foreach($tags_arr as $tag ) {
             // LIST ALL THE TAGS FOR DESIRED POST TYPE
             $sanitizeTag =  sanitize_title($tag);

$current_tag = get_term_by('name', $tag, 'post_tag');

             echo '<a href="' . get_tag_link($current_tag->term_id). '">' .$tag. '</a>';
         }
    }

This will give the list of tags with the links to the tag.

5
  • Awesome, It shows the link now but after testing properly it still shows duplicates, I have two posts with the same tag of 'test' and it shows test twice when i use that code
    – user34466
    Jun 24, 2013 at 11:12
  • check the title/slug of the tag you are using. There must be something which is making both the tags not to be identical. Otherwise array_unique must have solved this issue. Jun 24, 2013 at 11:17
  • I deleted all the tags and added new ones and tested again, im using only one tag its not duplicating it in the admin, just in when it shows
    – user34466
    Jun 24, 2013 at 11:27
  • Is the code working now? or do you need to make any more changes? Jun 24, 2013 at 11:30
  • Not working, still showing doubles!
    – user34466
    Jun 24, 2013 at 11:32
-1
 
     query_posts( 'post_type'=> 'custom_post_type_name' );
     if ( have_posts() ) : while ( have_posts() ) : the_post();
     $custom_post_tags = get_the_tags();
     if ( $custom_post_tags  ) {
        foreach( $custom_post_tags as $tag ) {
           $tags_arr[] = $tag -> name; 
        }
     }
     endwhile; endif;
     if( $tags_arr ) {
         $uniq_tags_arr = array_unique( $tags_arr );
         foreach( $uniq_tags_arr as $tag ) {
             // LIST ALL THE TAGS FOR DESIRED POST TYPE
             $tag_link = get_term_by('name', $tag, 'post_tag');
             echo 'term_id). '" title="'.$tag.'">' .$tag. '';
         }
    }
6
  • Fantastic thank you so much! The only thing is it dosen't contain a link to the tag, do you know how to do this?
    – user34466
    Jun 24, 2013 at 10:41
  • Yeah you just need to add this in the above foreach loop echo "<li><a href='".$sanitizeTag ."' title="'.$tag.'">$tag</a></li>";
    – S kumar
    Jun 24, 2013 at 10:51
  • hey I just tweaked my code little while use the above code and vote me up if you really satisfied with my solution.
    – S kumar
    Jun 24, 2013 at 11:17
  • Thanks but its showing the same tag twice when i use that code still!
    – user34466
    Jun 24, 2013 at 11:37
  • $uniq_tags_arr = array_unique( $tags_arr ); will remove the duplicate value just try no there is something went wrong I guess. Are they really same or seems like some white space or dot with it. please check it in your tags. Because its my working code.
    – S kumar
    Jun 24, 2013 at 11:52
-1

@user34466 This should work to solve the duplicate issue:

                <ul>
            <?php
                query_posts(array( 'post_type'=> 'work' ));
                if ( have_posts() ) : while ( have_posts() ) : the_post();
                    $custom_post_tags = get_the_tags();
                if ( $custom_post_tags ) {
                    foreach( $custom_post_tags as $tag ) {
                        $tags_arr[] = $tag -> name;
                    }
                }
                endwhile; endif;
                if( $tags_arr ) {
                    $uniq_tags_arr = array_unique( $tags_arr );
                 foreach( $uniq_tags_arr as $tag ) {
                     // LIST ALL THE TAGS FOR DESIRED POST TYPE
                     $sanitizeTag =  sanitize_title($tag);
                     $tag_link = get_term_by('name', $tag, 'post_tag');
                     echo '<li><a href="'. get_tag_link($tag_link->term_id).'">' .$tag. '</a></li>';
                     }
                 }
             ?>
            </ul>

Good Luck!

1
  • Please explain why that was actually helpful. Thanks.
    – kaiser
    May 8, 2014 at 1:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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