Edited:
This is a much simpler version of what you are looking to do. You don’t need WP_Query()
. You can use a foreach
loop and an iterator:
<?php
echo '<ul class="job-category-list">';
// Get the terms and order them by count in descending order.
$terms = get_terms( [
'taxonomy' => 'job_listing_category',
'orderby' => 'count',
'order' => 'DESC',
]
);
// Set an iterator
$i = 1;
// foreach term
foreach ( $terms as $term ) {
// if the iterator is less than or equal to 12.
if ( $i <= 12 ) :
echo '<li><a href="' . get_term_link( $term->term_id ) . '" title="' . esc_attr( $term->name ) . '">' . $term->name . '</a> (' . ( $term->count ) . ')</li>';
// Increase the iterator.
$i++;
endif;
}
echo '<ul><!-- /job-category-list -->';
?>
For the count, not sure why are you seeing a difference. But this essentially gives you what you want.
EDIT: from this wpse post: List taxonomy / category count showing list published posts only
You can use this filter to get the correct count for only published posts:
function get_terms_filter_published( $terms, $taxonomies, $args ) {
global $wpdb;
$taxonomy = $taxonomies[0];
if ( ! is_array($terms) && count($terms) < 1 ) {
return $terms;
}
$filtered_terms = array();
$ctr = 0;
foreach ( $terms as $term ) {
$result = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->posts p JOIN $wpdb->term_relationships rl ON p.ID = rl.object_id WHERE rl.term_taxonomy_id = $term->term_id AND p.post_status="publish" LIMIT 1");
$published_terms[ $ctr ] = $term;
if ( intval($result) > 0 ) {
$published_terms[ $ctr ] = $term;
} else {
// you can comment this out if you don't want to show empty terms
$published_terms[ $ctr ]->count = 0;
}
$ctr++;
}
return $published_terms;
}
add_filter('get_terms', 'get_terms_filter_published', 10, 3);
So, add that filter function to your functions.php and use the code above to get what you want – only the first 12 categories based on post count.