Paginator
-
class Cake\View\Helper\PaginatorHelper(View $view, array $config = [])
The PaginatorHelper is used to output pagination controls such as page numbers
and next/previous links. It works in tandem with
PaginatorComponent
.
See also Pagination for information on how to
create paginated datasets and do paginated queries.
PaginatorHelper Templates
Internally PaginatorHelper uses a series of simple HTML templates to generate
markup. You can modify these templates to customize the HTML generated by the
PaginatorHelper.
Templates use {{var}}
style placeholders. It is important to not add any
spaces around the {{}}
or the replacements will not work.
Loading Templates from a File
When adding the PaginatorHelper in your controller, you can define the
‘templates’ setting to define a template file to load. This allows you to
customize multiple templates and keep your code DRY:
// In your AppView.php
public function initialize()
{
...
$this->loadHelper('Paginator', ['templates' => 'paginator-templates']);
}
This will load the file located at config/paginator-templates.php. See the
example below for how the file should look like. You can also load templates
from a plugin using plugin syntax:
// In your AppView.php
public function initialize()
{
...
$this->loadHelper('Paginator', ['templates' => 'MyPlugin.paginator-templates']);
}
Whether your templates are in the primary application or a plugin, your
templates file should look something like:
return [
'number' => '<a href="{{url}}">{{text}}</a>',
];
Changing Templates at Run-time
-
Cake\View\Helper\PaginatorHelper::setTemplates($templates)
This method allows you to change the templates used by PaginatorHelper at
runtime. This can be useful when you want to customize templates for a
particular method call:
// Read the current template value.
$result = $this->Paginator->getTemplates('number');
// Prior to 3.4
$result = $this->Paginator->templates('number');
// Change a template
$this->Paginator->setTemplates([
'number' => '<em><a href="{{url}}">{{text}}</a></em>'
]);
Warning
Template strings containing a percentage sign (%
) need special
attention, you should prefix this character with another percentage so it
looks like %%
. The reason is that internally templates are compiled to
be used with sprintf()
.
Example: ‘<div style=”width:{{size}}%%”>{{content}}</div>’
Template Names
PaginatorHelper uses the following templates:
nextActive
The active state for a link generated by next().
nextDisabled
The disabled state for next().
prevActive
The active state for a link generated by prev().
prevDisabled
The disabled state for prev()
counterRange
The template counter() uses when format == range.
counterPages
The template counter() uses when format == pages.
first
The template used for a link generated by first().
last
The template used for a link generated by last()
number
The template used for a link generated by numbers().
current
The template used for the current page.
ellipsis
The template used for ellipses generated by numbers().
sort
The template for a sort link with no direction.
sortAsc
The template for a sort link with an ascending direction.
sortDesc
The template for a sort link with a descending direction.
Creating Sort Links
-
Cake\View\Helper\PaginatorHelper::sort($key, $title = null, $options = [])
- Parameters:
$key (string
) – The name of the column that the recordset should be sorted.
$title (string
) – Title for the link. If $title is null, $key will be
used converted to “Title Case” format and used as the title.
$options (array
) – Options for sorting link.
Generates a sorting link. Sets querystring parameters for the sort and
direction. Links will default to sorting by asc. After the first click, links
generated with sort()
will handle direction switching automatically. If the
resultset is sorted ‘asc’ by the specified key the returned link will sort by
‘desc’.
Accepted keys for $options
:
escape
Whether you want the contents HTML entity encoded, defaults to
true
.
model
The model to use, defaults to PaginatorHelper::defaultModel()
.
direction
The default direction to use when this link isn’t active.
lock
Lock direction. Will only use the default direction then, defaults to false
.
Assuming you are paginating some posts, and are on page one:
echo $this->Paginator->sort('user_id');
Output:
<a href="/posts/index?page=1&sort=user_id&direction=asc">User Id</a>
You can use the title parameter to create custom text for your link:
echo $this->Paginator->sort('user_id', 'User account');
Output:
<a href="/posts/index?page=1&sort=user_id&direction=asc">User account</a>
If you are using HTML like images in your links remember to set escaping off:
echo $this->Paginator->sort(
'user_id',
'<em>User account</em>',
['escape' => false]
);
Output:
<a href="/posts/index?page=1&sort=user_id&direction=asc"><em>User account</em></a>
The direction option can be used to set the default direction for a link. Once a
link is active, it will automatically switch directions like normal:
echo $this->Paginator->sort('user_id', null, ['direction' => 'desc']);
Output:
<a href="/posts/index?page=1&sort=user_id&direction=desc">User Id</a>
The lock option can be used to lock sorting into the specified direction:
echo $this->Paginator->sort('user_id', null, ['direction' => 'asc', 'lock' => true]);
-
Cake\View\Helper\PaginatorHelper::sortDir(string $model = null, mixed $options = [])
Gets the current direction the recordset is sorted.
-
Cake\View\Helper\PaginatorHelper::sortKey(string $model = null, mixed $options = [])
Gets the current key by which the recordset is sorted.
Creating Page Number Links
-
Cake\View\Helper\PaginatorHelper::numbers($options = [])
Returns a set of numbers for the paged result set. Uses a modulus to
decide how many numbers to show on each side of the current page By default
8 links on either side of the current page will be created if those pages exist.
Links will not be generated for pages that do not exist. The current page is
also not a link.
Supported options are:
before
Content to be inserted before the numbers.
after
Content to be inserted after the numbers.
model
Model to create numbers for, defaults to
PaginatorHelper::defaultModel()
.
modulus
how many numbers to include on either side of the current page,
defaults to 8.
first
Whether you want first links generated, set to an integer to
define the number of ‘first’ links to generate. Defaults to false
. If a
string is set a link to the first page will be generated with the value as the
title:
echo $this->Paginator->numbers(['first' => 'First page']);
last
Whether you want last links generated, set to an integer to define
the number of ‘last’ links to generate. Defaults to false
. Follows the same
logic as the first
option. There is a
last()
method to be used separately as well if
you wish.
While this method allows a lot of customization for its output. It is
also ok to just call the method without any parameters.
echo $this->Paginator->numbers();
Using the first and last options you can create links to the beginning
and end of the page set. The following would create a set of page links that
include links to the first 2 and last 2 pages in the paged results:
echo $this->Paginator->numbers(['first' => 2, 'last' => 2]);
Creating Jump Links
In addition to generating links that go directly to specific page numbers,
you’ll often want links that go to the previous and next links, first and last
pages in the paged data set.
-
Cake\View\Helper\PaginatorHelper::prev($title = '<< Previous', $options = [])
- Parameters:
-
Generates a link to the previous page in a set of paged records.
$options
supports the following keys:
escape
Whether you want the contents HTML entity encoded,
defaults to true
.
model
The model to use, defaults to PaginatorHelper::defaultModel()
.
disabledTitle
The text to use when the link is disabled. Defaults to
the $title
parameter.
A simple example would be:
echo $this->Paginator->prev(' << ' . __('previous'));
If you were currently on the second page of posts, you would get the following:
<li class="prev">
<a rel="prev" href="/posts/index?page=1&sort=title&order=desc">
<< previous
</a>
</li>
If there were no previous pages you would get:
<li class="prev disabled"><a href="" onclick="return false;"><< previous</a></li>
To change the templates used by this method see PaginatorHelper Templates.
-
Cake\View\Helper\PaginatorHelper::next($title = 'Next >>', $options = [])
This method is identical to prev()
with a few exceptions. It
creates links pointing to the next page instead of the previous one. It also
uses next
as the rel attribute value instead of prev
-
Cake\View\Helper\PaginatorHelper::first($first = '<< first', $options = [])
Returns a first or set of numbers for the first pages. If a string is given,
then only a link to the first page with the provided text will be created:
echo $this->Paginator->first('< first');
The above creates a single link for the first page. Will output nothing if you
are on the first page. You can also use an integer to indicate how many first
paging links you want generated:
echo $this->Paginator->first(3);
The above will create links for the first 3 pages, once you get to the third or
greater page. Prior to that nothing will be output.
The options parameter accepts the following:
-
Cake\View\Helper\PaginatorHelper::last($last = 'last >>', $options = [])
This method works very much like the first()
method. It has a few differences though. It will not generate any links if you
are on the last page for a string values of $last
. For an integer value of
$last
no links will be generated once the user is inside the range of last
pages.
Creating a Page Counter
-
Cake\View\Helper\PaginatorHelper::counter($options = [])
Returns a counter string for the paged result set. Using a provided format
string and a number of options you can create localized and application
specific indicators of where a user is in the paged data set.
There are a number of options for counter()
. The supported ones are:
format
Format of the counter. Supported formats are ‘range’, ‘pages’
and custom. Defaults to pages which would output like ‘1 of 10’. In the
custom mode the supplied string is parsed and tokens are replaced with
actual values. The available tokens are:
{{page}}
- the current page displayed.
{{pages}}
- total number of pages.
{{current}}
- current number of records being shown.
{{count}}
- the total number of records in the result set.
{{start}}
- number of the first record being displayed.
{{end}}
- number of the last record being displayed.
{{model}}
- The pluralized human form of the model name.
If your model was ‘RecipePage’, {{model}}
would be ‘recipe pages’.
You could also supply only a string to the counter method using the tokens
available. For example:
echo $this->Paginator->counter(
'Page {{page}} of {{pages}}, showing {{current}} records out of
{{count}} total, starting on record {{start}}, ending on {{end}}'
);
Setting ‘format’ to range would output like ‘1 - 3 of 13’:
echo $this->Paginator->counter([
'format' => 'range'
]);
model
The name of the model being paginated, defaults to
PaginatorHelper::defaultModel()
. This is used in
conjunction with the custom string on ‘format’ option.
Creating a Limit Selectbox Control
-
Cake\View\Helper\PaginatorHelper::limitControl(array $limits = [], $default = null, array $options = [])
Create a dropdown control that changes the limit
query parameter:
// Use the defaults.
echo $this->Paginator->limitControl();
// Define which limit options you want.
echo $this->Paginator->limitControl([25 => 25, 50 => 50]);
// Custom limits and set the selected option
echo $this->Paginator->limitControl([25 => 25, 50 => 50], $user->perPage);
The generated form and control will automatically submit on change.
New in version 3.5.0: The limitControl()
method was added in 3.5.0
Example Usage
It’s up to you to decide how to show records to the user, but most often this
will be done inside HTML tables. The examples below assume a tabular layout, but
the PaginatorHelper available in views doesn’t always need to be restricted as
such.
See the details on
PaginatorHelper in
the API. As mentioned, the PaginatorHelper also offers sorting features which
can be integrated into your table column headers:
<!-- src/Template/Posts/index.ctp -->
<table>
<tr>
<th><?= $this->Paginator->sort('id', 'ID') ?></th>
<th><?= $this->Paginator->sort('title', 'Title') ?></th>
</tr>
<?php foreach ($recipes as $recipe): ?>
<tr>
<td><?= $recipe->id ?> </td>
<td><?= h($recipe->title) ?> </td>
</tr>
<?php endforeach; ?>
</table>
The links output from the sort()
method of the PaginatorHelper
allow
users to click on table headers to toggle the sorting of the data by a given
field.
It is also possible to sort a column based on associations:
<table>
<tr>
<th><?= $this->Paginator->sort('title', 'Title') ?></th>
<th><?= $this->Paginator->sort('Authors.name', 'Author') ?></th>
</tr>
<?php foreach ($recipes as $recipe): ?>
<tr>
<td><?= h($recipe->title) ?> </td>
<td><?= h($recipe->author->name) ?> </td>
</tr>
<?php endforeach; ?>
</table>
Note
Sorting by columns in associated models requires setting these in the
PaginationComponent::paginate
property. Using the example above, the
controller handling the pagination would need to set its sortWhitelist
key as follows:
$this->paginate = [
'sortWhitelist' => [
'Posts.title',
'Authors.name',
],
];
For more information on using the sortWhitelist
option, please see
Control which Fields Used for Ordering.
The final ingredient to pagination display in views is the addition of page
navigation, also supplied by the PaginationHelper:
// Shows the page numbers
<?= $this->Paginator->numbers() ?>
// Shows the next and previous links
<?= $this->Paginator->prev('« Previous') ?>
<?= $this->Paginator->next('Next »') ?>
// Prints X of Y, where X is current page and Y is number of pages
<?= $this->Paginator->counter() ?>
The wording output by the counter() method can also be customized using special
markers:
<?= $this->Paginator->counter([
'format' => 'Page {{page}} of {{pages}}, showing {{current}} records out of
{{count}} total, starting on record {{start}}, ending on {{end}}'
]) ?>
Paginating Multiple Results
If you are paginating multiple queries
you’ll need to set the model
option when generating pagination related
elements. You can either use the model
option on every method call you make
to PaginatorHelper
, or use options()
to set the default model:
// Pass the model option
echo $this->Paginator->sort('title', ['model' => 'Articles']);
// Set the default model.
$this->Paginator->options(['model' => 'Articles']);
echo $this->Paginator->sort('title');
By using the model
option, PaginatorHelper
will automatically use the
scope
defined in when the query was paginated.
New in version 3.3.0: Multiple Pagination was added in 3.3.0