WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Is it possible to create a loop that goes through all the available custom post types without statically defining what those custom post types are, and then displaying the featured image of the first post for each of those custom post types?

share|improve this question
up vote 3 down vote accepted

This should work for you:

// grab all public post types
$post_types = get_post_types( array('public' => true), 'names' );

// loops through each post type
foreach( $post_types as $type ) {

    // setup the query
    $query_args = array(
        'post_type' => $type,
        'posts_per_page' => 1

    // perform the query
    $items = get_posts( $query_args );

    // check if we have found anything
    if( $items ) {

        // loop through the items
        foreach( $items as $item ) {

            // show the post thumbnail
            echo get_the_post_thumbnail( $item->ID, 'thumbnail' );



share|improve this answer
That's amazing, thank you so much Pippin! One tiny nitpick, there's a comma missing after the first property of the $query_args array. Apart from that, brilliant solution. – Squrler Jul 8 '12 at 14:56
Fixed the missing comma. – Pippin Jul 8 '12 at 15:23
One more question: is it possible to exclude certain post types from this query? – Squrler Jul 8 '12 at 15:33
@Squrler See my addition to Pippins answer below. In any case - if you want to exclude/include custom post types - you'll have to manually unset the from the $post_types array or filter them out with an foreach() and ! in_array() or something similar. – kaiser Jul 8 '12 at 16:37

As an addition to @Pippin answer:

It is even possible to use a single query, with a slightly different syntax.

// Get all post types
$post_types = get_post_types( 
         'public'       => true
         // Avoid attachments - those aren't shown in the admin menu
        ,'show_in_menu' => true 

// Get rid of unwanted post types
// Use the array to add your unwanted post types
foreach ( array( 'some_unwanted_post_type', 'another_one' ) as $not_me )
    in_array( $not_me, $post_types ) AND unset( $post_types[ $not_me ] );

// Group by filter
add_filter( 'posts_groupby', 'wpse57806_posts_groupby', 20 );

// Query posts - Two options for post_types
$items = get_posts( array(
     'post_type'      => $post_types
    // ... or ...
    # 'post_type'       => 'any' // every post type, but not attachments
    ,'posts_per_page' => count( $post_types )
) );

// Call the thumbnail
foreach ( $items as $item )
    echo get_the_post_thumbnail( $item->ID, 'thumbnail' );


You'll need a small callback function to make the edit work:

function wpse57806_posts_groupby()
    // only needed once - better kept in here
    remove_filter( current_filter(), __FUNCTION__ );

    return 'post_type';
share|improve this answer
That won't output one of each type though, no? If there are 5 types, but the 5 most recent posts are all of one type, you'll get 5 of that single type. – Milo Jul 8 '12 at 16:52
@Milo 'orderby' => 'post_type' should do the trick. I just have no setup with 5 different post types + 50 posts available. – kaiser Jul 8 '12 at 17:00
@Milo No, you're right. That will make it even worth, as we'd get 5 of the first post_type. Have to reconsider my answer. Guess it won't work without filtering the query... and adding something like a DISTINCT to it. – kaiser Jul 8 '12 at 17:01
@Milo I guess I found a solution, that should work seamlessly. – kaiser Jul 8 '12 at 17:07

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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