Customizing pagination templates in Laravel 5.3

Posted on July 26, 2016 | By Matt Stauffer


Warning: This post is over a year old. I don't always update old posts with new information, so some of this information may be out of date.

Laravel's pagination library is brilliant, because pagination is a common task that is a surprising amount of work to implement. In the past, if you wanted to customize your pagination templates, it was just as simple to customize your pagination template as it was to work with the rest of the pagination library.

However, for the sake of making the pagination library easier to extract for non-Laravel projects, Laravel 5.0 (or maybe even earlier?) introduced a much more complex—but more portable—system for pagination templates.

Thankfully, in Laravel 5.3, we're going to go back to how it always was: simple and easy.

How pagination works in Laravel

If you're not familiar, here's a quick rundown of how it works to use pagination in Laravel.

// routes file
Route::get('tasks', function () {
    return view('tasks.index')
        ->with('tasks', Task::paginate(10));
});
// resource/views/tasks/index.blade.php
@foreach ($tasks as $task)
    <!-- echo the task or whatever -->
@endforeach

{{ $tasks->links() }}

By default, the paginate() method on your Eloquent objects reads the query parameters of your request and detects which page you're on. So in this example, it'll read the ?page query parameter and grab 10 records for that page. It'll pass those 10 in, and when we foreach on the $tasks variable, we'll just be looping over those 10.

But if you retrieve those 10 records using paginate() instead of something like all(), you get a new method available on your $tasks object (or other Eloquent result) named links(), and this method returns the view string appropriate for showing a list of pagination buttons:

<ul class="pagination">
    <li class="disabled"><span>&laquo;</span></li>

    <li class="active"><span>1</span></li>
    <li><a href="http://53pagination.dev?page=2">2</a></li>
    <li><a href="http://53pagination.dev?page=3">3</a></li>

    <li><a href="http://53pagination.dev?page=2" rel="next">&raquo;</a></li>
</ul>

Customizing the pagination template in Laravel 5.3

OK, so let's finally get to the dirt. How do you customize this template in 5.3?

By default, the template that is rendering this can be found in the Illuminate\Pagination component: resources/views/bootstrap-3.blade.php. This is what it looks like right now:

<ul class="pagination">
    <!-- Previous Page Link -->
    @if ($paginator->onFirstPage())
        <li class="disabled"><span>&laquo;</span></li>
    @else
        <li><a href="{{ $paginator->previousPageUrl() }}" rel="prev">&laquo;</a></li>
    @endif

    <!-- Pagination Elements -->
    @foreach ($elements as $element)
        <!-- "Three Dots" Separator -->
        @if (is_string($element))
            <li class="disabled"><span>{{ $element }}</span></li>
        @endif

        <!-- Array Of Links -->
        @if (is_array($element))
            @foreach ($element as $page => $url)
                @if ($page == $paginator->currentPage())
                    <li class="active"><span>{{ $page }}</span></li>
                @else
                    <li><a href="{{ $url }}">{{ $page }}</a></li>
                @endif
            @endforeach
        @endif
    @endforeach

    <!-- Next Page Link -->
    @if ($paginator->hasMorePages())
        <li><a href="{{ $paginator->nextPageUrl() }}" rel="next">&raquo;</a></li>
    @else
        <li class="disabled"><span>&raquo;</span></li>
    @endif
</ul>

If you want to customize the pagination, you have two options: you can either publish the built-in view and edit it, or you can create a new file and manually link the Paginator to it.

Publishing the files

Probably the easiest option is to run php artisan vendor:publish. It'll publish the template to vendor/pagination and you can just edit it there. This is the preferred option unless you have some specific customization needs.

Manually linking the files

If you'd like to instead create your own pagination file and manually link to it, you can do that too. Create a new file that's a duplicate of that file, and modify it for your needs. Save it somewhere in resources/views; for now let's keep it simple and use resources/views/partials/pagination.blade.php.

Now, let's register it. Run \Illuminate\Pagination\LengthAwarePaginator::defaultView('partials.paginator') in the boot() method of a service provider.

Note: If you'd like to customize which template is used just by a single paginator, you can pass the view name to the links() method: {{ $users->links('partials.paginator') }}.

Overview

So, to get this entire thing to work, I took these steps:

  1. Clone the latest version of Laravel 5.3
  2. Composer install
  3. php artisan vendor:publish
  4. Edit resources/views/vendor/pagination/default.blade.php and customize it to my heart's desire

That's it!

Note: These instructions show you how to customize the length-aware paginator, which is the most common. But if you're working with the simple paginator, you can customize that too. Just use the file named simple-default as your base instead of default.


Comments? I'm @stauffermatt on Twitter


Tags: laravel  •  laravel 5.3