Custom post pagination in WordPress

If you’re dealing with lots of custom posts in WordPress and if you’re a theme developer, it is probably a well known issue to you. Lots of people are discussing about this pagination thing in different forums. However, it’s really not that tough to paginate custom posts. Let’s find out how we can do it easily.

Query CPTs

This is the first thing you are going to need, is to write a custom query. Because when you have a bunch of posts in your collection, you will start thinking about the pagination. So it’s time to find some posts. The following code will find all the posts of post type book and display their titles

[code lang=php]
$books = new WP_Query( array(
"posts_per_page" => – 1,
"post_type" => "book"
) );

while ($books->have_posts()){
$books->the_post();
the_title();
echo "<br/>";
}

[/code]

Now you’re probably going to use the good old next_posts_link() to display the next page. Well, that will not work because at this point next_posts_link() doesn’t know how many pages are there. So to make it work, you’ll have to pass the number of total pages found by your query. How is this total number of pages are calculated by the way?

[code lang=php]
$total_pages = ceil( $books->found_posts / get_option('posts_per_page') );
[/code]

Interestingly, you don’t need to calculate the total number of pages like this. A WP_query object already did it for you and made it available via max_num_pages property.

[code lang=php]
$total_pages = $books->max_num_pages;
[/code]

Now we need that value to show the link to our next page. Just pass it to next_posts_link() like this

[code lang=php]
next_posts_link('Prevous Posts',$books->max_num_pages)
[/code]

Now it wil show a valid link that can take you to the previous posts page. If your url is http://yoursite.com/books/ then, the link of the previous posts will be of this format http://yoursite.com/books/page/2. So you’re going to need this page number in your PHP script to fetch all the posts (or CPTs) from that page. In your theme, you can get this page number using a query var called paged. The following code will correctly fetch the current page number

[code lang=php]
$current_page = get_query_var('paged') ? get_query_var('paged'):1;
[/code]

To fetch all the posts from this page, you just need to rewrite your WP_Query like this

[code lang=php]
$books = new WP_Query( array(
"posts_per_page" => – 1,
"post_type" => "book",
"paged" => $current_page
) );
[/code]

In case you’d like to see a traditional pagination using page numbers, you will have to use the following code

[code lang=php]
paginate_links( array(
"current" => $current_page,
"total" => $books->max_num_pages
) );
[/code]

And you’re done 🙂