Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

I'm working on a WordPress site and I've created a page template that displays posts by a category slug. To do this, I create a field for the page, WP_Catid, and set it equal to the category slug I want to display posts from. However, I only want five posts to show up per page with pagination links at the bottom of those posts. How do I get the pagination links to display properly?

My code is as follows:

<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' );        $myposts = get_posts( $args );       foreach ( $myposts as $post ) : setup_postdata( $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>";       endforeach;        next_posts_link( 'Older Entries'); //not displaying       previous_posts_link('Newer Entries &raquo;'); //not displaying       wp_reset_postdata();     ?>   </div><!-- #content --> </div><!-- #container --> 
like image 824
B_Troutman Avatar asked Jul 19 '14 09:07

B_Troutman


People also ask

How do I get pagination page numbers in WordPress?

Since WP 3.9. 0, $paged = get_query_var( 'paged', $default ) allows a second argument with the default value. So, $paged = get_query_var( 'paged', 1 ) or $paged = get_query_var( 'paged', 0 ) (as @Kip noticed) will do.


2 Answers

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 &raquo;' );          wp_reset_postdata();     endif;     ?>  </div><!-- #content --> </div><!-- #container --> 
like image 97
Pieter Goosen Avatar answered Oct 09 '22 12:10

Pieter Goosen


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.

like image 34
indextwo Avatar answered Oct 09 '22 12:10

indextwo