DEV Community

Asif
Asif

Posted on

Macros to the Rescue! Add Pagination to Non-DB Collections in Laravel

Laravel's powerful Collection class provides many helpful methods for working with arrays of data. However, the built-in paginate method only works on Eloquent query builder and database results.

If you want to paginate a standard Laravel Collection instance, such as from an array or other custom data source, you're out of luck. Or are you?

By defining a custom macro, we can add pagination capabilities to any Collection instance in Laravel. Here's how it works...

Defining the Pagination Macro

Laravel allows you to define custom macros on existing classes to augment them with new functionality. We can utilize this to create a reusable paginate macro on the Collection class.

Inside the boot method of a service provider, like AppServiceProvider, we'll define the macro:

use Illuminate\Support\Collection;
use Illuminate\Pagination\LengthAwarePaginator;

Collection::macro('paginate', function ($perPage = 15, $pageName = 'page', $page = null, $options = []) {

  // Resolve current page from request  
  $page = $page ?: LengthAwarePaginator::resolveCurrentPage($pageName);

  // Paginate the Collection  
  return new LengthAwarePaginator(
      $this->forPage($page, $perPage),
      $this->count(), 
      $perPage,
      $page,
      $options
  );

});
Enter fullscreen mode Exit fullscreen mode

The macro creates a new LengthAwarePaginator instance which will handle the pagination render logic and links. We just need to pass the specific page's chunk of data from the collection using forPage, as well as the total collection count.

Paginating a Collection

With the macro defined, we can now paginate non-DB collections:

$collection = collect(range(1, 100)); // a Collection instance

$paginated = $collection->paginate(10); // 10 items per page

var_dump($paginated->items()); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] on page 1
Enter fullscreen mode Exit fullscreen mode

The macro handles all the complexity of slicing the collection into pages and generating the paginator instance.

Custom Pagination Super Powers!

Defining custom macros provides tremendous flexibility to expand Laravel's base classes. In this case, we've given all collections the ability to be paginated with a simple, expressive syntax.

While less efficient for giant data sets, this approach is great for smaller arrays or collections not coming directly from a database query.

So don't limit yourself to just paginating Eloquent results. With a bit of macro magic, you can bring pagination powers to any Laravel collection!

Top comments (0)

The discussion has been locked. New comments can't be added.