如何在Drupal视图中通过代码在指定页数后切换分页类型?
Drupal视图分页动态切换解决方案
问题背景
我有一个返回数百条数据的Drupal视图,规划了分层分页策略优化用户体验:
- 前3页通过
infinite_scroll模块实现AJAX自动加载 - 第3页之后切换为“加载更多”手动触发加载
- 第5页之后改用Drupal原生“mini”经典分页,避免大量数据加载导致浏览器内存溢出
前两部分已通过hook_views_pre_render()实现,但尝试切换分页类型时失败——修改infinite_scroll的配置有效,但无法将分页类型从infinite_scroll改为mini。
已实现的“加载更多”切换代码:
$pager = $view->display_handler->getOption('pager'); if ($view->pager->current_page > 2) { $pager['options']['views_infinite_scroll']['automatically_load_content'] = FALSE; $view->display_handler->setOption('pager', $pager); $view->pager->options['views_infinite_scroll']['automatically_load_content'] = FALSE; }
尝试切换分页类型但未生效的代码:
$pager = $view->display_handler->getOption('pager'); if ($pager['type'] == 'infinite_scroll') { if ($view->pager->current_page > 4) { $pager['type'] = 'mini'; unset($pager['options']['views_infinite_scroll']); $view->display_handler->setOption('pager', $pager); } elseif ($view->pager->current_page > 2) { $pager['options']['views_infinite_scroll']['automatically_load_content'] = FALSE; $view->display_handler->setOption('pager', $pager); $view->pager->options['views_infinite_scroll']['automatically_load_content'] = FALSE; } }
问题原因
hook_views_pre_render()的执行时机在视图分页对象初始化之后,仅修改display的分页配置不会重新实例化分页类,因此分页类型切换无法生效。
解决方案
需要手动重新初始化分页对象并绑定到视图,完整代码如下:
use Drupal\views\ViewExecutable; use Drupal\views\Views; function YOUR_MODULE_views_pre_render(ViewExecutable $view) { // 仅针对目标视图和显示,替换为实际值 if ($view->id() !== 'your_view_id' || $view->current_display !== 'your_display_id') { return; } $pager = $view->display_handler->getOption('pager'); $current_page = $view->pager->current_page; if ($pager['type'] == 'infinite_scroll') { if ($current_page > 4) { // 切换为mini分页 $pager['type'] = 'mini'; // 配置mini分页的基础参数(可按需调整) $pager['options'] = [ 'items_per_page' => $pager['options']['items_per_page'], 'offset' => 0, 'id' => 0, 'total_pages' => '', 'expose' => [ 'items_per_page' => FALSE, 'items_per_page_label' => '每页条数', 'items_per_page_options' => '10, 20, 50', 'items_per_page_options_all' => FALSE, 'offset' => FALSE, ], 'tags' => [ 'first' => '« 首页', 'last' => '末页 »', 'previous' => '‹ 上一页', 'next' => '下一页 ›', ], ]; $view->display_handler->setOption('pager', $pager); // 关键:重新创建mini分页实例并绑定到视图 $view->pager = Views::pluginManager('pager')->createInstance('mini', $pager['options']); $view->pager->setView($view); // 重新执行分页逻辑 $view->pager->execute($view->query); } elseif ($current_page > 2) { // 切换为手动加载更多 $pager['options']['views_infinite_scroll']['automatically_load_content'] = FALSE; $view->display_handler->setOption('pager', $pager); $view->pager->options['views_infinite_scroll']['automatically_load_content'] = FALSE; } } }
注意事项
- 替换代码中的
YOUR_MODULE、your_view_id、your_display_id为实际的模块名、视图ID和显示ID - 可根据需求调整mini分页的
options配置,比如每页条数、分页文本等 - 确保代码中引入了必要的命名空间
内容的提问来源于stack exchange,提问作者user15739925
相关产品推荐
相关产品推荐

