WordPress 5.7 Bootstrap 5.0 pagination (with custom WP_Query() and global $wp_query support)

Posted on
5/5 - (416 votes)
/**
* @param WP_Query|null $wp_query
* @param bool $echo
* @param array $params
*
* @return string|null
* 
* Using Bootstrap 4? see https://gist.github.com/mtx-z/f95af6cc6fb562eb1a1540ca715ed928
* 
* Accepts a WP_Query instance to build pagination (for custom wp_query()),
* or nothing to use the current global $wp_query (eg: taxonomy term page)
* - Tested on WP 5.7.1
* - Tested with Bootstrap 5.0 (https://getbootstrap.com/docs/5.0/components/pagination/)
* - Tested on Sage 9.0.9
*
* INSTALLATION:
* add this file content to your theme function.php or equivalent
*
* USAGE:
* <?php echo bootstrap_pagination(); ?> //uses global $wp_query
* or with custom WP_Query():
* <?php
* $query = new \WP_Query($args);
* ... while(have_posts()), $query->posts stuff ... endwhile() ...
* echo bootstrap_pagination($query);
* ?>
*/
function bootstrap_pagination( \WP_Query $wp_query = null, $echo = true, $params = [] ) {
if ( null === $wp_query ) {
global $wp_query;
}

$add_args = [];

//add query (GET) parameters to generated page URLs
/*if (isset($_GET[ 'sort' ])) {
$add_args[ 'sort' ] = (string)$_GET[ 'sort' ];
}*/

$pages = paginate_links( array_merge( [
'base' => str_replace( 999999999, '%#%', esc_url( get_pagenum_link( 999999999 ) ) ),
'format' => '?paged=%#%',
'current' => max( 1, get_query_var( 'paged' ) ),
'total' => $wp_query->max_num_pages,
'type' => 'array',
'show_all' => false,
'end_size' => 3,
'mid_size' => 1,
'prev_next' => true,
'prev_text' => __( '« Prev' ),
'next_text' => __( 'Next »' ),
'add_args' => $add_args,
'add_fragment' => ''
], $params )
);

if ( is_array( $pages ) ) {
//$current_page = ( get_query_var( 'paged' ) == 0 ) ? 1 : get_query_var( 'paged' );
$pagination = '<nav aria-label="Page navigation"><ul class="pagination">';

foreach ( $pages as $page ) {
$pagination .= '<li class="page-item' . (strpos($page, 'current') !== false ? ' active' : '') . '"> ' . str_replace('page-numbers', 'page-link', $page) . '</li>';
}

$pagination .= '</ul></nav>';

if ( $echo ) {
echo $pagination;
} else {
return $pagination;
}
}

return null;
}

/**
* Notes:
* AJAX:
* - When used with wp_ajax (generate pagination HTML from ajax) you'll need to provide base URL (or it'll be admin-ajax URL)
* - Example for a term page: bootstrap_pagination( $query, false, ['base' => get_term_link($term) . '?paged=%#%'] )
*
* Images as next/prev:
* - You can use image as next/prev buttons
* - Example: 'prev_text' => '<img src="' . get_stylesheet_directory_uri() . '/assets/images/prev-arrow.svg">',
*
* Add query parameters to page URLs
* - If you need custom URL parameters on your page URLS, use the "add_args" attribute
* - Example (before paginate_links() call):
* $arg = [];
* if (isset($_GET[ 'sort' ])) {
* $args[ 'sort' ] = (string)$_GET[ 'sort' ];
* }
* ...
* 'add_args' => $args,
*/