How to add pagination for pages or cpt using WP_Query()

WordPress is designed so that you can paginate any query for posts from the database using WP_Query(), because the necessary 'paged' and 'posts_per_page' arguments are already present in the query.

By pagination we mean page navigation. For example, if we specify the output of 10 posts per page and the WP_Query() response returns information about 32 posts, pagination will show us links to page 2, 3 and 4.

And lastly – if you are in any archive template, e.g. archive.php, category.php, index.php etc., then there is already a main loop and there is no need to re-request it, in this article we are also discussing pagination for arbitrary query on the example of page type pages.

Let’s look at the code as an example:

// Get the page number of the pagination.
$current = absint( max( 1, get_query_var( 'paged' ) ? get_query_var( 'paged' ) : get_query_var( 'page' ) ) );

// Argument for the request
$args = array(
	'post_type'      => 'page',
	'posts_per_page' => 10,
	'paged'          => $current,
);		

$query = new WP_Query( $args );

if ( $query->have_posts() ) {

	echo '<ul class="posts-list">';

	// Main query.
	while ( $query->have_posts() ) {
		$query->the_post();

		echo '<li class="posts-list__item">';
			echo '<a href="' . esc_url( get_the_permalink() ) . '">' . get_the_title() . '</a>';
		echo '</li>';
	}

	echo '</ul>';

	wp_reset_postdata(); // Return the global loop.

	// Output the pagination.
	echo wp_kses_post(
		paginate_links(
			array(
				'total'   => $query->max_num_pages, // The number is taken from the default query option.
				'current' => $current, // Current page.
			)
		)
	);
} else {
	// Output a "no content" pattern if there are no posts in the query.
	get_template_part( 'templates/content', 'none' );
}

First we collect variables for the query. Here we have two mandatory arguments: 'posts_per_page' (number of posts on the page) and 'paged' (pagination page X), the rest are specified depending on the query.

Then we make a WP_Query() query, collect the data in a variable and output it, reset the custom loop and output the pagination.

In case there is no data, output templates/content-none.php.

Problem with redirect in pagination

If the pagination is rendered correctly, but when you click on a link in the pagination you get a redirect to the first page you need to disable redirect in the entries.

In WordPress, redirect is always enabled by default, but in the case of custom pagination you need to disable it.

// Turn off redirect for pages, because at /page/2 redirects to /
add_filter( 'redirect_canonical', 'disable_page_redirect' );
function disable_page_redirect( $redirect_url ) {
	if( is_page() ) {
		$redirect_url = false;
		return $redirect_url;
	}
}

Problem with 404 in the pagination

If everything is displaying correctly, but you’re catching a 404 error when you click on a post, you need to reset the link cache. Go to Settings -> Permalinks and click “Save”

How useful is the publication?

Click on a star to rate it!

Average score 4 / 5. Number of grades: 2

No ratings yet. Rate it first.

Similar posts

Why Files with Identical Content (*.js, *.php, *.css) Can Have Different Sizes?

When developers compare files with identical content but notice that their sizes differ, it can be perplexing. Let’s explore why this happens and what factors influence the size of files with extensions like *.js, *.php, and *.css. 1. File Encoding One of the key factors affecting file size is text encoding. The most common encodings…
Read more

How to transfer a site from dle to WordPress?

Transferring a website from DLE (DataLife Engine) to WordPress can be a complex process, especially if the site has a lot of content. Here’s a step-by-step guide: 1. Preparation 2. Export Data from DLE DLE uses its own database structure, so you’ll need to export data and convert it into a format compatible with WordPress:…
Read more