How do I get pagination to work for get_posts() in WordPress?
The sweet and short of this, don't use get_posts
if you need paginated queries. get_posts
works perfectly if you are going to use a custom query that doesn't need pagination, but it really becomes a big complicated mess when you need to introduce pagination.
I think the easiest and most appropriate here is to make use of WP_Query
to construct your custom query, that is, if you can't use pre_get_posts
to alter the main query to get your desired output from the main query.
I do think that next_posts_link()
and previous_posts_link()
is better to use with a custom query, ie with WP_Query
. You must just remember however to set the $max_pages
parameter when you make use of a custom query, otherwise your pagination will break
With a few minor tweaks, your query should look like this
<div id="container"><div id="content" role="main"><?php$btpgid=get_queried_object_id();$btmetanm=get_post_meta( $btpgid, 'WP_Catid','true' );$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;$args = array( 'posts_per_page' => 5, 'category_name' => $btmetanm,'paged' => $paged,'post_type' => 'post' ); $postslist = new WP_Query( $args ); if ( $postslist->have_posts() ) : while ( $postslist->have_posts() ) : $postslist->the_post(); echo "<div style='border:2px groove black; margin-bottom:5px;'><h3 class='btposth'>"; the_title(); echo "</h3><div class='btpostdiv'>"; the_content(); echo "</div></div>"; endwhile; next_posts_link( 'Older Entries', $postslist->max_num_pages ); previous_posts_link( 'Next Entries ยป' ); wp_reset_postdata(); endif; ?></div><!-- #content --></div><!-- #container -->
Pieter Goosen's answer is completely correct, and his suggestion to use WP_Query
instead makes the most sense. However, I stumbled across this question whilst looking for pagination with get_posts
outside of the loop, so I thought this might also be a useful alternative for anyone else:
get_posts
has a direct property called offset
which achieves pretty much the same thing as paged
in WP_Query
; but where paged
refers to pagination (e.g. 1, 2, 3), offset
is the actual number of posts you want to offset your query by (e.g. 5, 10, 15). With a little maths - numberToShow * pageNumber
- you can get the correct offset easily:
$paged = (get_query_var('paged')) ? get_query_var('paged') : 0;$postsPerPage = 5;$postOffset = $paged * $postsPerPage;$args = array( 'posts_per_page' => $postsPerPage, 'category_name' => $btmetanm, 'offset' => $postOffset, 'post_type' => 'post');$myposts = get_posts($args);
The initial paged
value in this example is 0
rather than 1
because, when multiplying the posts_per_page
, you want the initial offset to be 0
rather than 5
.
This can be most handy if you want a little more granular control rather than straightforward pagination, but should work just as well in combination with the loop in the accepted answer.
Try to change your $args:
$args = array( 'posts_per_page' => 5,'category_name' => $btmetanm,'post_type' => 'post','paged' => ( get_query_var('paged') ? get_query_var('paged') : 1 ) );
And just after loop put this:
if (function_exists('wp_pagenavi')) {wp_pagenavi();}