0

Is it possible to order a tag page by the 'most commonly used' tag?

For example:

Say I have three tags: Apple, Orange, Banana, and 100 posts.

90 of those posts are tagged Apple, 50 are tagged Orange, and 20 are tagged Banana. (Some are tagged with more than 1 tag.)

So I want to order the posts listed on the tags page by Apple Tags first.

Right now, I am ordering by last modified using the following query, but would like to order by the tag that is used the most across all posts.

 $args = array(
            'posts_per_page' => 10, // Get 10 posts
            'paged' => $paged,
            'post_type' => 'post',
            'tag' => $tag->slug,
            'orderby' => 'modified'
        );
  • Let me be clear, you want to order your posts on a tag taxonomy archive page by the usage of tag terms right ? And what actually do you mean by usage? Does it mean the visit of users to the tag terms or the the number of post has been posted for past some time ? – CodeMascot Dec 14 '16 at 8:21
  • I've updated the question to make it clearer. – Chris J Allen Dec 15 '16 at 9:26
  • Then how you wanna show your posts which has overlapping multiple tags? I mean the post must show it self under one tag, is not it ? The if it has multiple tag then it is gonna show under which tag itself ? – CodeMascot Dec 15 '16 at 11:04
1

I'm afraid orderby taxonomy terms post count is not possible by WP_Query. See this answer. So here I've written a SQL based function for you. It'll order your posts based on terms post count.

function the_dramatist_order_posts_by_tag_count( $args = '' ) {
    global $wpdb;
    $param = empty($args) ? 'post_tag' : $args;
    $sql = $wpdb->prepare("SELECT posts.*, terms.name AS tag, count 
                            FROM {$wpdb->posts} AS posts
                                 LEFT JOIN {$wpdb->term_relationships} AS t_rel
                                            ON (t_rel.object_id = posts.ID)
                                 LEFT JOIN {$wpdb->term_taxonomy} AS t_tax
                                            ON (t_rel.term_taxonomy_id = t_tax.term_taxonomy_id)
                                 LEFT JOIN {$wpdb->terms} AS terms
                                            ON (terms.term_id = t_tax.term_id)
                            WHERE taxonomy LIKE '%s'
                            ORDER BY t_tax.count DESC, terms.name",
        array( $param )
    );

    return $wpdb->get_results($sql);
}

It'll return you all the data from you posts table with post_tag term name and this terms post count. But it has a simple limitation and that is if you have one tag in multiple posts then the post will appear multiple time for each post_tag term it is attached to. You can use GROUP BY posts.ID to remove the duplicate posts, but it'll not give you all the terms and terms count. So with GROUP BY posts.ID the function will be like below-

function the_dramatist_order_posts_by_tag_count( $args = '' ) {
    global $wpdb;
    $param = empty($args) ? 'post_tag' : $args;
    $sql = $wpdb->prepare("SELECT posts.*, terms.name AS tag, count 
                            FROM {$wpdb->posts} AS posts
                                 LEFT JOIN {$wpdb->term_relationships} AS t_rel
                                            ON (t_rel.object_id = posts.ID)
                                 LEFT JOIN {$wpdb->term_taxonomy} AS t_tax
                                            ON (t_rel.term_taxonomy_id = t_tax.term_taxonomy_id)
                                 LEFT JOIN {$wpdb->terms} AS terms
                                            ON (terms.term_id = t_tax.term_id)
                            WHERE taxonomy LIKE '%s'
                            GROUP BY posts.ID
                            ORDER BY t_tax.count DESC, terms.name",
        array( $param )
    );
    return $wpdb->get_results($sql);
}

Use which suits your need better.

This function works on post_tag taxonomy by default. If you want to use it with other taxonomy just pass it as parameter like the_dramatist_order_posts_by_tag_count( 'category' )

Better you do a print_r on this function before using it in production to understand the data structure.

Hope that helps.

  • Possible misuse of the comments box, but I want to acknowledge that you have gone way beyond what I was expecting. This is really great. I'm going to have a play and figure it all out. – Chris J Allen Dec 16 '16 at 12:27
0

This simple code make what you are looking for.

$tags = get_tags( array('orderby' => 'count', 'order' => 'DESC') );

foreach ( (array) $tags as $tag ) {
  echo '<li><a href="' . get_tag_link ($tag->term_id) . '" rel="tag">' . $tag->name . ' (' . $tag->count . ') </a></li>';
}
  • 1
    Please take a minute and make an edit to explain what the code is doing. Explaining the code adds value to your answer and you're likely to receive upvotes when providing answers that aren't just code dumps. – DᴀʀᴛʜVᴀᴅᴇʀ Oct 26 '17 at 17:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.