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