Pagination Within A Page In WordPress

pagination Pagination Within A Page In WordPress

WordPress 3.0 is coming with 2 interesting features: custom post types and (improved) custom taxonomies. These 2 features help us to create different content (not only traditional blog posts) and classify them in many ways. To list all this content in a page like an archive page, we often use the query_posts() function in a custom page template. The problem is: if the content is big (many custom posts), we might want to separate them in pages, but how to paginate the content within an archive page?

For example, we have a custom template for our archive page like this:

<?php
/*
 * Template name: Custom archive
 */
?>

<?php get_header(); ?>

    <div id="container">
        <div id="content">
        <?php
        query_posts(array(
            'post_type' => 'film', // can be custom post type
            'series' => 'hdtv' // custom taxonomy
        ));

        if (have_posts()):
        ?>
        <ul>
        <?php while (have_posts()): the_post(); ?>
            <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
        <?php endwhile; ?>
        </ul>
        <?php endif; ?>
        </div><!-- #content-->
    </div><!-- #container -->

<?php get_footer(); ?>

(Save the code above in a PHP file within theme folder with any name and then create a page in Admin Dashboard, choose the template ‘Custom archive’ from the Template box on the right to make it in action.)

Here I use query_posts() to get posts with film as custom post type and hdtv as custom taxonomy series. By default, this query returns all posts we need, and they’ll be listed in an unordered list.

To add pagination to this archive page, first we implement the pagination navigation links (previous and next pages). Fortunately, the next_posts_link() and previous_posts_link() both work with a page. So, we add them right before the close </ul> tag:

</ul>
    <div class="nav-previous"><?php next_posts_link('← Older posts'); ?></div>
    <div class="nav-next"><?php previous_posts_link('Newer posts →'); ?></div>
<?php endif; ?>

Now you can go to our custom archive page to test. The pagination links are there, but when we click on them, we get the same page.

That’s because WordPress is not told the current page number. Actually, when we click on a pagination link, WordPress saves all query variables in a global variable $wp_query->query_vars, which is an array. The current page number is saved in $wp_query->query_vars['paged'], too but it is not used at all. Why? Because in our custom query, we only use the post_type and series variables:

query_posts(array(
'post_type' => 'film', // can be custom post type
'series' => 'hdtv' // custom taxonomy
));

That means we’ve already reset the query and clear all query variables, including current page number.

So, we need to get the current page number before using custom query, and then put it in the custom query. There are some ways to get the current page number:

1. Using $wp_query->query_vars array

$wp_query->query_vars contains all query variables. Our current page number is saved as $wp_query->query_vars['paged']. So obviously we can use it to get the current page number:

<?php
global $wp_query;

$paged = (empty($wp_query->query_vars['paged'])) ? 1 : $wp_query->query_vars['paged'];

query_posts(array(
'post_type' => 'film', // can be custom post type
'series' => 'hdtv', // custom taxonomy
'paged' => $paged // set the current page
));

if (have_posts()):

// Loop
?>

2. Using get_query_var() function

The get_query_var() function return value of a query parameter. Unfortunately, this function does not have full documentation in Codex now.

We can use get_query_var() function to get the current page number like this:

<?php
$paged = get_query_var('paged');

query_posts(array(
'post_type' => 'film', // can be custom post type
'series' => 'hdtv', // custom taxonomy
'paged' => $paged // set the current page
));

if (have_posts()):

// Loop
?>

3. Using global variable $paged

This maybe the simplest and fastest method to get the current page number. By default, WordPress saves the current page number not in $wp_query->query_vars array only, but also in global variable – $paged. So all we need to do is just declare it and use it immediately:

<?php
global $paged;

query_posts(array(
'post_type' => 'film', // can be custom post type
'series' => 'hdtv', // custom taxonomy
'paged' => $paged // set the current page
));

if (have_posts()):

// Loop
?>

These are 3 methods to get the current page number. I sorted them in order of increased simplicity, but you see, all of them are simple and can be implemented easily in a custom page template. Using pagination within a page can make your blog more powerful and flexible to display content. Everyone when looks at the custom page with pagination inside, will not easily recognize the type of this page.

10 Comments

  1. Thanx alot for the tutorial…i was pissed of with the same problem the whole day and finally got it right..Thanx again

    Reply
  2. If you use query_posts as the example above, then you can paginate with built-in WP functions like next_posts_link.

    Or you can divide the post into many pages, using this

    Reply
  3. Thanks for solution its working for me. I have searching for this solution for some days and stumbled at this site finally.

    Reply
  4. ‘paged’ => $paged this line solved problem of pagination at my custom template.
    Thanks

    Reply
  5. Question here…

    I use your script but the problem now is my custom template can’t find the next page…

    if my custom page is ‘testimonials’, the generated second post is /testimonais/page/2 and I am getting 404…

    Any thoughts on this?

    Thanks,

    Patrick

    Reply

Leave a Reply