Archive page…limiting posts per page

So what I have done is created a custom post type ‘testimonials’ and set the “has archive” option to “true” and have a PHP template file named “archive-testimonials.php”.

What I wan’t to do is limit the number of post being shown to only 5 with a next and back option to go back and forward to the next 5. Sounds easy enough but for some reason I can’t get it to work.

Here is my loop that shows me all 17 testimonial posts:

<?php $loop = new WP_Query( array( 'pagename' => 'testimonials', 'posts_per_page' => -1 ) ); ?>
<?php while ( $loop->have_posts() ) : $loop->the_post(); ?>
  <div>
    <h2><?php the_title(); ?></h2>
    <?php the_content(); ?>
   </div>
 <?php endwhile; ?>

The only way it will show all of them instead of just 10 is with ‘posts_per_page’ => -1. And even without that “posts_per_page” it only will show 10 of the 17 posts.

Now I have tried:

<?php $loop = new WP_Query( array( 'post_type' => 'testimonials', 'posts_per_page' => 5 ) ); ?>
<?php previous_posts_link(); ?> &bull; <?php next_posts_link(); ?>
<?php while ( $loop->have_posts() ) : $loop->the_post(); ?>
  <div>
    <h2><?php the_title(); ?></h2>
     <?php the_content(); ?>
  </div>
<?php endwhile; ?>

I can get it to show only five but I have no pagination to the next 5. I just opens “testimonials/page/2/” and shows the same five as the previous page.

What am I doing wrong. Any help is greatly appreciated.

Thanks

1 Answer
1

Don’t create a new query and loop just to alter posts per page. Add a function hooked to pre_get_posts and alter whatever parameters you want in there before the query is run. This would go in your theme’s functions.php file, or a plugin.

function wpd_testimonials_query( $query ){
    if( ! is_admin()
        && $query->is_post_type_archive( 'testimonials' )
        && $query->is_main_query() ){
            $query->set( 'posts_per_page', 5 );
    }
}
add_action( 'pre_get_posts', 'wpd_testimonials_query' );

Then in the template you run the normal loop and pagination works as expected.

Leave a Comment