WordPress custom loop with pagination

<?php
if ( get_query_var('paged') ) {
	$paged = get_query_var('paged');
} elseif ( get_query_var('page') ) { // 'page' is used instead of 'paged' on Static Front Page
	$paged = get_query_var('page');
} else {
	$paged = 1;
}
 
$custom_query_args = array(
	'post_type' => 'post', 
	'posts_per_page' => get_option('posts_per_page'),
	'paged' => $paged,
	'post_status' => 'publish',
	'ignore_sticky_posts' => true,
	//'category_name' => 'custom-cat',
	'order' => 'DESC', // 'ASC'
	'orderby' => 'date' // modified | title | name | ID | rand
);
$custom_query = new WP_Query( $custom_query_args );
 
if ( $custom_query->have_posts() ) :
	while( $custom_query->have_posts() ) : $custom_query->the_post(); ?>
 
		<article <?php post_class(); ?>>
			<h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
			<small><?php the_time('F jS, Y') ?> by <?php the_author_posts_link() ?></small>
			<div><?php the_excerpt(); ?></div>
		</article>
 
	<?php
	endwhile;
	?>
 
	<?php if ($custom_query->max_num_pages > 1) : // custom pagination  ?>
		<?php
		$orig_query = $wp_query; // fix for pagination to work
		$wp_query = $custom_query;
		?>
		<nav class="prev-next-posts">
			<div class="prev-posts-link">
				<?php echo get_next_posts_link( 'Older Entries', $custom_query->max_num_pages ); ?>
			</div>
			<div class="next-posts-link">
				<?php echo get_previous_posts_link( 'Newer Entries' ); ?>
			</div>
		</nav>
		<?php
		$wp_query = $orig_query; // fix for pagination to work
		?>
	<?php endif; ?>
 
<?php
	wp_reset_postdata(); // reset the query 
else:
	echo '<p>'.__('Sorry, no posts matched your criteria.').'</p>';
endif;
?>

WordPress query functions

  • query_posts() is overly simplistic and problematic way to modify main query of a page by replacing it with new instance of the query. It is inefficient (re-runs SQL queries) and will outright fail in some circumstances (especially often when dealing with posts pagination). Any modern WP code should use more reliable methods, like making use ofpre_get_posts hook, for this purpose. TL;DR don't use query_posts() ever;

  • get_posts() is very similar in usage and accepts same arguments (with some nuances, like different defaults), but returns array of posts, doesn't modify global variables and is safe to use anywhere;

  • WP_Query class powers both behind the scenes, but you can also create and work with own object of it. Bit more complex, less restrictions, also safe to use anywhere.

4 comments on “WordPress custom loop with pagination

  1. The pagination is working for me partially. Unfortunately, it is only returning page one and two, when i try to exceed to order posts meaning to page three, it get stuck and repeats to page 2. Kindly assist me....

  2. Hans Peter

    Is it possible also add between pagina numbers like
    Older 1,2,3,4,5,6... 25 Newer

  3. Pingback: [WP 类] WP_Query - WordPress 类 - MoMo

Leave a Reply

Your email address will not be published. Required fields are marked *