Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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()?

share|improve this question
add comment

2 Answers 2

up vote 3 down vote accepted

Yes, get_posts is the safest way to use multiple loops. It does not mess up with the original query.

Another way would be to create new WP_Query objects:

$my_query = new WP_Query($args);
while ($my_query->have_posts()) : $my_query->the_post();

Note: Why you should not use query_posts()

share|improve this answer
    
So should i use get_posts() or WP_Query()? What way would you recommend? –  dotty Oct 6 '10 at 8:11
    
get_posts() uses WP_Query(), so I personally prefer the later. I find it more powerful, more flexible,... –  sorich87 Oct 6 '10 at 9:19
    
get_posts() worked a treat in conjunction with setup_postdata() –  dotty Oct 6 '10 at 10:31
add comment

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:

share|improve this answer
add comment

Your Answer

 
discard

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.