CakePHP 4 で Bootstrap 4 準拠のページリンクをつくる

はじめに

CakePHP 4 にはページリンクを作成する Paginator 機能があり、
PaginatorHelper Templates を使えば HTML タグを自由にカスタムすることができます。

ところで CSS のフレームワークとして非常に有名なもののひとつに Bootstrap があります。僕自身、システム開発を行う際に Bootstrap ベースでコーディングをすることが多くあり、相性もいいなと感じています。

そこで今日は CakePHP 4 の PaginatorHelper Templates を使って Bootstrap 4 準拠のページリンクをつくる方法 をご紹介します。

CakePHP
4.0.7
Bootstrap
4.5.0
目次
  1. 下準備
  2. 実装方法
  3. おわりに

1. 下準備

動作確認で使用した各種コードです。

今回はページ番号を増やすために、articles テーブルに記事 20 件 を登録し、
1 ページあたりの表示件数を 1 件に設定して、合計 20 ページにしました。

データベース

CREATE TABLE articles (
  id int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
  body text NOT NULL
);

INSERT INTO articles (body) VALUES
  ('Sample1'), ('Sample2'), ('Sample3'), ('Sample4'), ('Sample5'),
  ('Sample6'), ('Sample7'), ('Sample8'), ('Sample9'), ('Sample10'),
  ('Sample11'), ('Sample12'), ('Sample13'), ('Sample14'), ('Sample15'),
  ('Sample16'), ('Sample17'), ('Sample18'), ('Sample19'), ('Sample20');

レイアウト

Bootstrap や jquery などの CDN へのリンクは変更になっている可能性がありますので、公式サイトで紹介しているタグをコピペすることをおススメします。
/templates/layout/default.php
<!doctype html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <title>Sample</title>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
  <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
</head>
<body>
  <?= $this->fetch('content') ?>
</body>
</html>

テスト用アクション

/src/Controllers/ArticlesController.php
<?php
declare(strict_types=1);

namespace App\Controller;

class ArticlesController extends AppController
{
    public function initialize(): void
    {
        parent::initialize();
        $this->loadComponent('Paginator');
    }

    public function index()
    {
        $this->paginate['limit'] = 1;

        $this->set('articles', $this->paginate($this->Articles));
    }
}
/templates/Articles/index.php
<h1>Articles</h1>

<nav aria-label="Page navigation example">
  <ul class="pagination">
    <?= $this->Paginator->prev('Prev') ?>
    <?= $this->Paginator->numbers([
      'first' => 2,
      'modulus' => 2,
      'last' => 2
    ]) ?>
    <?= $this->Paginator->next('Next') ?>
  </ul>
</nav>

<?php debug($articles) ?>

2. 実装方法

ページリンクのテンプレートは、設定ファイルとして記述して View で指定します。

テンプレートのファイル名は、公式ドキュメントに倣って
config/paginator-templates.php にしています。

/config/paginator-templates.php
<?php
return [
    // ページ番号
    'number' => '<li class="page-item"><a class="page-link" href="{{url}}">{{text}}</a></li>',
    // 現在開いているページ番号
    'current' => '<li class="page-item active"><span class="page-link">{{text}} <span class="sr-only">(current)</span></span></li>',
    // 「...」の部分
    'ellipsis' => '<li class="page-item disabled"><span class="page-link">...</span></li>',
    // Prev
    'prevActive' => '<li class="page-item"><a class="page-link" href="{{url}}">{{text}}</a></li>',
    'prevDisabled' => '<li class="page-item disabled"><span class="page-link">{{text}}</span></li>',
    // Next
    'nextActive' => '<li class="page-item"><a class="page-link" href="{{url}}">{{text}}</a></li>',
    'nextDisabled' => '<li class="page-item disabled"><span class="page-link">{{text}}</span></li>',
];
/src/View/AppView.php
<?php
declare(strict_types=1);

namespace App\View;

use Cake\View\View;

class AppView extends View
{
    public function initialize(): void
    {
        $this->loadHelper('Paginator', ['templates' => 'paginator-templates']); // ← これを追加
    }
}

3. おわりに

ページリンクはよく使うものなので、自分が良く使う CSS フレームワークなどに合わせて設定ファイルを作ると便利だと思います。

一度作れば使いまわせるので、パターンごとにファイルを用意しておくのも良いかもしれませんね。

また、僕は試していませんが、プラグインに含めることもできるようなので、状況に応じて使えるようにしておくと、開発効率が上がると思います。