Quienes han trabajado con Eloquent en Laravel, seguramente conocen lo sencillo que es paginar una lista de resultados accediendo al método links() en la colección de resultados desde la vista. Por ejemplo si tenemos un modelo Users podríamos listar todos los usuarios de la siguiente manera:

Route::get('users', function () {
    $users = User::paginate(5);

    return view('some.view')->withUsers($users);

});

Y en la vista usamos:

{{ $users->links() }}

De esta forma se renderizan automáticamente los links de la paginación en la vista.

Crear un paginador personalizado

Es probable que requieras desarrollar aplicaciones que no usen directamente bases de datos y por lo tanto Eloquent, o tal vez aplicaciones que consuman datos desde una API, etc. En estos casos podemos hacer lo siguiente para crear una paginación simple:

use Illuminate\Pagination\Paginator;
use Illuminate\Support\Facades\Input;

Route::get('blog', function () {

    $page = Input::get('page');

    $posts = range(1, 20);

    $posts = new Paginator($posts, 10, $page);

    $posts->setPath('blog');

    return view('pagination')->withPosts($posts);
});

La clase Paginator recibe los siguientes parámetros:

new Paginator($items, $perPage, $currentPage = null, array $options = []);

En la vista nuevamente usamos:

{{ $posts->links() }}

Cada link tiene la siguiente estructura:

laravel.dev/blog?page=1

El problema con esta solución es que únicamente nos brinda dos enlaces de navegación.

Para solucionar ese problema podemos usar la clase LengthAwarePaginator de la siguiente manera:

use Illuminate\Pagination\Paginator;
use Illuminate\Support\Facades\Input;
use Illuminate\Pagination\LengthAwarePaginator;

Route::get('blog', function () {

    $page = Input::get('page');

    $posts = range(1, 50);

    $posts = new LengthAwarePaginator($posts, $total = 50, 10, $page);

    $posts->setPath('blog');

    return view('pagination')->withPosts($posts);
});

LengthAwarePaginator recibe los siguientes parámetros:

new LenghtAwarePaginator($items, $total, $perPage, $currentPage = null, array $options = []);

Esto nos muestra más enlaces en la vista.

Nota: La diferencia entre las clases PaginatorLenghtAwarePaginator es que Paginator crea una paginación simple que genera los enlaces únicamente para ir hacia atrás y hacia adelante mientras que la clase LengthAwarePaginator, como su nombre lo indica, toma en cuenta el tamaño de la colección y crea los enlaces correspondientes para cada una de las páginas disponibles.

Esto lo podemos optimizar un poco más para cambiar la forma como se pide la página actual y la forma en como se define el path de la ruta actual.

Route::get('blog', function () {

    $posts = range(1, 50);

    $pageName = 'page';

    $page = Paginator::resolveCurrentPage($pageName);

    $posts =  new LengthAwarePaginator($posts, $total = 50, $perPage = 10, $page, [
        'path' => Paginator::resolveCurrentPath(),
        'pageName' => $pageName,
    ]);

    return view('pagination')->withPosts($posts);

});

Como puedes ver, ahora estamos especificando la ruta utilizando el método resolveCurrentPath de la clase Paginator:

Paginator::resolveCurrentPath()

La variable $pageName nos permite cambiar el nombre del parámetro que contiene el número de página actual, asi que si por ejemplo lo cambiamos a algo como:

$pageName = 'p';

La estructura de los links cambia de la siguiente forma:

laravel.dev/blog?p=1

De esta manera puedes aplicar una paginación personalizada de ser requerido usando la misma lógica (al menos desde el lado de la vista) que usarías si estuvieras trabajando con Eloquent.

Material Relacionado

Suscríbete a nuestro boletín

Te enviaremos publicaciones con consejos útiles y múltiples recursos para que sigas aprendiendo.

Regístrate hoy en Styde y obtén acceso a todo nuestro contenido.