• Resolved transpersonal

    (@transpersonal)


    Hi guys,

    Does anyone know how to do this? I would like to display the number of posts that are assigned under each tag on my blog. Like:

    Dog (8)
    Cat (3)
    Fish (15)

    and so on…

Viewing 14 replies - 16 through 29 (of 29 total)
  • Yeah, got those ?? Something is still wrong though…

    Ah ha! It’s the fact that I’m tagging WP pages and not posts. When I tag a post, your code works perfectly! Exactly as I would have liked. But the code is not picking up tagged WP pages (made possible by the Simple Tags plugin).

    I’m going to play around some more…

    Got it! Just changed

    AND p.post_type = 'post'

    to

    AND p.post_type = 'page'

    …and it worked like a charm. Case close. t31os_ can I buy you a beer?

    Appreciate the offer, unfortunately i don’t have a “Buy me a beer” facility ..

    Glad to hear it’s all working for you though… ??

    Hi t310s_,

    I have a new challenge… ??

    The client now wants the list to be alphabetized not by first word in the tag names, but rather by the second word of the tag names. The reason is that the tags are actually author names and the list I’m creating is meant to be an index.

    You can see what I have so far here: https://bit.ly/aK3oRH

    Here is the code I’m using (a slight modification of your code to account for my db table names; and I made the html print out in a table rather than ul/li)

    <?php
    
    $tags_and_posts = $wpdb->get_results("
    	SELECT tr.object_id,p.post_title,p.guid,t.name
    	FROM wp_dub_term_relationships tr
    	JOIN wp_dub_term_taxonomy tt ON tt.term_taxonomy_id = tr.term_taxonomy_id
    	JOIN wp_dub_posts p ON tr.object_id = p.ID
    	JOIN wp_dub_terms t ON tt.term_id = t.term_id
    	WHERE tt.taxonomy = 'post_tag'
    	AND p.post_status = 'publish'
    	AND p.post_type = 'page'
    	ORDER by t.name
    ");
    
    $tag_array = array();
    $letters = array();
    
    foreach( $tags_and_posts as $unwanted_key => $result ) {
    
    	$tag_array[$result->name][] = '<a href="'. get_permalink( $result->object_id ) .'">' . $result->post_title . '</a>';
    }
    
    foreach( $tag_array as $tag => $post_titles ) {
    
    	$letter = $tag{0};
    	$letters[ $letter ][] =  $tag . ' <td class="issue-numbers"> ' . implode( ' <span class="sep">/</span>', $post_titles ) . ' </td> ';
    }
    
    foreach( $letters as $tag_letter => $tags ) {
    
    	// Create a list for each letter
    	print '<table id="index-table"><tr><td class="author-name">' . implode( '</td></tr><tr><td class="author-name">', $tags ) . '</td></tr></table>';
    }
    ?>

    If there is a way to achieve this programatically, it would be absolutely huge! If you can solve this, I honestly want to buy you a beer. ??

    All best,
    Mark

    Actually, this is going to be harder than I thought. Some people’s names are like: Ann Marie Hourihane (alphabetized by H)

    So is it possible to alphabetize the list by the last word in a tag name, regardless of how many words make up the tag name?

    Assuming there always be a space between the names you could split the string by the spaces to work out the last word.

    Something like replacing..

    // Ignore this line
    
    	$letter = $tag{0};

    ..with..

    // Ignore this line
    
    	$letter = ( strpos( $tag, ' ' ) ) ? explode( ' ',$tag ) : $tag;
    	if( is_array( $letter ) ) {
    		$letter = array_reverse( $letter );
    		$letter = $letter[0]{0};
    	}
    	else {
    		$letter = $letter{0};
    	}

    The commented line just works around a forum bug which removes tabbing on the first line.

    Hi again, thanks so much for the quick reply. Your suggested code worked wonders! The names are now grouped by the last word. Check it out: https://bit.ly/aK3oRH

    Two issues still need to be solved, though.

    1) “letter groups” should be printed in alphabetical order. So this list:

    Antonin Artaud 1
    Benedict Anderson 10
    Fergus Allen 13 /27

    Should be printed before this list:

    Angela Bourke 4 /21
    Greg Baxter 15 /27 /29 /30 /32 /34
    Harry Browne 6 /8 /10 /21 /25 /33

    2) within each “letter group”, the names should be in alphabetical order. So this list:

    Antonin Artaud 1
    Benedict Anderson 10
    Fergus Allen 13 /27

    Should actually print like this:

    Fergus Allen 13 /27
    Benedict Anderson 10
    Antonin Artaud 1

    …because Allen comes before Anderson which comes before Artaud.

    Ok needs further modification then..

    Change.

    // Ignore
    
    	$letter = $tag{0};
    	$letters[ $letter ][] =  $tag . ' <td class="issue-numbers"> ' . implode( ' <span class="sep">/</span>', $post_titles ) . ' </td> ';

    To.

    // Ignore
    
    	$letter = ( strpos( $tag, ' ' ) ) ? explode( ' ',$tag ) : $tag;
    	if( is_array( $letter ) ) {
    		$letter = array_reverse( $letter );
    		$surname = strtolower( $letter[0] );
    		$letter = $letter[0]{0};
    	}
    	else {
    		$surname = strtolower( $letter );
    		$letter = $letter{0};
    	}
    	$letters[ $letter ][ $surname ] =  $tag . ' <td class="issue-numbers"> ' . implode( ' <span class="sep">/</span>', $post_titles ) . ' </td> ';

    Also add the following…

    // Ignore
    
    	ksort( $tags );

    After.

    foreach( $letters as $tag_letter => $tags ) {

    Think that should do it… let me know.. ??

    I think we’re almost there. Now the “letter groups” are in alphabetical order by surname, which is great. But the groups themselves are jumbled up.. it starts with “F”, then “D”, then “O”, etc. Have a look: https://bit.ly/aK3oRH

    Here is the full code snippet FYI

    <?php
    
    $tags_and_posts = $wpdb->get_results("
    	SELECT tr.object_id,p.post_title,p.guid,t.name
    	FROM wp_dub_term_relationships tr
    	JOIN wp_dub_term_taxonomy tt ON tt.term_taxonomy_id = tr.term_taxonomy_id
    	JOIN wp_dub_posts p ON tr.object_id = p.ID
    	JOIN wp_dub_terms t ON tt.term_id = t.term_id
    	WHERE tt.taxonomy = 'post_tag'
    	AND p.post_status = 'publish'
    	AND p.post_type = 'page'
    	ORDER by t.name
    ");
    
    $tag_array = array();
    $letters = array();
    
    foreach( $tags_and_posts as $unwanted_key => $result ) {
    
    	$tag_array[$result->name][] = '<a href="'. get_permalink( $result->object_id ) .'">' . $result->post_title . '</a>';
    }
    
    foreach( $tag_array as $tag => $post_titles ) {
    
    	// Ignore
    	$letter = ( strpos( $tag, ' ' ) ) ? explode( ' ',$tag ) : $tag;
    	if( is_array( $letter ) ) {
    		$letter = array_reverse( $letter );
    		$surname = strtolower( $letter[0] );
    		$letter = $letter[0]{0};
    	}
    	else {
    		$surname = strtolower( $letter );
    		$letter = $letter{0};
    	}
    	$letters[ $letter ][ $surname ] =  $tag . ' <td class="issue-numbers"> ' . implode( ' <span class="sep">/</span>', $post_titles ) . ' </td> ';
    }
    
    foreach( $letters as $tag_letter => $tags ) {
    
    	// Ignore
    	ksort( $tags );
    
    	// Create a list for each letter
    	print '<table id="index-table"><tr><td class="author-name">' . implode( '</td></tr><tr><td class="author-name">', $tags ) . '</td></tr></table>';
    }
    ?>

    Before this line..

    foreach( $letters as $tag_letter => $tags ) {

    Add.

    ksort( $letters );

    SCORE! IT WORKS!
    I cannot thank you enough!!!!

    You’re welcome.. ??

    NOTE: You don’t need those // Ignore lines in the code, they were intended to be ignored (works around a forum bug when posting code).

    Hello, me again!

    I’ve restructured my content and needed to try a little tweak. For the links to the relevant posts, I needed to display the post excerpts rather than the post titles. I changed the code to the following and it worked like a charm ??

    ‘post_title’ to ‘post_excerpt’

    and

    ‘post-titles’ to ‘post_excerpts’

    I’m going to mark the topic resolved as it appears you have things working as required.

    Any problems, feel free to start a new thread. ??

Viewing 14 replies - 16 through 29 (of 29 total)
  • The topic ‘How to display the number of posts under each tag?’ is closed to new replies.