Paginatorを使う【cakephp3.8】

今回はPaginatorコンポーネントとPaginatorヘルパーを使った、データベースのページネーション 表示について整理したのでまとめておく。

ページネーション整理ノート。

bakeコマンドで初めから用意されている

もともとbakeコマンドでVMCを生成したらpaginateが入っている。

// Controller
$people = $this->paginate($this->People);

// Model
// 特になし

// Template
<thead>
    <tr>
        <th scope="col"><?= $this->Paginator->sort('id') ?></th>
        <th scope="col"><?= $this->Paginator->sort('name') ?></th>
        <th scope="col" class="actions"><?= __('Actions') ?></th>
    </tr>
</thead> // あたり

<ul class="pagination">
    <?= $this->Paginator->first('<< ' . __('first')) ?>
    <?= $this->Paginator->prev('< ' . __('previous')) ?>
    <?= $this->Paginator->numbers() ?>
    <?= $this->Paginator->next(__('next') . ' >') ?>
    <?= $this->Paginator->last(__('last') . ' >>') ?>
</ul> // あたり

最低限ある感じなのでここにいろいろ付け足していく。

$paginateに用意される設定

page初期状態で表示されるページ番号。
デフォルトで1
filelds取得する項目名の配列
sortWhiteListソート可能となる項目の配列
order並べ替えの指定。
'acs’または’desc’
limit表示する項目数
maxLimit最大表示項目数
contain同時に取得するテーブルの設定
$oagenateの設定項目

ページネーションによる検索

流れ

$paginateに設定情報をいれる。

TableRegistryで関連するテーブルクラスを登録する。

paginatorコンポーネントをロード。

[コントローラー]->paginate( テーブルインスタンス, 検索設定 );

ビューテンプレートでのPaginatorヘルパー

ページ移動のリンクを作成する

最初のページに移動

$this->Paginator->first( 表示テキスト, 属性設定 );

前のページに移動

$this->Paginator->prev( 表示テキスト, 属性設定 );

次のページに移動

$this->Paginator->next( 表示テキスト, 属性設定 );

最後のページに移動

$this->Paginator->last( 表示テキスト, 属性設定 );

<div class="paginator">
        <ul class="pagination">
            <?= $this->Paginator->first('<< ' . __('first')) ?>
            <?= $this->Paginator->prev('< ' . __('previous')) ?>
            <?= $this->Paginator->numbers() ?>
            <?= $this->Paginator->next(__('next') . ' >') ?>
            <?= $this->Paginator->last(__('last') . ' >>') ?>
        </ul>
        <p><?= $this->Paginator->counter(['format' => __('Page {{page}} of {{pages}}, showing {{current}} record(s) out of {{count}} total')]) ?></p>
    </div>

このうちのPaginator->numbers()はページ番号でリンクを列表示させる。

// numbers()で表示する例
<?= $this->Paginator->numbers([
  'before' => $this->Paginator->first('<<'). '・',
  'after' => '・'. $this->Paginator->last('>>'),
  'modules' => 4,
  'separator' => '・'
]); ?>

これだと、前または後ろにページがなくなったときにセパレートの’・’が残ってしまう。

Paginator->hasPrev(), Paginator->hasNext()を使って条件分岐できる。

// 前・後ろになかったら表示しない
<?= $this->Paginator->numbers([
      'before' => $this->Paginator->hasPrev() ? $this->Paginator->first('<<'). '・' : '',
      'after' => $this->Paginator->hasNext() ? '・'. $this->Paginator->last('>>') : '',
      'modules' => 4,
      'separator' => '・'
    ]); ?>

ソート機能の実装

<thead>
    <tr>
        <th scope="col"><?= $this->Paginator->sort('title', 'タイトル') ?></th>
        <th scope="col"><?= $this->Paginator->sort('person_id', '監督名') ?></th>
        <th scope="col"><?= $this->Paginator->sort('registed', '追加日') ?></th>
        <th scope="col" class="actions"><?= __('Actions') ?></th>
    </tr>
</thead>

sort('カラム’, '表示テキスト’)