How do I get pagination to work for get_posts() in WordPress? How do I get pagination to work for get_posts() in WordPress? wordpress wordpress

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();}