Symfony中Knp Paginator如何将查询参数式分页URL改为路径式
Knp Paginator 路径式分页URL配置方案
问题描述
我正在学习使用Knp Paginator,希望将当前的分页URL(如loli/page/?page=2)修改为路径形式的loli/page/2。尝试过在路由中使用{page}作为参数,也试过在Twig中使用split过滤器,虽然URL显示正确,但页面内容无法正常加载,默认显示最后一页。
解决方案
1. 修改路由定义
把分页路由改为带有可选page参数的形式,设置默认值为1,同时将参数直接注入控制器方法,确保分页参数来源清晰:
// 修改后的分页控制器代码 #[Route('/loli/page/{page}', name: 'loli', defaults: ['page' => 1], methods: ['GET'])] public function mainPaginate(Request $request, ImageRepository $image, PaginatorInterface $paginator, int $page): Response { $images = $paginator->paginate( $image->findBy([], ['id' => 'DESC']), $page, // 直接使用路由参数中的page值 8 // 每页条数 ); return $this->render('pages/main.html.twig', compact('images')); }
2. 优化Knp Paginator全局配置(可选)
在config/packages/knp_paginator.yaml中添加参数配置,指定分页参数名为路由中的page,让组件自动适配参数来源:
knp_paginator: page_parameter_name: page
3. 修改Twig分页模板的URL生成逻辑
原模板中使用查询参数拼接URL,现在改为直接将page作为路由参数传入path函数,彻底切换为路径式URL:
{# 修改后的paginate.html.twig核心代码 #} {% if pageCount > 1 %} <nav aria-label="Pagination"> {% set classAlign = (align is defined) ? " text-#{align}" : '' %} <ul class="pagination{{ classAlign }}"> {% if previous is defined %} <li><a rel="prev" href="{{ path('loli', {'page': previous}) }}"> {{ '-'|trans({}, 'KnpPaginatorBundle') }}</a></li> {% else %} <li style="display: none;"><a class="disabled">{{ '-'|trans({}, 'KnpPaginatorBundle') }}</a></li> {% endif %} {% if startPage > 1 %} <li><a href="{{ path('loli', {'page': 1}) }}">1</a></li> {% if startPage == 3 %} <li><a href="{{ path('loli', {'page': 2}) }}">2</a></li> {% elseif startPage != 2 %} <li class="ellipsis"></li> {% endif %} {% endif %} {% for page in pagesInRange %} {% if page != current %} <li><a href="{{ path('loli', {'page': page}) }}"> {{ page }}</a></li> {% else %} {# <li class="current">{{ page }}</li> #} {% endif %} {% endfor %} {% if pageCount > endPage %} {% if pageCount > (endPage + 1) %} {% if pageCount > (endPage + 2) %} <li class="ellipsis"></li> {% else %} <li><a href="{{ path('loli', {'page': (pageCount - 1)}) }}"> {{ pageCount -1 }}</a></li> {% endif %} {% endif %} <li><a href="{{ path('loli', {'page': pageCount}) }}">{{ pageCount }}</a></li> {% endif %} {% if next is defined %} <li><a rel="next" href="{{ path('loli', {'page': next}) }}"> {{ '+'|trans({}, 'KnpPaginatorBundle') }}</a></li> {% else %} <li style="display: none;" class="disabled">{{ '+'|trans({}, 'KnpPaginatorBundle') }}</li> {% endif %} </ul> </nav> {% endif %}
关键说明
- 路由参数直接注入控制器,避免了从
request->query获取参数导致的来源混乱,解决了默认显示最后一页的问题。 - 模板中直接使用路由参数生成URL,彻底抛弃查询参数模式,确保URL格式为
/loli/page/2。 - 全局配置参数后,Knp Paginator会自动识别路由中的分页参数,减少模板中的重复代码。
内容的提问来源于stack exchange,提问作者UnSeulChemin
相关产品推荐
相关产品推荐

