Pagination instead of pager

Oh, hey!

I couldn’t find anyone else asking about this, so: I’d like to use pagination instead of the “pager” div, but I can’t seem to find the function in Roots. I’m not sure if it exists!

Does it?

If not, is there a simple way to add a Bootstrap-looking function?


This isn’t built in to Roots but there are a lot of examples online that you could use.

Hi octonaut,

The non-Bootstrap way is rather simple (source)

// in functions.php or a custom plugin
function pagination_simple( $args = array() ) {

	global $wp_query;
	$total_pages = $wp_query->max_num_pages;
	if ($total_pages > 1){
	  $current_page = max(1, get_query_var('paged'));
	  echo '<div class="page_nav">';
	  echo paginate_links(array(
	      'base' => get_pagenum_link(1) . '%_%',
	      'format' => '/page/%#%',
	      'current' => $current_page,
	      'total' => $total_pages,
	      'prev_text' => 'Prev',
	      'next_text' => 'Next'
	  echo '</div>';

// in template file
<?php pagination_simple() ;?>

This probably doesn’t cut it as it didn’t for me so I frankenstein’ed a function by taking parts from some plugins and making them work for my use case. While I have used it in a couple of projects, I am constantly finding ‘bugs’ and refining it, so you may want to test it out before you commit to it. I’ve created the following gist of the template function to be used as above

Please send me a link to any improvements you make :smile:


Just to add some notes:

  • The “Previous Page” and “Next Page” link texts are visible to screen readers only (.sr-only bootstrap class)
  • You probably want to replace all instances of ‘enollo’ with your theme name/domain
  • A lot of the arguments in the $args array are still to be implemented. - I have refined and completed these now.


1 Like

@enollo, your function looks interesting (but long). I always use this function for full pagination within roots…

Does this go into custom.php? I’m assuming that there need to be some markup added into the archive.php to reference this. Do you have a usage guide at all?


I used this function, only thing I had to do was to remove the extra DIV that was wrapped around the UL and assign the classes accordingly to match current Bootstrap ver and it worked out perfectly.

Then in Roots index.php you replace the pagination area with the function

    <?php if ($wp_query->max_num_pages > 1) : ?>
    // custom function to output Bootstrap pagination added in custom.php
<?php endif; ?>

@corey, there are some simpler ways to do it as seen in @corradomatt’s and @buretta’s solutions.
Mine probably meeds to be evaluated again and shortened down. I needed a quick solution that will let me pass a custom query if needed as well as a few options.

You can place any of these functions in custom.php or wherever it makes sense in your project.
To use with the standard query, just call the function after your post list in index.php instead of the standard roots post-nav

<?php if ($wp_query->max_num_pages > 1) : ?>
  <nav class="post-nav">
    <ul class="pager">
      <li class="previous"><?php next_posts_link(__('&larr; Older posts', 'roots')); ?></li>
      <li class="next"><?php previous_posts_link(__('Newer posts &rarr;', 'roots')); ?></li>
<?php endif; ?>

<?php page_navi(); ?>
<?php your_pagination(); ?>
<?php enollo_pagination(); ?>

Below is the output of the function I suggested to try if you were curious. I would post a working preview but only have it on a local DEV site right now, sry

   <ul class="pagination">
   <li class="disabled"><a href="#">«</a> </li>
   <li class="active"><a href="#">1</a></li>
   <li><a href="/news/page/2/">2</a></li>
   <li class=""><a href="/news/page/2/">»</a></li>

Here is the entire function, place in lib/custom.php

// Use this function to create pagingation links that are styleable with Twitter Bootstrap

// Numeric Page Navi
function page_navi($before = '', $after = '') {
  global $wpdb, $wp_query;
  $request = $wp_query->request;
  $posts_per_page = intval(get_query_var('posts_per_page'));
  $paged = intval(get_query_var('paged'));
  $numposts = $wp_query->found_posts;
  $max_page = $wp_query->max_num_pages;
  if ( $numposts <= $posts_per_page ) { return; }
  if(empty($paged) || $paged == 0) {
    $paged = 1;
  $pages_to_show = 7;
  $pages_to_show_minus_1 = $pages_to_show-1;
  $half_page_start = floor($pages_to_show_minus_1/2);
  $half_page_end = ceil($pages_to_show_minus_1/2);
  $start_page = $paged - $half_page_start;
  if($start_page <= 0) {
    $start_page = 1;
  $end_page = $paged + $half_page_end;
  if(($end_page - $start_page) != $pages_to_show_minus_1) {
    $end_page = $start_page + $pages_to_show_minus_1;
  if($end_page > $max_page) {
    $start_page = $max_page - $pages_to_show_minus_1;
    $end_page = $max_page;
  if($start_page <= 0) {
    $start_page = 1;

  echo $before.'<ul class="pagination">'."";
  if ($paged > 1) {
    $first_page_text = "<span class='glyphicon glyphicon-home'></span>";
    echo '<li class="prev"><a href="'.get_pagenum_link().'" title="First">'.$first_page_text.'</a></li>';

  $prevposts = get_previous_posts_link('&laquo;');
  if($prevposts) { echo '<li>' . $prevposts  . '</li>'; }
  else { echo '<li class="disabled"><a href="#">&laquo;</a></li>'; }

  for($i = $start_page; $i  <= $end_page; $i++) {
    if($i == $paged) {
      echo '<li class="active"><a href="#">'.$i.'</a></li>';
    } else {
      echo '<li><a href="'.get_pagenum_link($i).'">'.$i.'</a></li>';
  echo '<li class="">';
  echo '</li>';
  if ($end_page < $max_page) {
    $last_page_text = "»";
    echo '<li class="next"><a href="'.get_pagenum_link($max_page).'" title="Last">'.$last_page_text.'</a></li>';
  echo '</ul>'.$after."";

Then replace any instance in your theme templates that reference pagination with the following

<?php if ($wp_query->max_num_pages > 1) : ?>
    // custom function to output Bootstrap pagination added in custom.php
<?php endif; ?>

This worked very nicely


i tried to add your function inside my “content-page.php” but it did not worked.
The idea is to display a list of posts only on the “news” page .
Here’s my code :

<?php while (have_posts()) : the_post(); ?>
	<?php get_template_part( 'templates/feature-image' ); ?>		
  	<?php the_content(); 
  	if (is_page('actus')) :
			$args = array( 'posts_per_page' => 1, 'order'=> 'ASC', 'orderby' => 'title' );
			$postslist = get_posts( $args );
			foreach ( $postslist as $post ) :
			  setup_postdata( $post ); ?> 
					<?php if ( has_post_thumbnail() ) {
					} ?>
					<br />
					<?php the_title(); ?>   
					<?php the_excerpt(); ?>
  	endif; ?>

  	<?php wp_link_pages(array('before' => '<nav class="pagination">', 'after' => '</nav>')); ?>
<?php endwhile; ?>

Any ideas please ?

Try it on index.php or an archive template first to ensure you can get it working there and then migrate that over to whatever custom templates you may be wanting to apply pagination on.

Below is my index.php with the custom pagination added.

<?php get_template_part('templates/page', 'header'); ?>

<?php if (!have_posts()) : ?>
  <div class="alert alert-warning">
    <?php _e('Sorry, no results were found.', 'roots'); ?>
  <?php get_search_form(); ?>
<?php endif; ?>

<?php while (have_posts()) : the_post(); ?>
  <?php get_template_part('templates/content', get_post_format()); ?>
<?php endwhile; ?>

<?php if ($wp_query->max_num_pages > 1) : ?>
    // custom function to output Bootstrap pagination, found in custom.php
<?php endif; ?>

thx for your answer !
it’s not working with your index.php…
i don’t understand where the number of articles limit to display pagination is set in your page_navi function ?
does this function work for articles pagination ?

The number of articles is set in WP dash > settings > reading > blog pages to show
This is another setup I have, basic roots skeleton with the pagination function relaced in the index. I have set to only show 3 posts per page giving you an idea of the above setting and showing it working in context to the function.

Have you placed the function in your custom.php and then replaced the roots default pagination with the new function? The below goes into the index. At the bottom you will see the default call for pagination, just replace it with the new function below.

<?php if ($wp_query->max_num_pages > 1) : ?>
    // custom function to output Bootstrap pagination, found in custom.php
<?php endif; ?>

I’ve moved this in to a plugin, haven’t documented this nor added any real features yet but feel free to suggest any on GIT

I also needed this recently and basically followed @corradomatt’s gist (which actually comes from this WP Codex entry) .

However, I did not use the regular expressions in his post because LESS makes it easy enough to simply add Bootstrap class styles to any element by class or id, so I did:

.page-numbers {

It’s much cleaner (and faster) than the regex.


Even better, use LESS’s extend feature and don’t forget to extend the active page number: {
	&:extend(.pagination all, .pagination-sm all);
	> li .current {
		&:extend(.pagination > .active > span all);
1 Like

nice, I think if i ever have time I may explore adding these features

I’m trying to use this on Roots Sage 8.1.1. We now have extras.php instead of custom.php. I’ve pasted the function there and included the pagination hook in my index.php file but it does not seem to work.

Any ideas on how I can get it to work?

EDIT: I figured it out. Extras.php is namespaced so I used this in my index.php file instead. Note the Roots\Sage\Extras before the function name:

<?php if ($wp_query->max_num_pages > 1) : ?>
  <?php Roots\Sage\Extras\page_navi(); ?>
<?php endif; ?>


1 Like

Trying to ge this to work but not been able to. I inserted the function page_navi in the lib/extras.php and then used the path/namespace bit it’s not rendering anything in the front end.
I am using a custom query, from a custom made plugin, so that might be the reason why. Still can’t get around it to make it work.

I went with an approach that still leverages WordPress! core to do the heavy lifting and just applies the necessary Bootstrap markup.
Just add this function to functions.php and call <?php echo paginate_links_as_bootstrap(); ?> in your theme.

1 Like

For Bootstrap 4.3 you are missing ‘page-link’ class on $link, if someone needs to add it:

str_replace('page-numbers', 'page-numbers page-link', $link)