如何在 CakePHP 4.x 中使用路由元素而不是查询字符串参数进行分页?
How to use route elements instead of query string arguments for pagination in CakePHP 4.x?
我网站的分页网址是这样工作的,但是当我升级到 4.x 时停止工作 - 例如:第一页:mywebsite。com/new - 第二页:mywebsite。com/new /page/2 等。我用下面的代码做到了:
//routes.php
$routes->connect('/new/page/:page',
['controller' => 'Articles', 'action' => 'latest'], [
'pass' => [
'page'
],
'page' => '\d+'
]);
$routes->connect('/new', ['controller' => 'Articles', 'action' => 'latest']);
然后在我的 view/pagination-element 我有以下内容:
//view
$this->Paginator->options(['url' => ['controller' => 'Articles', 'action' => 'latest']]);
url mywebsite.com/new/page/2, 3等在直接访问时仍然有效,但是通过视图中的分页器创建的链接是mywebsite.com/new?page =2、3 等,而它们应该是 mywebsite。com/new/page/2、3 等
有人能指出我正确的方向吗?
我建议您考虑可能更改 URL 架构以使用查询参数样式。使用 route/URI 元素只意味着需要更多工作才能使分页器功能正常工作。此外,所有关于使用 "pretty URLs" 进行分页的论点(搜索引擎优化、可读性等)在过去非常流行,结果证明只是空谈。
也就是说,您必须使用 custom/extended 分页助手来更改 URL 的生成方式,因为默认情况下,助手会显式设置 page
参数(以及所有其他分页相关参数)作为查询字符串参数。如果覆盖 \Cake\View\Helper\PaginatorHelper::generateUrlParams()
.
,则可以控制所有生成的 URL
一个简单粗暴的例子:
// src/View/Helper/PaginatorHelper.php
/*
Load in `AppView::initialize()` via:
$this->loadHelper('Paginator', [
'className' => \App\View\Helper\PaginatorHelper::class
]);
*/
declare(strict_types=1);
namespace App\View\Helper;
class PaginatorHelper extends \Cake\View\Helper\PaginatorHelper
{
public function generateUrlParams(array $options = [], ?string $model = null, array $url = []): array
{
$params = parent::generateUrlParams($options, $model, $url);
if (isset($params['?']['page'])) {
$params[0] = $params['?']['page'];
unset($params['?']['page']);
} else {
$params[0] = 1;
}
return $params;
}
}
这会将 URL 数组中的 page
参数值从查询字符串配置移动到常规 URL 参数,即 turn
['controller' => 'Articles', 'action' => 'latest', '?' => ['page' => 1, /* ... */]]
进入
['controller' => 'Articles', 'action' => 'latest', 1, '?' => [/* ... */]]
但是,我再次强烈建议考虑切换到查询字符串 URL 架构。
另见
我网站的分页网址是这样工作的,但是当我升级到 4.x 时停止工作 - 例如:第一页:mywebsite。com/new - 第二页:mywebsite。com/new /page/2 等。我用下面的代码做到了:
//routes.php
$routes->connect('/new/page/:page',
['controller' => 'Articles', 'action' => 'latest'], [
'pass' => [
'page'
],
'page' => '\d+'
]);
$routes->connect('/new', ['controller' => 'Articles', 'action' => 'latest']);
然后在我的 view/pagination-element 我有以下内容:
//view
$this->Paginator->options(['url' => ['controller' => 'Articles', 'action' => 'latest']]);
url mywebsite.com/new/page/2, 3等在直接访问时仍然有效,但是通过视图中的分页器创建的链接是mywebsite.com/new?page =2、3 等,而它们应该是 mywebsite。com/new/page/2、3 等
有人能指出我正确的方向吗?
我建议您考虑可能更改 URL 架构以使用查询参数样式。使用 route/URI 元素只意味着需要更多工作才能使分页器功能正常工作。此外,所有关于使用 "pretty URLs" 进行分页的论点(搜索引擎优化、可读性等)在过去非常流行,结果证明只是空谈。
也就是说,您必须使用 custom/extended 分页助手来更改 URL 的生成方式,因为默认情况下,助手会显式设置 page
参数(以及所有其他分页相关参数)作为查询字符串参数。如果覆盖 \Cake\View\Helper\PaginatorHelper::generateUrlParams()
.
一个简单粗暴的例子:
// src/View/Helper/PaginatorHelper.php
/*
Load in `AppView::initialize()` via:
$this->loadHelper('Paginator', [
'className' => \App\View\Helper\PaginatorHelper::class
]);
*/
declare(strict_types=1);
namespace App\View\Helper;
class PaginatorHelper extends \Cake\View\Helper\PaginatorHelper
{
public function generateUrlParams(array $options = [], ?string $model = null, array $url = []): array
{
$params = parent::generateUrlParams($options, $model, $url);
if (isset($params['?']['page'])) {
$params[0] = $params['?']['page'];
unset($params['?']['page']);
} else {
$params[0] = 1;
}
return $params;
}
}
这会将 URL 数组中的 page
参数值从查询字符串配置移动到常规 URL 参数,即 turn
['controller' => 'Articles', 'action' => 'latest', '?' => ['page' => 1, /* ... */]]
进入
['controller' => 'Articles', 'action' => 'latest', 1, '?' => [/* ... */]]
但是,我再次强烈建议考虑切换到查询字符串 URL 架构。
另见