Skip to content

Commit b4efd6e

Browse files
authored
Merge pull request #8122 from cakephp/5.next-paginator
Document pagination improvements.
2 parents 346ea5b + 4aa6b20 commit b4efd6e

File tree

2 files changed

+118
-0
lines changed

2 files changed

+118
-0
lines changed

en/appendices/5-3-migration-guide.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,21 @@ ORM
155155
- ``Cake\ORM\Locator\TableContainer`` was added. By adding this container
156156
delegate to your application, ORM Tables can be injected by the DI container.
157157

158+
Pagination
159+
----------
160+
161+
- Added ``SortableFieldsBuilder`` class enabling fluent configuration of
162+
sortable fields with advanced features. The ``sortableFields`` option now
163+
accepts a callable that receives a ``SortableFieldsBuilder`` instance,
164+
allowing you to map friendly sort keys to database fields with multi-column
165+
sorting and direction control.
166+
- Added ``SortField`` class for defining sort field configurations with
167+
customizable default directions and locked directions (e.g.,
168+
``SortField::asc('price')`` or ``SortField::desc('created', locked: true)``).
169+
- Added support for combined sorting keys in URLs (e.g., ``?sort=title-asc`` or
170+
``?sort=price-desc``) in addition to the traditional ``?sort=field&direction=asc``
171+
format.
172+
158173
Routing
159174
-------
160175

en/controllers/pagination.rst

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,109 @@ pagination query::
224224
Any requests that attempt to sort on fields not in the allowed list will be
225225
ignored.
226226

227+
Advanced Sorting with SortableFieldsBuilder
228+
============================================
229+
230+
The ``SortableFieldsBuilder`` provides a powerful way to create user-friendly
231+
sort URLs while maintaining control over database ordering. Instead of exposing
232+
raw field names in URLs, you can map friendly keys to complex sorting logic with
233+
multi-column support and direction control.
234+
235+
Using the Builder
236+
-----------------
237+
238+
You can configure sortable fields using a callable that receives a
239+
``SortableFieldsBuilder`` instance::
240+
241+
use Cake\Datasource\Paging\SortField;
242+
use Cake\Datasource\Paging\SortableFieldsBuilder;
243+
244+
protected array $paginate = [
245+
'sortableFields' => function (SortableFieldsBuilder $builder) {
246+
return $builder
247+
->add('id', 'Articles.id')
248+
->add('title', 'Articles.title')
249+
->add('username', 'Users.username');
250+
},
251+
];
252+
253+
This configuration allows users to sort using friendly keys like ``?sort=username``
254+
instead of exposing the full field name ``?sort=Users.username``.
255+
256+
Multi-Column Sorting
257+
--------------------
258+
259+
The builder supports mapping a single sort key to multiple database fields with
260+
independent direction control. Use the ``SortField`` class to define complex
261+
sorting::
262+
263+
use Cake\Datasource\Paging\SortField;
264+
265+
protected array $paginate = [
266+
'sortableFields' => function ($builder) {
267+
return $builder
268+
->add('best-deal', [
269+
SortField::desc('in_stock'),
270+
SortField::asc('price'),
271+
])
272+
->add('popularity', [
273+
SortField::desc('view_count'),
274+
SortField::asc('title'),
275+
]);
276+
},
277+
];
278+
279+
Now ``?sort=best-deal`` will order by in-stock items first (descending), then by
280+
price (ascending). When users toggle the direction (e.g., ``?sort=best-deal&direction=asc``),
281+
all fields in the array will toggle their directions: in_stock becomes ASC and
282+
price becomes DESC.
283+
284+
Locked Sort Directions
285+
----------------------
286+
287+
You can lock a sort direction to prevent users from toggling it. This is useful
288+
when a field should always be sorted in a specific direction::
289+
290+
protected array $paginate = [
291+
'sortableFields' => function ($builder) {
292+
return $builder
293+
->add('latest', SortField::desc('created', locked: true))
294+
->add('id', SortField::asc('id', locked: true));
295+
},
296+
];
297+
298+
With locked directions, the sort key will always use the specified direction
299+
regardless of the ``direction`` parameter in the URL.
300+
301+
Combined Sorting Keys
302+
---------------------
303+
304+
In addition to the traditional ``?sort=field&direction=asc`` format, you can use
305+
combined sorting keys in URLs::
306+
307+
// These are equivalent
308+
?sort=title&direction=asc
309+
?sort=title-asc
310+
311+
// These are equivalent
312+
?sort=price&direction=desc
313+
?sort=price-desc
314+
315+
This provides a cleaner URL format for applications that prefer it.
316+
317+
Simple Array Configuration
318+
---------------------------
319+
320+
For basic use cases where you just need to allow sorting on specific fields
321+
without mapping or multi-column support, you can still use the simple array
322+
format::
323+
324+
protected array $paginate = [
325+
'sortableFields' => [
326+
'id', 'title', 'Users.username', 'created',
327+
],
328+
];
329+
227330
Limit the Maximum Number of Rows per Page
228331
=========================================
229332

0 commit comments

Comments
 (0)