【Laravel6.x】ページネーションを短くする

PHP

こんばんは。

このブログのタイトルがかなり弱い気がするなと長年強く思っていたので変えてみました。(元々「かあブロッグ」だったけど、検索かけるとtypoと判断されて”かあブログ”での検索結果になるのが終わってたので変えました)

今回はLaravelのページネーションの話です。Laravelは下記の形でLaravelが用意したページネーションを呼び出すことができます。

# controller側
$posts = Post::orderBy('id','desc')->paginate(5);

# blade側
{{ $posts->links() }}

ただ、編集することができないので自分のサイトが横に短かったりするとページネーションの方が長くなりサイトの横幅に合わなかったりしてしまうので修正が必要となります。なので、テンプレートではないページネーションを作ってあげる必要があります。

paginationを作るためのコマンドを叩く

以下のコマンドで、Laravelが自動でpaginationに関するディレクトリを作成してくれます。

php artisan vendor:publish

コマンドを打つと選択肢が出ます。自分の環境では16番にpaginationの項目があったので16とタイプします。pagination以外にもいろいろ機能があって、指定すればそれを入れられると言った感じですね。

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

実行するとresources/views/vendor/paginationというディレクトリができて、中に5つくらいbladeファイルができます。

bootstrap-4.blade.php
default.blade.php
semantic-ui.blade.php
simple-bootstrap-4.blade.php
simple-default.blade.php

どれもページネーションのパーツの部分です。さっきの$posts->links()にこのbladeファイルを''で指定することで、5つのファイルのうち好きなページネーションのテンプレートを選択できます。

$posts->links('vendor.pagination.default')
$posts->links('vendor.pagination.bootstrap-4')
$posts->links('vendor.pagination.semantic-ui')
etc...

links()で出てくるのと同じテンプレートなのがbootstrap-4ですね。

今回は5つのテンプレートファイルは使わずに、新しく短いページネーションのファイルを作って呼び出すことにします。下記の記事で紹介されているリンクのものが短いものだったため、参考に使用することにします。

Laravelでリンク数を可変で決められるペジネーションの自作方法 - Qiita
Laravelのデフォルトのペジネーションが長さの調整はしにくいわ、treee dotsは邪魔だわ、デザインの変更はしづらいわで絶妙に使いづらかったので自作しました。完成系こんな感じ環境PH…

resources/views/vendor/paginationに新しいbladeファイルを作成します。今回はoriginal.blade.phpとします。

bladeファイルの内容は上記のリンクから参考にいただいて、以下のような形とします。

// resources/views/vendor/pagination/original.blade.php

@if ($paginator->hasPages())
    <ul class="pagination" role="navigation">
        {{-- First Page Link --}}
        <li class="page-item {{ $paginator->onFirstPage() ? ' disabled' : '' }}">
          <a class="page-link" href="{{ $paginator->url(1) }}">&laquo;</a>
        </li>

        {{-- Previous Page Link --}}
          <!-- 前のページへのリンク -->
          <li class="page-item {{ $paginator->onFirstPage() ? ' disabled' : '' }}">
            <a class="page-link" href="{{ $paginator->previousPageUrl() }}">&lsaquo;</a>
          </li>

        {{-- Pagination Elemnts --}}
            {{-- Array Of Links --}}
            {{-- 定数よりもページ数が多い時 --}}
            @if ($paginator->lastPage() > config('paginate.PAGINATE.LINK_NUM'))

                {{-- 現在ページが表示するリンクの中心位置よりも左の時 --}}
                @if ($paginator->currentPage() <= floor(config('paginate.PAGINATE.LINK_NUM') / 2))
                    <?php $start_page = 1; //最初のページ ?> 
                    <?php $end_page = config('paginate.PAGINATE.LINK_NUM'); ?>

                {{-- 現在ページが表示するリンクの中心位置よりも右の時 --}}
                @elseif ($paginator->currentPage() > $paginator->lastPage() - floor(config('paginate.PAGINATE.LINK_NUM') / 2))
                    <?php $start_page = $paginator->lastPage() - (config('paginate.PAGINATE.LINK_NUM') - 1); ?>
                    <?php $end_page = $paginator->lastPage(); ?>

                {{-- 現在ページが表示するリンクの中心位置の時 --}}
                @else
                    <?php $start_page = $paginator->currentPage() - (floor((config('paginate.PAGINATE.LINK_NUM') % 2 == 0 ? config('paginate.PAGINATE.LINK_NUM') - 1 : config('paginate.PAGINATE.LINK_NUM'))  / 2)); ?>
                    <?php $end_page = $paginator->currentPage() + floor(config('paginate.PAGINATE.LINK_NUM') / 2); ?>
                @endif

            {{-- 定数よりもページ数が少ない時 --}}
            @else
                <?php $start_page = 1; ?>
                <?php $end_page = $paginator->lastPage(); ?>
            @endif

            {{-- 処理部分 --}}
            @for ($i = $start_page; $i <= $end_page; $i++)
                @if ($i == $paginator->currentPage())
                    <li class="page-item active"><span class="page-link">{{ $i }}</span></li>
                @else
                    <li class="page-item"><a class="page-link" href="{{ $paginator->url($i) }}">{{ $i }}</a></li>
                @endif
            @endfor

          {{-- Next Page Link --}}
            <li class="page-item {{ $paginator->currentPage() == $paginator->lastPage() ? ' disabled' : '' }}">
              <a class="page-link" href="{{ $paginator->nextPageUrl() }}">&rsaquo;</a>
            </li>

          {{-- Last Page Link --}}
          <li class="page-item {{ $paginator->currentPage() == $paginator->lastPage() ? ' disabled' : '' }}">
            <a class="page-link" href="{{ $paginator->url($paginator->lastPage()) }}">&raquo;</a>
          </li>

    </ul>
@endif

上記を見てみるとconfig('paginate.PAGINATE.LINK_NUM')と記述がありますが、これはconfig/paginate.phpから、PAGINATEという値のLINK_NUMを持ってきているということです。記事を書いた方の実装だと、configから定数を持ってきていて、ページの表示数をconfigファイルから編集できるようになっているため、そちらに従うような形とします。

とはいえconfigpaginate.phpというファイルはないと思うので、自分で新規に作ってしまいましょう。paginate.phpを作成し、内容は以下の形で書きます。

<?php

return [
  'PAGINATE' => [
      'LINK_NUM' => '6',
  ],
];

このようにconfigファイルを作成し、ここでページ数を定義しておけば、ページ数をやっぱり6から10にしたいという時があっても、このページ部分のLINK_NUM10にすれば終わるので楽になります(キャッシュクリアを忘れずに)。

config関係,.envなどのファイルを記述した後はキャッシュをクリアして反映させます。

php artisan config:cache

最後にページネーションを貼りたいbladeファイルに、指定して上げれば完成です。

{{-- links('vendor.pagination.自分の作成したファイル名') --}}
{{ $posts->links('vendor.pagination.original') }}

以上です。

タイトルとURLをコピーしました