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 am building a section on a site where I am merging two different post types into one loop, and then displaying them randomly. The problem is, I'm having a hard time finding a way to limit the amount of posts per type.

Here's what I've tried:

  • One query with multiple post types can be achieved with an array:

    $args = array( 'post_type' => array( 'photos', 'quotes' ), ...
    

    ... but cannot limited to a certain number of posts per type.

  • Merging two query argument arrays before running WP_Query on it:

    $photos = array( 'post_type' => 'photos', 'posts_per_page' => 15, 'orderby' => 'rand' );
    $quotes = array( 'post_type' => 'quotes', 'posts_per_page' => 5, 'orderby' => 'rand' );
    
    $args = $photos + $quotes;
    // Also tried array_merge( $photos, $quotes );
    

    No luck on this. What happens is the latter variable $quotes overwrites $photos and only shows the quotes.

  • Merging two WP_Query objects together through typecasting:

    $photos_query = new WP_Query( $photos );
    $quotes_query = new WP_Query( $quotes );
    $result = (object)array_merge( (array)$photos_query, (array)$quotes_query );
    

... and so on.

I could probably use an SQL query straight to the database, but I need to be able to combine these two separate post types for one loop, arranged randomly, AND limited to a certain amount of posts per type.

Thanks for your help!

share|improve this question
add comment

2 Answers 2

up vote 4 down vote accepted

One way is to customize the SQL query executed using posts_clauses or other such filters. To find them search for posts_clauses in "wp-includes/query.php" & see the series of filters just before this line. These together are capable of customizing any part of the query

Another thing you can do is manually merge the queried posts in the objects

$photos_query = new WP_Query( $photos );
$quotes_query = new WP_Query( $quotes );
$result = new WP_Query();

// start putting the contents in the new object
$result->posts = array_merge( $photos_query->posts, $quotes_query->posts );

// here you might wanna apply some sort of sorting on $result->posts

// we also need to set post count correctly so as to enable the looping
$result->post_count = count( $result->posts );
share|improve this answer
    
Your second solution (without the SQL) did the trick! Now I have complete control over what is going into that final query before going into the loop. Thanks for your help! –  Andy Merskin Nov 5 '12 at 8:34
    
The first one is difficult but more efficient(in second there are still 2 database queries). I would say it comes down to personal preference –  Mridul Aggarwal Nov 5 '12 at 8:54
add comment

@mridual aggarwal your answer is very very good but unfortuntly it is not really combining the 2 wp_query it is only shows the posts from both in arrange i mean 5 posts from the first & 5 from the second but not sorted all in one so i have this solution & it exactly achieved the goal for my self at least

<?php
$term = get_term_by( 'slug', get_query_var( 'tag' ), "post_tag" );
$tagslug = $term->slug;
$post_types = get_post_types('','names');
?>
<?php
//first query
$blogposts = get_posts(array(
    'tag' => $tagslug, //first taxonomy
    'post_type' => $post_types,
    'post_status' => 'publish',
    ));
//second query
$authorposts = get_posts(array(
    'bookauthor' => $tagslug, //second taxonomy
    'post_type' => $post_types,
    'post_status' => 'publish',
    ));
$mergedposts = array_merge( $blogposts, $authorposts ); //combine queries

$postids = array();
foreach( $mergedposts as $item ) {
$postids[]=$item->ID; //create a new query only of the post ids
}
$uniqueposts = array_unique($postids); //remove duplicate post ids

$posts = get_posts(array(
        //new query of only the unique post ids on the merged queries from above
    'post__in' => $uniqueposts,  
    'post_type' => $post_types,
    'post_status' => 'publish',
    ));
foreach( $posts as $post ) :
setup_postdata($post);
?>
// posts layout
<?php endforeach; ?>
<?php wp_reset_postdata();?>
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.