snippets / pagination.php

A reusable pagination partial with simple controls.

<?php

$next_text       = __( 'Next' , 'stardust' );
$prev_text       = __( 'Prev', 'stardust' );
$paged           = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
$next_posts_link = get_next_posts_link( $next_text ) ?? false;
$prev_posts_link = get_previous_posts_link ( $prev_text ) ?? false;

?>

<nav class="pagination" aria-label="Pagination">
	<div class="pagination__wrapper">
		<?php if ( $paged === 1 ) : ?>
			<span><?php echo get_next_posts_link( __( 'View more', 'stardust' ) ); ?></span>
		<?php else : ?>
			<?php if ( ! empty( $prev_posts_link ) ) : ?>
				<span class="pagination__label">
					<?php echo wp_kses_post( $prev_posts_link ); ?>
				</span>
			<?php else : ?>
				<span class="pagination__label pagination__label--disabled">
					<?php esc_html( $prev_text ); ?>
				</span>
			<?php endif; ?>
			<?php if ( ! empty( $paged ) ) : ?>
				<span class="pagination__label pagination__label--current" aria-current="page">
					<?php esc_html_e( "Page {$paged}", 'stardust' ); ?>
				</span>
			<?php endif; ?>
			<?php if ( ! empty( $next_posts_link ) ) : ?>
				<span class="pagination__label">
					<?php echo wp_kses_post( $next_posts_link ); ?>
				</span>
			<?php else : ?>
				<span class="pagination__label pagination__label--disabled">
					<?php esc_html( $next_text ); ?>
				</span>
			<?php endif; ?>
		<?php endif; ?>
	</div>
</nav>

Context

Table of Contents

  1. Con­text
  2. Usage
  3. Expla­na­tion

I recent­ly need­ed a sim­pli­fied pag­i­na­tion nav­i­ga­tion for a Word­Press site and end­ed up with this. Maybe I haven’t looked into it much, but the pag­i­na­tion solu­tions I’ve found in the past usu­al­ly involved a plugin.

This is a plug and play type of thing which is always nice to have.

Usage

First, I’d drop the code snip­pet into a file called pagination.php inside of my template-parts fold­er. Then on any tem­plate where I’m using the loop, I can just drop this in with the following:

<?php get_template_part( 'template-parts/pagination' ); ?>

Explanation

$next_text       = __( 'Next' , 'stardust' );
$prev_text       = __( 'Prev', 'stardust' );
$paged           = get_query_var('paged') ?? 1;
$next_posts_link = get_next_posts_link( $next_text ) ?? false;
$prev_posts_link = get_previous_posts_link ( $prev_text ) ?? false;

First we need to set­up our vari­ables for the par­tial. I defined the text for the pre­vi­ous and next pages. Next, I’m set­ting $paged to the val­ue of get_query_var('paged'). If that val­ue isn’t set, set the vari­able to 1. This informs our par­tial of what page we’re on. 

Final­ly, I’m set­ting $next_posts_link to the val­ue of get_next_posts_link( $next_text). This func­tion finds out whether that link exists and returns it, oth­er­wise we set the val­ue to false. We repeat this step with $prev_posts_link with the cor­re­spond­ing function.

<?php if ( $paged === 1 ) : ?>
  <span><?php echo get_next_posts_link( __( 'View more', 'stardust' ) ); ?></span>
<?php else : ?>

This piece checks if we’re on the first page, and out­puts a View More” link if we are.

<?php if ( ! empty( $prev_posts_link ) ) : ?>
  <span class="pagination__label">
	  <?php echo wp_kses_post( $prev_posts_link ); ?>
	</span>
<?php else : ?>
	<span class="pagination__label pagination__label--disabled">
 	  <?php esc_html( $prev_text ); ?>
	</span>
<?php endif; ?>

A Quick Note About empty()

Here I’m using the empty() func­tion from PHP to check whether the vari­able is set. Accord­ing to the docs:

Deter­mine whether a vari­able is con­sid­ered to be emp­ty. A vari­able is con­sid­ered emp­ty if it does not exist or if its val­ue equals false.

Since we set the vari­able to false if the val­ue of get_next_posts_link( $next_text ) does­n’t exist, we can be con­fi­dent this check will always work. If it does exist, we escape the out­put with the wp_kses_post() func­tion. If not, we still out­put the $prev_text just with­out the link.

<?php if ( ! empty( $paged ) ) : ?>
  <span class="pagination__label pagination__label--current" aria-current="page">
	  <?php esc_html_e( "Page {$paged}", 'stardust' ); ?>
  </span>
<?php endif; ?>

This next check is prob­a­bly a bit much because this whole part of the tem­plate should­n’t be show­ing if $paged is emp­ty. But here we’re still check­ing if that vari­able isn’t emp­ty, then we out­put the page number.

<?php if ( ! empty( $next_posts_link ) ) : ?>
  <span class="pagination__label">
    <?php echo wp_kses_post( $next_posts_link ); ?>
	</span>
<?php else : ?>
  <span class="pagination__label pagination__label--disabled">
    <?php esc_html( $next_text ); ?>
  </span>
<?php endif; ?>

Final­ly this is the same check we did with the pre­vi­ous posts links. If there’s a link, we out­put it. If not, we out­put a label with­out the link.