Laravel6でページネーションのカスタマイズ

## 概要
Laravelのページネーションに触れてみたので備忘録です。
基本的に公式ページに全て書いてある。
[Database: Pagination - Laravel - The PHP Framework For Web Artisans](https://laravel.com/docs/6.x/pagination)

## 環境
PHP: 7.2.22
Laravel: 6.11.0

## 事前準備
テスト用の各種設定は以下の通りです。ユーザやルーティングを適当に設定しています。

```php:UsersController.php
class UsersController extends Controller
{
    public function index() {
        $users = DB::table('users')->paginate(10);
        return view('user.index', compact('users'));
    }
}
```

```php:index.blade.php
<html>
  <head>
      <title>Paging Sample</title>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
  </head>
  <body>
    <div class="container">
      <h1>Paging Sample</h1>
      <ul class="list-group">
        @foreach ($users as $user)
          <li class="list-group-item">
            {{ $user->name }}
          </li>
        @endforeach
      </ul>
      {{ $users->links() }}
    </div>
  </body>
</html>
```
<img width="1147" alt="スクリーンショット 2020-01-18 21.21.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183878/32a50bdd-1acb-f5e7-3b8a-56c4ae65f67e.png">

## ページネーション設定
以下コマンドを実行するとresources/views/vendor以下にpaginationのビューファイルが作成されます。現在のバージョンではデフォルトはこの中にあるbootstrap-4.blade.phpが使用されているようです。

```bash
$ php artisan vendor:publish --tag=laravel-pagination
Copied Directory [/vendor/laravel/framework/src/Illuminate/Pagination/resources/views] To [/resources/views/vendor/pagination]
Publishing complete.
Publishing complete.
```

```bash
$ ls resources/views/vendor/pagination/
bootstrap-4.blade.php
default.blade.php
semantic-ui.blade.php
simple-bootstrap-4.blade.php
simple-default.blade.php
```

以下のようにしても同じです。

```bash
$ php artisan vendor:publish

 Which provider or tag's files would you like to publish?:
  [0 ] Publish files from all providers and tags listed below
  [1 ] Provider: Facade\Ignition\IgnitionServiceProvider
  [2 ] Provider: Fideloper\Proxy\TrustedProxyServiceProvider
  [3 ] Provider: Illuminate\Foundation\Providers\FoundationServiceProvider
  [4 ] Provider: Illuminate\Mail\MailServiceProvider
  [5 ] Provider: Illuminate\Notifications\NotificationServiceProvider
  [6 ] Provider: Illuminate\Pagination\PaginationServiceProvider
  [7 ] Provider: Laravel\Tinker\TinkerServiceProvider
  [8 ] Tag: flare-config
  [9 ] Tag: ignition-config
  [10] Tag: laravel-errors
  [11] Tag: laravel-mail
  [12] Tag: laravel-notifications
  [13] Tag: laravel-pagination
 > 13

Copied Directory [/vendor/laravel/framework/src/Illuminate/Pagination/resources/views] To [/resources/views/vendor/pagination]
Publishing complete.
Publishing complete.
```

bladeテンプレート内で呼び出しているlinks()でページネーションにのテンプレートを指定できます。

```php:index.blade.php
{{ $users->links('vendor.pagination.default') }}
```
<img width="54" alt="スクリーンショット 2020-01-18 22.12.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183878/e9f6ba98-3aa9-c3ae-2350-d9ead5c2e620.png">


```php:index.blade.php
{{ $users->links('vendor.pagination.semantic-ui') }}
```

<img width="43" alt="スクリーンショット 2020-01-18 22.12.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183878/5a979aee-ea1a-67f6-8dcb-2a6bfb2a02a9.png">

前か次かだけのシンプルなページングを指定することも可能です。

```php:index.blade.php
{{ $users->links('vendor.pagination.simple-default') }}
```

<img width="132" alt="スクリーンショット 2020-01-18 23.43.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183878/b61a947f-30b6-9bfc-11bd-029cd34e7889.png">


デフォルトでbootstrap-4.blade.phpが呼び出されている訳なので、これを編集することでページネーションの表示をカスタマイズすることもできます。

また、自身で作成したテンプレートも使用できますので、今回はbootstrap-4をちょっとだけ修正してsample-paginationというテンプレートを作成し使用してみる。

```php:index.blade.php
{{ $users->links('vendor.pagination.sample-pagination') }}
```

```php:sample-pagination.php
@if ($paginator->hasPages())
    <nav>
        <ul class="pagination justify-content-center pagination-lg">
            {{-- Previous Page Link --}}@cannot('update', Model::class)
                
            @endcannot
            @if ($paginator->onFirstPage())
                <li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.previous')">
                    <span class="page-link" aria-hidden="true">&laquo;</span>
                </li>
            @else
                <li class="page-item">
                    <a class="page-link text-success" href="{{ $paginator->previousPageUrl() }}" rel="prev" aria-label="@lang('pagination.previous')">&laquo;</a>
                </li>
            @endif

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

                {{-- Array Of Links --}}
                @if (is_array($element))
                    @foreach ($element as $page => $url)
                        @if ($page == $paginator->currentPage())
                            <li class="page-item active" aria-current="page"><span class="page-link bg-success border-success">{{ $page }}</span></li>
                        @else
                            <li class="page-item"><a class="page-link text-success" href="{{ $url }}">{{ $page }}</a></li>
                        @endif
                    @endforeach
                @endif
            @endforeach

            {{-- Next Page Link --}}
            @if ($paginator->hasMorePages())
                <li class="page-item">
                    <a class="page-link text-success" href="{{ $paginator->nextPageUrl() }}" rel="next" aria-label="@lang('pagination.next')">&raquo;</a>
                </li>
            @else
                <li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.next')">
                    <span class="page-link" aria-hidden="true">&raquo;</span>
                </li>
            @endif
        </ul>
    </nav>
@endif
```

<img width="961" alt="スクリーンショット 2020-01-18 23.05.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183878/062ed6ff-7351-e4e8-0bad-747169433d69.png">

## まとめ
Laravelのページネーションは意外と簡単に実装できる。
スタイルの変更も分かりやすく、自由に修正できる。

## 参考サイト
* [Laravel 6.x データベース・ページネーション](https://readouble.com/laravel/6.x/ja/pagination.html)
* [Laravel 5.3でページネーションのビューを変更する](https://co.bsnws.net/article/164)