show tags of custom post type ONLY

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

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>';
}

Leave a Comment