Custom Pagination in CakePHP 4

Photo by Annie Spratt on Unsplash

One of the first things I did with new CakePHP 3.x projects was rip out all the existing CSS and put in my own. I’ll admit I’m less inclined to do that now that everything’s in red ‘n’ black (I bet they wanted to be LAMPStack Ninja too!) but it’s expected when we work for clients or employers that we’re gonna have to switch out the look and feel. In this post we’ll go over how to get the pagination to match your scheme.

As with many of the CakePHP articles you’ll find here, this one uses the mini-CMS produced from the Content Management Tutorial on the official CakePHP documentation site.

Out of the Box Pagination

CakePHP 4 uses the Milligram CSS framework. Even though freshly-baked CakePHP looks really nice with Milligram, you might want to change the look and feel of the default pagination:

The “Articles” Controller, “Index” Method

Adding some customization

The first step in customizing pagination is to create a new file called config/paginator-templates.php. The contents in our case will tell our paginator to use Milligram’s “button” class:

return [
    'number' => '<span class="button"><a href="{{url}}">{{text}}</a></span>',
    'first' => '<span class="button"><< </span>',
    'last' => '<span class="button"> >></span>',
    'nextActive' => '<span class="button"> ></span>',
    'nextDisabled' => '<span class="button"> ></span>',
    'prevActive' => '<span class="button">< </span>',
    'prevDisabled' => '<span class="button">< </span>'

Next, we need to tell CakePHP to load our new template, so in src/View/AppView.php, add the following line to the initialize() function:

$this->loadHelper('Paginator', ['templates' => 'paginator-templates']);

Now, if you refresh your Articles list page and you should see something like this:

We now have buttons for pagination!

We’ve changed things around a bit, which is what we set out to do. However, I don’t like how our new pagination buttons bump up against each other (and the table above them). Let’s fix that.

Custom CSS

In CakePHP4, the webroot/css/cake.css contains some overrides for Milligram. We could certainly make our own CSS file (and that’s not a bad idea for larger projects) but for what we’re doing here, I’m just going to add a little to the bottom. Let’s give our buttons some margin space:

.pagination-button {
    margin: 2px 1px 2px 1px;

To make this work, we’ll need to go back to config/paginator-templates.php and add in this new class. The full code now looks like this:

return [
    'number' => '<span class="button pagination-button"><a href="{{url}}">{{text}}</a></span>',
    'first' => '<span class="button pagination-button"><< </span>',
    'last' => '<span class="button pagination-button"> >></span>',
    'nextActive' => '<span class="button pagination-button"> ></span>',
    'nextDisabled' => '<span class="button pagination-button"> ></span>',
    'prevActive' => '<span class="button pagination-button">< </span>',
    'prevDisabled' => '<span class="button pagination-button">< </span>'

Back to our list of Articles, we have something that looks much better:

Improved Pagination Buttons

And there you go; we’ve made a simple start toward retooled pagination visuals that don’t interfere with any of our (or CakePHP’s) other pagination code.

Final words

This was all pretty simple… once I figured it out. Unless I missed it, no where in the CakePHP documentation does it spell this out in a contiguous manner; it’s something for which I both did a bit of searching and had some trial-and-error.

Hopefully this will be helpful to you (and I’ll certainly refer back to it myself!)

Do you know of an alternative way of doing what we just did? Please feel free to comment!

Leave a Reply

Your email address will not be published. Required fields are marked *