PaginatorHelper 用于输出分页控件,例如页码和上一页/下一页链接。
另请参阅 分页,了解如何创建分页数据集和执行分页查询。
默认情况下,助手使用在视图变量中找到的第一个 Cake\Datasource\Paging\PaginatedInterface
实例。(通常是 Controller::paginate()
的结果)。
您可以使用 PaginatorHelper::setPaginated()
显式设置助手应该使用的分页结果集。
在内部,PaginatorHelper 使用一系列简单的 HTML 模板来生成标记。您可以修改这些模板以自定义 PaginatorHelper 生成的 HTML。
模板使用 {{var}}
样式占位符。重要的是不要在 {{}}
周围添加任何空格,否则替换将不起作用。
在控制器中添加 PaginatorHelper 时,您可以定义 'templates' 设置来定义要加载的模板文件。这允许您自定义多个模板并保持代码 DRY
// In your AppView.php
public function initialize(): void
{
...
$this->loadHelper('Paginator', ['templates' => 'paginator-templates']);
}
这将加载位于 config/paginator-templates.php 的文件。有关文件外观,请参阅下面的示例。您还可以使用 插件语法 从插件加载模板
// In your AppView.php
public function initialize(): void
{
...
$this->loadHelper('Paginator', ['templates' => 'MyPlugin.paginator-templates']);
}
无论您的模板位于主应用程序还是插件中,您的模板文件都应类似于以下内容
return [
'number' => '<a href="{{url}}">{{text}}</a>',
];
此方法允许您在运行时更改 PaginatorHelper 使用的模板。当您希望为特定方法调用自定义模板时,这很有用
// Read the current template value.
$result = $this->Paginator->getTemplates('number');
// Change a template
$this->Paginator->setTemplates([
'number' => '<em><a href="{{url}}">{{text}}</a></em>'
]);
警告
包含百分号 (%
) 的模板字符串需要特别注意,您应该用另一个百分号作为前缀,使其看起来像 %%
。原因是在内部,模板被编译为与 sprintf()
一起使用。示例:‘<div style=”width:{{size}}%%”>{{content}}</div>’
PaginatorHelper 使用以下模板
nextActive
next() 生成的链接的活动状态。
nextDisabled
next() 的禁用状态。
prevActive
prev() 生成的链接的活动状态。
prevDisabled
prev() 的禁用状态
counterRange
counter() 在 format == range 时使用的模板。
counterPages
counter() 在 format == pages 时使用的模板。
first
first() 生成的链接使用的模板。
last
last() 生成的链接使用的模板
number
numbers() 生成的链接使用的模板。
current
当前页面使用的模板。
ellipsis
numbers() 生成的省略号使用的模板。
sort
没有方向的排序链接的模板。
sortAsc
具有升序方向的排序链接的模板。
sortDesc
具有降序方向的排序链接的模板。
$key (string
) – 记录集应排序的列的名称。
$title (string
) – 链接的标题。如果 $title 为 null,则将使用 $key 转换为 “Title Case” 格式并用作标题。
$options (array
) – 排序链接的选项。
生成排序链接。设置用于排序和方向的查询字符串参数。链接默认按升序排序。在第一次点击后,使用 sort()
生成的链接将自动处理方向切换。如果结果集按指定键按 'asc' 排序,则返回的链接将按 'desc' 排序。使用 sort
、sortAsc
、sortDesc
、sortAscLocked
和 sortDescLocked
模板。
用于 $options
的接受的键
escape
是否希望对内容进行 HTML 实体编码,默认为 true
。
direction
当此链接不活动时使用的默认方向。
lock
锁定方向。然后将仅使用默认方向,默认为 false
。
假设您正在分页一些帖子,并且您在第一页上
echo $this->Paginator->sort('user_id');
输出
<a href="/posts/index?page=1&sort=user_id&direction=asc">User Id</a>
您可以使用 title 参数为您的链接创建自定义文本
echo $this->Paginator->sort('user_id', 'User account');
输出
<a href="/posts/index?page=1&sort=user_id&direction=asc">User account</a>
如果您在链接中使用图像之类的 HTML,请记住关闭转义
echo $this->Paginator->sort(
'user_id',
'<em>User account</em>',
['escape' => false]
);
输出
<a href="/posts/index?page=1&sort=user_id&direction=asc"><em>User account</em></a>
direction 选项可用于为链接设置默认方向。链接处于活动状态后,它将像往常一样自动切换方向
echo $this->Paginator->sort('user_id', null, ['direction' => 'desc']);
输出
<a href="/posts/index?page=1&sort=user_id&direction=desc">User Id</a>
lock 选项可用于将排序锁定到指定方向
echo $this->Paginator->sort('user_id', null, ['direction' => 'asc', 'lock' => true]);
获取当前记录集排序的方向。
获取当前记录集排序的键。
返回分页结果集的一组页码。使用取模运算来决定当前页两侧显示多少个页码。默认情况下,如果存在这些页码,则会在当前页两侧创建 8 个链接。对于不存在的页码,不会生成链接。当前页也不是链接。将使用 number
、current
和 ellipsis
模板。
支持的选项:
before
插入页码之前的文本。
after
插入页码之后的文本。
modulus
在当前页两侧包含的页码数量,默认为 8。
first
是否要生成第一个链接,设置为整数以定义要生成的“第一个”链接的数量。默认为 false
。如果设置了字符串,则将使用该值作为标题生成指向第一页的链接。
echo $this->Paginator->numbers(['first' => 'First page']);
last
是否要生成最后一个链接,设置为整数以定义要生成的“最后一个”链接的数量。默认为 false
。遵循与 first
选项相同的逻辑。如果您希望单独使用,还有一个 last()
方法。
虽然此方法允许对输出进行大量定制,但也可以在不带任何参数的情况下调用该方法。
echo $this->Paginator->numbers();
使用 first 和 last 选项,您可以创建指向分页结果集的开头和结尾的链接。以下示例将创建一组页码链接,其中包含指向分页结果集中前 2 页和后 2 页的链接。
echo $this->Paginator->numbers(['first' => 2, 'last' => 2]);
除了生成指向特定页码的链接外,您通常还需要生成指向分页数据集中上一页、下一页、第一页和最后一页的链接。
$title (string
) – 链接标题。
$options (mixed
) – 分页链接的选项。
生成指向一组分页记录中上一页的链接。使用 prevActive
和 prevDisabled
模板。
$options
支持以下键
escape
是否希望对内容进行 HTML 实体编码,默认为 true
。
disabledTitle
链接禁用时使用的文本。默认为 $title
参数。
一个简单的示例:
echo $this->Paginator->prev(' << ' . __('previous'));
如果您当前位于帖子列表的第二页,您将看到以下内容:
<li class="prev">
<a rel="prev" href="/posts/index?page=1&sort=title&order=desc">
<< previous
</a>
</li>
如果没有上一页,您将看到以下内容:
<li class="prev disabled"><a href="" onclick="return false;"><< previous</a></li>
要更改此方法使用的模板,请参见 PaginatorHelper 模板。
此方法与 prev()
相同,但有一些例外。它创建指向下一页的链接,而不是上一页的链接。它还使用 next
作为 rel 属性值,而不是 prev
。使用 nextActive
和 nextDisabled
模板。
返回第一页或一组页码。如果给定字符串,则只会创建一个带有提供的文本指向第一页的链接。
echo $this->Paginator->first('< first');
以上代码创建了一个指向第一页的单链接。如果您位于第一页,则不会输出任何内容。您也可以使用整数来指示要生成的第一个分页链接的数量。
echo $this->Paginator->first(3);
以上代码将为前 3 页创建链接,当您进入第 3 页或更高页时。在此之前不会输出任何内容。使用 first
模板。
options 参数接受以下内容:
escape
文本是否应该转义。如果您的内容包含 HTML,则将其设置为 false
。
获取记录集的当前页。
// Our URL is: /comments?page=3
echo $this->Paginator->current();
// Output is 3
使用 current
模板。
如果给定结果集不在最后一页,则返回 true
。
如果给定结果集不在第一页,则返回 true
。
如果给定结果集包含 $page
给定的页码,则返回 true
。
返回所提供模型的总页数。
返回分页结果集的计数器字符串。 使用提供的格式字符串和一些选项,您可以创建本地化和特定于应用程序的指标,以指示用户在分页数据集中的位置。 使用 counterRange
和 counterPages
模板。
支持的格式为 'range'、'pages' 和自定义。 默认为 pages,它将输出为 '1 of 10'。 在自定义模式下,提供的字符串将被解析,并且标记将被替换为实际值。 可用的标记是
{{page}}
- 显示的当前页码。
{{pages}}
- 总页数。
{{current}}
- 当前显示的记录数。
{{count}}
- 结果集中的总记录数。
{{start}}
- 显示的第一条记录的编号。
{{end}}
- 显示的最后一条记录的编号。
{{model}}
- 模型名称的复数形式。 如果您的模型是 'RecipePage',{{model}}
将是 'recipe pages'。
您也可以只向 counter 方法提供一个字符串,使用可用的标记。 例如
echo $this->Paginator->counter(
'Page {{page}} of {{pages}}, showing {{current}} records out of
{{count}} total, starting on record {{start}}, ending on {{end}}'
);
将 'format' 设置为 range 将输出类似 '1 - 3 of 13' 的内容
echo $this->Paginator->counter('range');
默认情况下返回用于非标准上下文(即 JavaScript)的完整分页 URL 字符串。
// Generates a URL similar to: /articles?sort=title&page=2
echo $this->Paginator->generateUrl(['sort' => 'title']);
// Generates a URL for a different model
echo $this->Paginator->generateUrl(['sort' => 'title'], 'Comments');
// Generates a URL to a different controller.
echo $this->Paginator->generateUrl(
['sort' => 'title'],
null,
['controller' => 'Comments']
);
创建一个下拉控件,该控件更改 limit
查询参数
// 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);
生成的表单和控件将自动在更改时提交。
设置 PaginatorHelper 的所有选项。 支持的选项有
url
分页操作的 URL。
此选项允许您为助手生成的 URL 设置/覆盖任何元素
$this->Paginator->options([
'url' => [
'lang' => 'en',
'?' => [
'sort' => 'email',
'direction' => 'desc',
'page' => 6,
],
]
]);
上面的示例将 en
路由参数添加到助手将生成的所有链接中。 它还将使用特定的排序、方向和页码值创建链接。 默认情况下,PaginatorHelper
将合并所有当前传递的参数和查询字符串参数。
escape
定义链接的标题字段是否应进行 HTML 转义。 默认值为 true
。
您需要决定如何向用户展示记录,但大多数情况下这将在 HTML 表格内完成。 以下示例假设表格布局,但视图中可用的 PaginatorHelper 不一定需要限制为这样。
查看 API 中有关 PaginatorHelper 的详细信息。 如前所述,PaginatorHelper 还提供排序功能,这些功能可以集成到您的表格列标题中
<!-- templates/Posts/index.php -->
<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>
PaginatorHelper
的 sort()
方法输出的链接允许用户单击表格标题来切换数据的排序方式(按给定字段排序)。
还可以根据关联对列进行排序
<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->name) ?> </td>
</tr>
<?php endforeach; ?>
</table>
注意
按关联模型中的列排序需要在 PaginationComponent::paginate
属性中进行设置。 使用上面的示例,处理分页的控制器需要将其 sortableFields
键设置为以下内容
$this->paginate = [
'sortableFields' => [
'Posts.title',
'Authors.name',
],
];
有关使用 sortableFields
选项的更多信息,请参阅 控制用于排序的字段。
视图中分页显示的最后一个要素是添加页面导航,这也由 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() ?>
counter() 方法输出的文字也可以使用特殊标记进行自定义
<?= $this->Paginator->counter([
'format' => 'Page {{page}} of {{pages}}, showing {{current}} records out of
{{count}} total, starting on record {{start}}, ending on {{end}}'
]) ?>
如果您要 对多个查询进行分页,则需要先使用 PaginatorHelper::setPaginated()
,然后再调用助手的其他方法,这样才能生成预期的输出。
PaginatorHelper
将自动使用查询分页时定义的 scope
。 要为多个分页设置其他 URL 参数,您可以在 options()
中包含范围名称
$this->Paginator->options([
'url' => [
// Additional URL parameters for the 'articles' scope
'articles' => [
'?' => ['articles' => 'yes']
],
// Additional URL parameters for the 'comments' scope
'comments' => [
'articleId' => 1234,
],
],
]);