How to create pager in drupal 8/9 for custom data set

Sometimes we need to create a pager for custom data sets, such as retrieving specific types of nodes and applying a filter on top of it to get the expected data set.

In this post, I am going to create a custom Drupal module named pager_example, which will create a pager for a custom data set.

Register a path where we will display a page with a pager using a custom data set. For that, I am going to create a routing file with the name "pager_example.routing.yml", which will have the following snippet:

pager_example.subscriptions:
    path: '/subscriptions' 
    defaults: 
      _controller: '\Drupal\pager_example\Controller\SubscriptionsController::getSubscriptions' 
    requirements:
      _permission: 'access content'

Let's create a controller for the route mentioned above.

namespace Drupal\pager_example\Controller;

use Drupal\Core\Controller\ControllerBase;

/**
 * Subscriptions controller.
 */
class SubscriptionsController extends ControllerBase {

  /**
   * Subscriptions page.
   */
  public function getSubscriptions(): array {

    // Custom data set of subscriptions.
    $subscriptions = [
      ['title' => 'Title one', 'start_date' => '08/Jun/2021', 'end_date' => '08/Jun/2022'],
      ['title' => 'Title two', 'start_date' => '10/Jun/2021', 'end_date' => '10/Jun/2022']
      ['title' => 'Title three', 'start_date' => '11/Jun/2021', 'end_date' => '11/Jun/2022']
      ['title' => 'Title four', 'start_date' => '12/Jun/2021', 'end_date' => '12/Jun/2022']
      ....
      ['title' => 'Title n', 'start_date' => '13/Jun/2021', 'end_date' => '13/Jun/2022']
    ];


    $build['page'] = [
      '#theme' => 'subscriptions',
      '#data' => $this->buildPager($subscriptions, 10),
      '#cache' => [
        'max-age' => 0,
      ],
    ];

    // Create pager
    $build['pager'] = [
      '#type' => 'pager',
    ];
    return $build;
  }

  /**
   * Build custom pager.
   */
  private function buildPager($result, $limit = 10) {
    $total = count($result);
    // Initialize pager and gets current page.
    /* @var $pager_manager \Drupal\Core\Pager\PagerManagerInterface */
    $pager_manager = \Drupal::service('pager.manager');
    $current_page = $pager_manager->createPager($total, $limit)->getCurrentPage();
    // Split the items up into chunks:
    $chunks = array_chunk($result, $limit);
    // Get the items for our current page:
    return $chunks[$current_page];
  }

}

We need a template to show the data in tabular format along with a pager. Let's create a pager_example.module and add the below snippet.

/**
 * Implements hook_theme().
 */
function pager_example_theme($existing, $type, $theme, $path) {
  return [
    'subscriptions' => [
      'variables' => [
        'data' => NULL
      ],
    ],
  ];
}

Now we need to add a twig template called subscriptions.html.twig

<div class="view">
  <div class="view-content">
    <div class="table-responsive">
      <table class="table"><thead>
        <tr>
          <th >Name</th>
          <th >Start date</th>
          <th >End date</th>
        </tr>
        </thead>
        <tbody>
        {% for subscription in data %}
          <tr>
            <td>{{subscription.title}}</td>
            <td>{{subscription.start_date}}</td>
            <td>{{subscription.end_date}}</td>
          </tr>
        {% endfor %}
        {% if content is empty %}
          <tr>
            <td colspan="3">No subscription found!</td>
          </tr>
        {% endif %}
        </tbody>
      </table>
    </div>
  </div>
</div>

We've got everything set up; navigate to /subscriptions in the browser to see a custom data set with a pager.

0/5