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