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

There's a file called inform.php included in index.php, single.php and single-news.php with the below query in it:

    $arr = array('cat' => '12837', 'posts_per_page' => '22');
    $query1 = new WP_Query($arr);
    while($query1->have_posts()) : $query1->the_post();
    <li><a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>"><?php the_post_thumbnail("icon-40", array('class' => 'right icon-40')); ?><?php /*<span class="app-name"><?php echo text_excerpt(get_the_title(), 67); ?></span>*/ ?></a></li>

It returns exact 22 number of posts in index.php and single.php but in single-news.php it returns only one post.

There is no difference between single.php and singel-news.php except styling and displaying some custom fields.

Also I checked for wp_reset_postdata(); to be considered after each custom query I wrote, but yet there is that strange result.

Single news template will load by this function:

function custom_cat_single_file($single_template) {
  global $post;
   if ( in_category( 'news' ) && !in_category('mac-game')) {
      $single_template = dirname( __FILE__ ) . '/single-news.php';
  return $single_template;
add_filter( "single_template", "custom_cat_single_file" );

Update #1

Reformatted var_dump($query1->request);

string(476) "SELECT SQL_CALC_FOUND_ROWS wp_posts.id 
FROM   wp_posts 
       INNER JOIN wp_term_relationships 
               ON ( wp_posts.id = wp_term_relationships.object_id ) 
WHERE  1 = 1 
       AND ( wp_term_relationships.term_taxonomy_id IN (12837) ) 
       AND wp_posts.post_type = 'post' 
       AND ( wp_posts.post_status = 'publish' 
              OR wp_posts.post_status = 'private' ) 
       AND wp_posts.post_date >= '2014:03:21 00:00:00' 
       AND wp_posts.post_date < '2015:03:21 00:00:00' 
GROUP  BY wp_posts.id 
ORDER  BY wp_posts.post_date DESC 
LIMIT  0, 22"

I've a pre_get_post hook but I don't think it affects something.

function post_in_page( $query ) {
  // not an admin page and is the main query
  if (!is_admin() && $query->is_main_query()){
      $current = get_query_var('cat');
      $cat = get_category ($current);
      if($cat->slug != 'news')
        $query->set('posts_per_page', 25);
add_action( 'pre_get_posts', 'post_in_page');

Update #2

As @s_ha_dum noticed about dates, I didn't found any hooked function however I didn't go deep in all plugins files.

So I ended up with modifying WHERE clause of query:

function so__weird()
  function filter_where( $where = '' ) {
    $where = preg_replace("/ AND\s+wp_posts\.post_date.*?wp_posts\.post_date.+[^'].*?'/s", '', $where);
    return $where;
  add_filter( 'posts_where', 'filter_where' );

and calling so__weird() at the needed place.

share|improve this question
And nothing changes when you comment out the posts_per_page setting in your pre_get_posts function? – Howdy_McGee Mar 25 '14 at 14:37
@Howdy_McGee No, nothing changes. It's obvious that it doesn't do nothing with that single template, however nothing is impossible! – revo Mar 25 '14 at 14:45
up vote 1 down vote accepted

There is no reason that query should behave differently on a single post page than on any other page. That is, there is no reason in the code posted. The only thing that I can think of would be that there is a filter interfering-- perhaps a poorly written filter on pre_get_posts or post_limits.

You should be able to verify the SQL coming out of that query with var_dump($query1->request);, and if it ends with anything other than LIMIT 0, 22 you have something interfering.

Based on additional information in the question:

The pre_get_posts callback you posted should not, unless I am reading wrong, cause the query to return a single post. It should return more than 22 if anything. However, there are date conditions in that query...

   AND wp_posts.post_date >= '2014:03:21 00:00:00' 
   AND wp_posts.post_date < '2015:03:21 00:00:00' 

... that are not accounted for by your explicit query arguments. There must be another filter somewhere.

share|improve this answer
Thanks. You may consider seeing my update. – revo Mar 25 '14 at 14:30
Updated my post. +1 for being a good debugger guy. – revo Mar 25 '14 at 21:10

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.