Show the First Post from Each of 3 Different Post Types on a Web Page?

I have 3 different custom post types: 1.) "events", 2.) "winners" and 3.) "offers". How would I go about retrieving the first (latest) post in each of these post types on a single web page (i.e a home page).

Would I use get_posts() or would I have to manipulate the_loop()?

Related posts

Leave a Reply

2 comments

  1. Hi @dotty:

    The answer from @sorich87 is correct, but I thought I’d elaborate a bit. I’ve coded a class for you called (verbosely) LatestPostPerPostTypeQuery and you can use it in the loop in place of WP_Query, like so:

    <ul>
    <?php $args = array('post_type'=>'events,winners,offers'); ?>
    <?php $query = new LatestPostPerPostTypeQuery($args); ?>
    <?php while($query->have_posts()): $query->the_post(); ?>
      <li><?php the_title(); ?></li>
    <?php endwhile; ?>
    </ul>
    

    Below is the code for the LatestPostPerPostTypeQuery class which you can copy into your theme’s functions.php file (or use the code in a plugin if you like.) The nice thing about this alternative to WP_Query is it does a single query to the database instead of one for each of the three post types like you’d be forced to use when using WP_Query() directly.

    <?php
    class LatestPostPerPostTypeQuery extends WP_Query {
      var $flag;
      function __construct($args=array()) {
        $this->LatestPostPerPostTypeQuery($args);
      }
      function LatestPostPerPostTypeQuery($args=array()) {
        if (isset($args['post_type']) && !is_array($args['post_type']))
          $args['post_type'] = explode(',',$args['post_type']);
        $this->flag = true;
        parent::query($args);
      }
      static function on_load() {
        add_filter('posts_join',array(__CLASS__,'posts_join'),10,2);
      }
      static function posts_join($join,$query) {
        if (isset($query->flag)) {
          global $wpdb;
          $join .=<<<SQL
    INNER JOIN (
    SELECT post_type,MAX(post_date) AS post_date
    FROM {$wpdb->posts}
    GROUP BY post_type) max_date ON 
      max_date.post_type={$wpdb->posts}.post_type AND 
      max_date.post_date={$wpdb->posts}.post_date
    SQL;
        }
        return $join;
      }
    }
    LatestPostPerPostTypeQuery::on_load();
    

    I’ve also posted a standalone file on Gist allowing you grab the source code and drop the example into a file in the root of your website to call it directly from the browser to watch it in action: