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

I'm having a very peculiar bug with pagination :( I'm trying to display 4 posts per page for a category with slug "lastest-news".

The pagination function seems to work correctly. There are 33 posts. The pagination gets constructed correctly with 9 pages and links of following format: /category/lastest-news/page//

The interesting thing is that it works correctly (displaying 4 posts per page) from page 1-4 including. However, for pages 5-9 it doesn't work at all. It doesn't even seem to serve the template... the only error that I could spot is of the page saying "Nothing found for Category Lastest-news Page 5".

I would understand if it won't work at all, but for randomly 4 pages and not more?

I would really really appreciate any help! I've spend about over 4 hours trying to figure out what's wrong and it's bugging me.

Thanks for help :)

I'm using the following code for query:

$page = get_query_var('paged');
$posts_on_page = new WP_Query("posts_per_page=4&category_name=lastest-news&paged=".$page);

//loop to display every one of 4 posts


I'm using pagination function from this post: http://www.kriesi.at/archives/how-to-build-a-wordpress-post-pagination-without-plugin

Here is the function (which seems to work fine):

function pagination($pages = '', $range = 2){  
 $showitems = ($range * 2)+1;  

 global $paged;
 if(empty($paged)) $paged = 1;

 if($pages == '')
     global $wp_query;
     $pages = $wp_query->max_num_pages;
         $pages = 1;

 if(1 != $pages)
     echo "<div class='pagination'>";
     if($paged > 2 && $paged > $range+1 && $showitems < $pages) echo "<a href='".get_pagenum_link(1)."'>&laquo;</a>";
     if($paged > 1 && $showitems < $pages) echo "<a href='".get_pagenum_link($paged - 1)."'>&lsaquo;</a>";

     for ($i=1; $i <= $pages; $i++)
         if (1 != $pages &&( !($i >= $paged+$range+1 || $i <= $paged-$range-1) || $pages <= $showitems ))
             echo ($paged == $i)? "<span class='current'>".$i."</span>":"<a href='".get_pagenum_link($i)."' class='inactive' >".$i."</a>";

     if ($paged < $pages && $showitems < $pages) echo "<a href='".get_pagenum_link($paged + 1)."'>&rsaquo;</a>";  
     if ($paged < $pages-1 &&  $paged+$range-1 < $pages && $showitems < $pages) echo "<a href='".get_pagenum_link($pages)."'>&raquo;</a>";
     echo "</div>\n";
share|improve this question
up vote 5 down vote accepted

WordPress does its own query on every page. You should modify that query instead of creating a new one. What happens now is that WordPress does a query with the standard posts per page of 10, but you don't do anything with these results and do your own query. This works... until WordPress goes beyond post #33, which is on page number 4.

  1. WordPress queries 1-10, your template queries 1-4
  2. WordPress queries 11-20, your template queries 5-8
  3. WordPress queries 21-30, your template queries 9-12
  4. WordPress queries 31-40, your template queries 13-16
  5. WordPress queries 41-50, but gets no results, so it gives 404. Your template doesn't load.

So instead you should modify the standard query that WordPress will execute, by placing this in your functions.php or in a plugin:

add_action( 'pre_get_posts', 'wpse7687_pre_get_posts' );
function wpse7687_pre_get_posts( &$wp_query ) {
    if ( $wp_query->is_category && 'latest-news' == $wp_query->get_queried_object()->slug ) {
        $wp_query->set( 'posts_per_page', 4 );
share|improve this answer
Oh that makes sense. I thought if I specify my own query everything will be tired up to that... I've added the code to the functions.php but it still seems to have 10 posts per page :S – dashaluna Jan 25 '11 at 17:52
I've changed the syntax of the if statement a bit - I think that was the reason. Thank you sooo much for taking time and explaining to me what was wrong :) – dashaluna Jan 25 '11 at 18:26
@DashaLuna: Of course, silly me, you can't ask for the current query object before you execute the query! – Jan Fabry Jan 25 '11 at 20:15

Based on @Jan Fabry reply I've change the syntax a bit. It works well. Thanks Jan for the explanation!!!

add_action( 'pre_get_posts', 'wpse7687_pre_get_posts' );
function wpse7687_pre_get_posts( &$wp_query ) {
  if ($wp_query->query_vars['category_name'] == 'latest-news'){
    $wp_query->query_vars['posts_per_page'] = 4;
share|improve this answer

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.