WordPress offered us as a developer function to create pagination easily by using the Paginate_links function. One just need to provide the function with configuration arguments array and voila... pager is built.

Is that true? Far from it. When building our Premium Bueza Theme I found out that the function only provides us with the correct markup for pager, and assumes that every page will use Paged as the variable for determining which page are you currently on.

How about if you have multiple pager on a single page? valid case for this is you have multiple widget that has the capability to do pagination, the default Paged query variables will change all the pager to x page at once when user only change a single pager instance.

This is why I have created a wrapper function for building a smarter pagination. Utilizing this function, you can do multiple pager in a single page and each pager will have their own pagination query variables to determine which pager instance should display what page and this function can be used with custom query or default query.

  /**
   * Build multiple post pager
   */
  static public function getPager($wp_query = FALSE, $mini = FALSE, $id = 1) {
    if (!$wp_query) {
      global $wp_query;
    }

    $get = filter_input_array(INPUT_GET);
    unset($get['paged_' . $id]);

    $prev = __('Previous', ACTIVE_THEME);
    $next = __('Next', ACTIVE_THEME);

    if ($mini) {
      $next = '<i class="color icon-angle-right"></i>';
      $prev = '<i class="color icon-angle-left"></i>';
    }

    $big = 999999999;
    $link = html_entity_decode(get_pagenum_link($big));
    $link = remove_query_arg('paged_' . $id, $link);

    $base_url = str_replace('paged=', 'paged_' . $id .'=', $link);

    $args = array(
      'base'         => str_replace($big, '%#%', $base_url),
      'format'       => '?paged_' . $id . '=%#%',
      'total'        => $wp_query->max_num_pages,
      'current'      => max(0, $wp_query->query_vars['paged']),
      'show_all'     => false,
      'prev_next'    => true,
      'prev_text'    => $prev,
      'next_text'    => $next,
      'type'         => 'list',
      'add_args'     => empty($get) ? false : $get,
      'add_fragment' => false,
    );

    $pager = paginate_links($args);

    if ($mini) {
      $dom = new DOMDocument();
      $dom->preserveWhiteSpace = false;
      $dom->formatOutput       = true;
      $dom->loadHTML($pager);
      $dom->removeChild($dom->firstChild);

      $remove = array();
      foreach ($dom->getElementsByTagName('li') as $key => $item) {
        foreach ($item->childNodes as $childkey => $child) {
          $class = $child->getAttribute('class');
          $class = array_flip(explode(' ', $class));
          if (isset($class['page-numbers'])) {
            if (isset($class['next']) || isset($class['prev'])) {
              continue;
            }

            $remove[] = $item;
            break;
          }
        }
      }

      // @note dont remove element in the main loop will cause strange output
      foreach ($remove as $item) {
        $item->parentNode->removeChild($item);
      }

      foreach ($dom->getElementsByTagName('ul') as $key => $item) {
        $class = $item->getAttribute('class');
        $item->setAttribute('class', $class . ' pager-mini');
      }

      $pager = str_replace(array('<html>', '</html>', '<body>', '</body>'), array('', '', '', ''), $dom->saveHTML());
    }

    return $pager;
  }

 

How to use the function?

The function is intended to be embedded inside a class as a static method, if you wish to use it as a normal PHP function, you can remove the static and public keywords.

Before calling this function, you must define the WP_Query object or use the default global main query.

Example for intergrating the Query to match the pagination :

<?php
/**
 * Example Query
 */
public function sampleQuery() {
    $argument = array(
      'post_type' => 'post',
      'posts_per_page' => 5,
      'post_status' => 'publish',
      'order' => 'DESC',
      'orderby' => 'modified',
      'paged' => isset($_GET['paged_unique_id') ? $_GET['paged_unique_id'] : 1,
    );

    $query = new WP_Query($argument);

     // Do something using the query

    // Notice the "unique_id" that value must be unique for this pager only
    echo getPager($query, false, 'unique_id');
}

 

Now trully enjoy easy way to build a TRUE pagination!.