michael ciccarelli is a web designer & developer out of buffalo, ny.
I am currently available for freelance and other opportunities.

Fix pagination on query_posts()

| 55 comments

article

Here is a simple solution for those of you looking to customize your WordPress theme, to use the WordPress query_posts() function to retrieve your blog posts rather than the standard loop.

I created a custom Page Template named “Blog” using query_posts() and assigned this template to be used on a designated Blog page within my site at http://michaelciccarelli.com/blog/ (a Blog within a Blog even). I did this mainly because my original homepage didn’t really resemble a traditional blog and I wanted something more than just your average archives page that only lists the titles of all your previous blog posts.

So here’s my Blog Page Template’s Source Code:


<?php
/*
Template Name: Blog page
*/
?>
<?php get_header(); ?>
<div id="content">
  <div id="primary">
    <?php
    $limit = get_option('posts_per_page');
    $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
    query_posts('showposts=' . $limit . '&paged=' . $paged .'&cat=-166,-167,-168');
    $wp_query->is_archive = true; $wp_query->is_home = false;
    ?>
    <?php if (have_posts()) : while (have_posts()) : the_post(); ?>
    <div class="blog-post" id="post-<?php the_ID(); ?>">
      <h2><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent link to <?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
      <div class="post-entry">
          <?php the_content(__('Read the rest of this entry &raquo;')); ?>
      </div>
    </div><!-- /post -->
    <?php endwhile; ?>

    <!-- Page Navigation -->
    <?php if (function_exists('wp_pagenavi')) : ?>
    <div class="pagenavi">
        <?php wp_pagenavi(); ?>
    </div>
    <?php else : // Use WordPress default page navigation. ?>
    <div class="pages">
        <span class="older"><?php next_posts_link('&laquo; Older Entries'); ?></span>
        <span class="newer"><?php previous_posts_link('Newer Entries &raquo;'); ?></span>
    </div>
    <?php endif; ?>
    <?php else : ?>
    <div class="blog-post">
        <h2 class="post-title"><?php _e('404 - Not Found'); ?></h2>
        <div class="post-entry">
          <p><?php _e('Sorry, no posts matched your criteria.'); ?></p>
          </div>
  </div>
  <?php endif; ?>
      </div>
      <?php get_sidebar(); ?>
</div><!-- content -->
<span class="clr"></span>
<?php get_footer(); ?>

Notes:

The only bit you may want to alter in the function that retrieves your posts is the 3rd line in from top:query_posts('showposts=' . $limit . '&paged=' . $paged .'&cat=-166,-167,-168');

Notice the &cat=-166,-167,-168 this basically says exclude the following category IDs, which in my case are portfolio categories, that I don’t want to display in my blog section. This parameter is more commonly used like cat=1,3,5 which will only return posts from those categories.

$limit is assigned the ‘posts_per_page’ option from your WordPress settings, this stopped working for me for some reason but not a big deal because it can be changed to something specific, like: $limit = 20;


$wp_query->is_archive = true;
$wp_query->is_home = false;

These variables that come after the query_posts() are important as they force posts_nav_link() (and so pagination) to work, along with a few other helpful results gained for fooling WordPress into thinking we’re in the archive pages.

For the $paged stuff, see: this support forum postSource [via WordPress Support]

Tags: , ,

55 Responses

  1. Ivette says:

    thanks a lot, you’ve saved my day :)

  2. Adam says:

    So glad to see that this solution just came out so maybe I’m not that far behind.

    Thanks so much!

  3. james says:

    Fantastic! I’ve been searching for the solution to this for several hours. Many thanks :-)

  4. James says:

    Hey… just found this post after looking for a little while thanks. Wanted to add i was using a plugin called redirection to handle when i rename posts and also to help remove the category base from the permalink url.

    The plugin was causing a 404 when going to page 2. I had to disable one of it’s redirect matches. I haven’t ascertained whether it will throw off the rest of my site… we shall see.

    Thanks for the help, led me on the right path!

  5. Kyle says:

    Just a simple: Thanks!

  6. [...] Fix pagination on query_posts() | MikeChick.net reddit_url=’http://www.baby-parenting.com/lma/directory/Kids_&_Teens/School_Time/Science/Chemistry/Class_Pages/Class_Pages.html’ reddit_title=’Website Directory – Class Pages’ [...]

  7. Will Dawson says:

    Thank you so much! Been searching for this for about 3 days.

  8. RobInjection says:

    Dude, thank you sooooo much. I spent 3 hours trying to figure this out and almost pulled my hair out. You are a king amongst men! ;)

  9. Caroline says:

    Thank you so much for this. As like the others, I was searching for a straight-forward answer for a while.

    My only problem is using WordPress’ option of using a static homepage. On the page that I selected as the Posts page, the page links break. When I click on a different page number, I get redirected to my 404 error page.

    Do you know how to solve this problem?

    It may help to know that I am also using the Advanced Category Excluder plugin by DjZoNe. However, even when I tell it not to exclude any categories for both the home and archive pages, it still doesn’t work.

    This is my query_posts function:

    query_posts( array(
    “showposts” => $limit,
    “paged” => $paged,
    “cat” => implode(“,”, get_archiveCats(1))
    ));

    I created a function that allows me to dynamically change which categories are included in the archive list.

    I hope this makes sense, and any help will be awesome.

  10. Nicole says:

    I’m probably a bit late on this one..
    Thank-you!!

    p.s: really like the look of your site- very clean and simple- love the transparency.

  11. Thank you so much! The explanation of query_posts on the WP Codex is faulty. Merely placing query_posts(“cat=-4″) doesn’t work. Your post is gold!

  12. [...] As a very useful way of excluding a category from the index. But it doesn’t work so well on archives. Especially not when these are paginated. The problem was that now every older or newer entry was actually the same. Thankfully, the brilliant Michael Ciccarelli, figured out a way to overcome this problem: [...]

  13. Mike says:

    This is some good stuff. Nice site too. I was just looking for a way to include pagination, so thanks.

  14. excelent my friend!!!!!!!!!!!!!!!!!!!!! eres un genio, very god job!! :) )))))))

  15. Rob Anderson says:

    Thank you so much – this was exactly the probelm I ws trying to solve :)

  16. coco says:

    thanks a lot.
    now I can list all my posts on a page template.

    if someone has problem read more content, he/she should insert the following

    global $more;
    // set $more to 0 in order to only get the first part of the post
    $more = 0;

  17. [...] Michael Ciccarelli has a better solution. [...]

  18. Daniel says:

    Hi Michael, this fix is working fine, but when using a numbered pagination with a plugin like “wp-page-numbers” there are empty pages because excluded items are included in the total count. Do you have any idea how to fix that? Thank you!

  19. Based on examples I found on WordPress and the solution on this post, here’s a simpler version that worked for me. Thanks for posting this information, was a lot of help. – Henry

Leave a Reply