I’m using WP_Query to create ‘latest posts’ & ‘popular posts’ sections on my home page. I’m trying to just pull 5 posts from 2 categories (9 & 11) but it will only show posts from cat 9.
Here’s the php I’m using for ‘latest posts’-
<ul>
<?php
$cat = array(9,11);
$showposts = 5;
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args=array(
'category__in' => $cat,
'showposts' => $showposts,
'paged' => $paged,
'orderby' => 'post_date',
'order' => 'DESC',
'post_status' => 'publish',
);
$the_query = new WP_Query ( $args ); //the query
$i = 0;while ($the_query->have_posts() ) : $the_query->the_post(); //start the loop
?>
<?php
if($i==0){ //Sets the output for the top post
?>
<li class="first-news">
<div class="post-thumbnail"><a href="<?php the_permalink(); ?>"><?php the_post_thumbnail(350,187); ?></a></div>
<h2 class="post-box-title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<p class="post-meta"><span class="tie-date"><?php the_time('F jS, Y') ?></span></p>
<div class="entry"><?php the_excerpt(); ?></div>
<div><a class="more-link" href="<?php the_permalink(); ?>">Read More »</a></div>
</li>
<?php
$i++;
} else { ?>
<li class="other-news rar">
<div class="post-thumbnail"><a href="<?php the_permalink(); ?>"><?php the_post_thumbnail(145,93); ?></a></div>
<h3 class="post-box-title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
<p class="post-meta"><span class="tie-date"><?php the_time('F jS, Y') ?></span></p>
</li>
<?php } endwhile; //end of the loop ?>
<?php wp_reset_postdata(); // reset the query ?>
</ul>
Any suggestions?
In my experience using
'posts_*'
filters ('posts_request'
,'posts_where'
…) in combination withstr_replace
/preg_replace
is unreliable and unflexible:Unreliable because if another filter modify uses one of that filters, in better case one gets unexpected results, in worst cases one gets SQL errors.
Unflexible because changing an argument, e.g. ‘include_children’ for categories, or reuse the code for e.g. 3 terms instead of 2 need a lot of works.
Moreover, adapt code to be musltisite compatibe need to edit SQL manually.
So, sometimes, evevn if not the best solution regarding performance, a more canonical approach is the best and more flexible one.
And performance can be improced with some caching tricks…
My propose:
usort
to order posts coming from different queries (e.g. one per term)Code
First the function that order posts:
Then the function that get non cached results:
Now the function that check cache and return it if available or return non cached results
Cache is auto-cleaned daily, however, is possible to invalidate it everytime a new post in on a specific taxonomy is added or updated. That can be done adding a cleaning cache function on
'set_object_terms'
Usage
Functions are flexible enough to use complex queries, even queries for additional taxonomies:
E.G.
In this way the ‘tax_query’ set in
$args
array will be merged dinamically with the tax query argument in$base_tax_args
, for each of the terms in the$terms
array.Is also possible order posts in ascending order:
Please note:
According to the Codex:
And, the Codex’s Pagination Parameters says that,
'showposts'
is deprecated and replaced with'posts_per_page'
.What you are asking is a near duplicate of this question: How do I create my own nested meta_query using posts_where / posts_join?
The problem, as @fischi suggests, is almost certainly that results are coming from one category or the other and hitting the post limit before both are equally represented. To make this work, you need a UNION.
WP_Query
is not capable of that logic, but with hooks you can make it work.A couple of notes:
WP_Query
will parse the category argument and find category children so the firstUNION
will include all of the children of category 9. I did not duplicate that logic for category 11. If you need that functionality, you can refer to theWP_Query
source and reproduce the effect.