0

I am trying to order posts by tag count. I want to order posts with no tags first and posts with highest count last.

I tried and got posts with no tags only.

    $tags = get_tags();
    $tag_ids = wp_list_pluck( $tags, 'term_id' );

    $args1 = array (
       'orderby'          => 'DEC',
       'post_type'        => 'post',
       'pagination'       => true,
       'posts_per_page'   => '1',
       'tag__not_in'      =>  $tag_ids,
       'meta_key'         => '_thumbnail_id',
    );

How do I order posts based on the tags count?

2
  • I don't think you can do that directly. Although you can save terms count for each post in a custom meta field (on post publish) and then in your query define sort by that meta field. Or while running your query, you can save terms count along with posts ids in another array, then sort them by count and print posts. Second one will consume more resources so I would recommend first method.
    – Robert hue
    Commented Jan 5, 2015 at 5:32
  • SELECT p.ID,COUNT(*) count FROM wp_term_relationships r, wp_posts p, wp_term_taxonomy x WHERE r.object_id = p.ID AND p.post_type = 'post' AND r.term_taxonomy_id = x.term_taxonomy_id AND x.taxonomy = 'post_tag' GROUP BY object_id ORDER BY count;
    – user27457
    Commented Jan 5, 2015 at 11:22

1 Answer 1

2

As @Robert hue says you can't do it directly, you need a filter and a CASE in the orderby eg

$args1 = array (
   'orderby'          => 'tag_count',
   'order'            => 'DESC',
   'post_type'        => 'post',
   'pagination'       => true,
   'posts_per_page'   => '1', // 1 post per page?!
   'meta_key'         => '_thumbnail_id',
   'suppress_filters' => false,
);

function wpse173949_posts_clauses( $pieces, $query ) {
    if ( $query->get( 'orderby' ) != 'tag_count' ) return $pieces;
    global $wpdb;
    if ( ! ( $order = $query->get( 'order' ) ) ) $order = 'DESC';
    $pieces[ 'fields' ] .= $wpdb->prepare(
        ', (SELECT COUNT(tr.object_id) FROM ' . $wpdb->term_relationships . ' tr'
        . ' JOIN ' . $wpdb->term_taxonomy . ' AS tt ON tt.term_taxonomy_id = tr.term_taxonomy_id'
        . ' WHERE tr.object_id = ' . $wpdb->posts . '.ID AND tt.taxonomy = %s) AS tag_count'
        , 'post_tag' );
    // Treat zero tagged posts as max int (~0).
    $pieces[ 'orderby' ] = 'CASE WHEN tag_count THEN tag_count ELSE ~0 END ' . $order;
    return $pieces;
}

add_filter( 'posts_clauses', 'wpse173949_posts_clauses', 10, 2 );
$query = new WP_Query( $args1 );
remove_filter( 'posts_clauses', 'wpse173949_posts_clauses', 10 );
0

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.