thinkphp 8 的 paginate() 自定义模板需严格遵循路径和命名规则:模板必须置于 resources/view/paginate/custom.php,调用时仅用 $list->render('custom');appends 推荐使用 request()->except(['page']) 避免空参数。

ThinkPHP 8 的 paginate() 返回的 Paginator 实例默认调用的是内置模板(如 bootstrap.php),HTML 结构和 class 名是硬编码的,不改模板或类就不可能真正换样式——光靠 setConfig() 或传参只能改文字、改占位符内容,改不了 <ul></ul>、<li> 这些标签本身。
为什么 render('custom') 不生效?路径和命名必须严格匹配
很多人复制了 bootstrap.php 到 resources/view/paginate/custom.php,却在模板里写 {$list->render('custom')} 或 $list->render('paginate/custom'),结果还是输出默认样式。这是因为:
- ThinkPHP 8 只识别
resources/view/paginate/下的文件,且**不带目录前缀**,只认文件名(不含.php) - 正确调用是:
$list->render('custom'),不是'paginate/custom'或'custom.php' - 模板文件必须是 PHP 文件,且需返回字符串(不能 echo,要 return)
- 模板中可用变量有:
$paginator(实例)、$currentPage、$lastPage、$hasPrevious、$hasNext;别用已弃用的$render
自定义模板里怎么写 HTML 才安全?别直接删逻辑
打开你复制的 custom.php,不要一上来就全删,先看清楚哪些是结构、哪些是逻辑。常见错误是把 foreach 循环整个删掉,导致页码数字消失。
- 保留原始循环结构(比如遍历
$paginator->getUrlRange(...)或$paginator->links()的部分),只替换外层标签和 class - 想用
<nav></nav>替代<ul></ul>?把<ul class="pagination"></ul>换成<nav class="pager"></nav>,里面<li>改成<button></button>或<a></a>都可以 - 当前页需要特殊 class?用
$page == $currentPage ? 'active' : ''判断,别依赖框架旧的current_class配置(它在模板里不起作用) - 中文按钮文字直接写,如
上一页、下一页,不用urlencode—— 框架会自动处理 URL 编码
appends 传参漏掉或带空值?request()->except(['page']) 更稳
分页链接默认不带搜索参数,点第二页就丢掉 ?keyword=abc&status=1。手动 appends 时容易出错:
- 错:只写
$list->appends(request()->only(['keyword', 'status']))→ 如果keyword不存在,会传['keyword' => null],URL 变成?keyword=&status=1 - 对:用
$list->appends(request()->except(['page'])),它只取所有非空、存在的 GET 参数 - 如果是 POST 表单提交后分页,得先在控制器里合并:
$list->appends(array_merge($searchData, ['page' => $request->input('page', 1)])) -
var_page要配对:如果 URL 是/list?p=2,必须加'var_page' => 'p',否则翻页时参数名还是page,失效
真正卡住人的地方不在模板语法,而在「模板路径注册规则」和「appends 参数过滤逻辑」——这两处错一个,样式再漂亮也出不来,参数一丢就回到第一页。动手前先确认 resources/view/paginate/custom.php 存在且可读,再检查控制器里 render('custom') 的调用是否干净无拼写错误。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











