在 Laravel 中通过自定义分页器分页方法实现伪静态分页链接以利于 SEO
我们知道,Laravel 自带的分页器方法包含 simplePaginate 和 paginate 方法,一个返回不带页码的分页链接,另一个返回带页码的分页链接,但是这两种分页链接页码都是以带问号的动态参数形式附加在查询字符串中,形如 https://laravelacademy.org?page=100,但是这种包含动态参数的 URL 格式对 SEO 不友好,我们最好将其转化为 https://laravelacademy.org/page/100 这种不带问号的伪静态分页链接格式,遗憾的是 Laravel 并没有提供对这种伪静态分页链接格式的自定义支持,只好自己动手了。
我们将基于 paginate 方法实现的分页进行扩展,只是修改其分页链接格式,该方法底层调用了 Illuminate\Pagination\LengthAwarePaginator 类实现分页,所以我们需要自定义一个继承自该分页器类的 app/Utils/AcademyPaginator.php。
一、创建文件app/Utils/AcademyPaginator.php
<?php
namespace App\Utils; use Illuminate\Container\Container;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Str;
use Illuminate\Pagination\Paginator;
use Illuminate\Pagination\LengthAwarePaginator as BasePaginator; class AcademyPaginator extends BasePaginator
{
/**
* 重写页面 URL 实现代码,去掉分页中的问号,实现伪静态链接
* @param int $page
* @return string
*/
public function url($page)
{
if ($page <= 0) {
$page = 1;
} // 移除路径尾部的/
$path = rtrim($this->path, '/'); // 如果路径中包含分页信息则正则替换页码,否则将页码信息追加到路径末尾
if (preg_match('/\/page\/\d+/', $path)) {
$path = preg_replace('/\/page\/\d+/', '/page/' . $page, $path);
} else {
$path .= '/page/' . $page;
}
$this->path = $path; if ($this->query) {
$url = $this->path . (Str::contains($this->path, '?') ? '&' : '?')
. http_build_query($this->query, '', '&')
. $this->buildFragment();
} elseif ($this->fragment) {
$url = $this->path . $this->buildFragment();
} else {
$url = $this->path;
} return $url;
} /**
* 重写当前页设置方法
*
* @param int $currentPage
* @param string $pageName
* @return int
*/
protected function setCurrentPage($currentPage, $pageName)
{
if (!$currentPage && preg_match('/\/page\/(\d+)/', $this->path, $matches)) {
$currentPage = $matches[1];
} return $this->isValidPageNumber($currentPage) ? (int) $currentPage : 1;
} /**
* 将新增的分页方法注册到查询构建器中,以便在模型实例上使用
* 注册方式:
* 在 AppServiceProvider 的 boot 方法中注册:AcademyPaginator::rejectIntoBuilder();
* 使用方式:
* 将之前代码中在模型实例上调用 paginate 方法改为调用 seoPaginate 方法即可:
* Article::where('status', 1)->seoPaginate(15, ['*'], 'page', page);
*/
public static function injectIntoBuilder()
{
/*
* $perPage 每页显示多少条
* $columns 查询的字段
* $pageName 翻页链接的参数名
* $page 当前页数
* */
Builder::macro('seoPaginate', function ($perPage, $columns, $pageName, $page) {
$perPage = $perPage ?: $this->model->getPerPage(); $items = ($total = $this->toBase()->getCountForPagination())
? $this->forPage($page, $perPage)->get($columns)
: $this->model->newCollection(); $options = [
'path' => Paginator::resolveCurrentPath(),
'pageName' => $pageName,
]; return Container::getInstance()->makeWith(AcademyPaginator::class, compact(
'items', 'total', 'perPage', 'page', 'options'
));
});
}
}
二、在 AppServiceProvider 的 boot 方法中全局调用这个注入:
// 为查询构建器注入自己实现的分页器方法
AcademyPaginator::injectIntoBuilder();
这样,在模型实例上调用 seoPaginate 方法,将通过 AcademyPaginator 进行分页。接下来,就可以在自己的代码中编写以下这种代码实现伪静态分页链接了:
$articles = Article::with('author', 'category')->public()->orderBy('id', 'desc')->seoPaginate($pageSize, $this->listColumns, 'page', $page);
参考文档:https://laravelacademy.org/post/9661.html
在 Laravel 中通过自定义分页器分页方法实现伪静态分页链接以利于 SEO的更多相关文章
- Laravel 中通过自定义分页器分页方法实现伪静态分页链接以利于 SEO
我们知道,Laravel 自带的分页器方法包含 simplePaginate 和 paginate 方法,一个返回不带页码的分页链接,另一个返回带页码的分页链接,但是这两种分页链接页码都是以带问号的动 ...
- 详解如何在Laravel中增加自定义全局函数
http://www.php.cn/php-weizijiaocheng-383928.html 如何在Laravel中增加自定义全局函数?在我们的应用里经常会有一些全局都可能会用的函数,我们应该怎么 ...
- django中的自定义分页器
1.什么是自定义分页器 当我们需要在前端页面展示的数据太多的时候,我们总不能将数据展示在一页上面吧!这时,我们就需要自定义一个分页器,将数据分成特定的页数进行展示,每一页展示固定条数的数据! 2.为什 ...
- Javascript 中创建自定义对象的方法(设计模式)
Javascript 中创建对象,可以有很多种方法. Object构造函数/对象字面量: 抛开设计模式不谈,使用最基本的方法,就是先调用Object构造函数创建一个对象,然后给对象添加属性. var ...
- php在laravel中使用自定义的Common类
众所周知,laravel是一款高度集成的开发框架,框架内置非常多的操作方法,从而保证了我们的开发效率.但是在日常中为了满足我们的个性化业务,也需要自己去编写工具类,在laravel中我们完成编写后还需 ...
- JavaScript中创建自定义对象的方法
本文内容参考JavaScript高级程序设计(第3版)第6章:面向对象的程序设计 ECMA-262中把对象定义为:“无序属性的集合,其属性可以包含基本值.对象或者函数.”我所理解的就是对象就是一个结构 ...
- Laravel中利用队列发送邮件的方法示例
https://www.jb51.net/article/121647.htm 本文主要给大家介绍了关于Laravel中队列发送邮件的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的 ...
- delphi中使用自定义资源的方法
如果要在delphi中使用自定义资源文件*.res文件,比如一个光标,此时可以采用下列步骤: 1,创建包含相应的资源文件,这里是创建一个包含自定义光标的res文件. 2,在主窗体的pas文件中加入编译 ...
- 纯JS前端分页方法(JS分页)
1.JS分页函数:开发过程中,分页功能一般是后台提供接口,前端只要传page(当前页码)和pageSize(每页最大显示条数)及对应的其他查询条件,就可以返回所需分页显示的数据. 但是有时也需要前端本 ...
随机推荐
- 不同编程语言实现HelloWorld程序
目录 C C# C++ HTML Java Python C #include <stdio.h> int main() { printf("Hello World!" ...
- Easy [还是概率DP思想……]
题目描述 某一天\(WJMZBMR\)在打\(osu\)~~~但是他太弱逼了,有些地方完全靠运气\(QaQ\) 我们来简化一下这个游戏的规则 有\(n\)次点击要做,成功了就是\(o\),失败了就是\ ...
- 图解resilience4j容错机制
Resilience4j是一个轻量级.易于使用的容错库,其灵感来自Netflix Hystrix,但专为Java 8和函数式编程设计.轻量级,因为库只使用Vavr,它没有任何其他外部库依赖项.相比之下 ...
- 小师妹学JVM之:逃逸分析和TLAB
目录 简介 逃逸分析和栈上分配 TLAB简介 TLAB详解 设置TLAB空间的大小 TLAB中大对象的分配 TLAB空间中的浪费 总结 简介 逃逸分析我们在JDK14中JVM的性能优化一文中已经讲过了 ...
- css实现1px 像素线条_解决移动端1px线条的显示方式
使用CSS 绘制出 1px 的边框,在移动端上渲染的效果会出现不同,部分手机发现1px 线条变胖了,这篇文章整理2种方式实现1px 像素线条. 1.利用box-shadow + transform & ...
- 洛谷P3237 米特运输
题目链接 题意: 中文题,挺好理解.就是让节点的权值等于各子节点权值之和,然后每个子节点的权值相等,原本每个点有一个权值,通过最少次的修改(可以修改成小数)使其满足要求. 分析: 题意一旦读明白,题什 ...
- Deno 学习笔记(1)安装及简单的request
Deno下载和安装 PowerShell iwr https://deno.land/x/install/install.ps1 -useb | iex Shell curl -fsSL https: ...
- 【题解】p1809 过河问题
原题传送门 题目分析 现有n个人在东岸,要过河去西岸.开始东岸有一艘船,船最多可承载2人,过河时间以耗时最长的人所需时间为准. 给定n个人的过河时间a,求所有人从东岸到西岸所需的最短时间. 当\(n= ...
- C/C++编程语言制作《游戏内存外挂》
通过C/C++编程语言编写一个简单的外挂,通过 API 函数修改游戏数据,从而实现作弊功能 对象分析要用的 API 函数简单介绍编写测试效果. 下面是我整理好的全套C/C++资料,加入天狼QQ7269 ...
- Scala 面向对象(四):import
1 Scala引入包基本介绍 Scala引入包也是使用import, 基本的原理和机制和Java一样,但是Scala中的import功能更加强大,也更灵活. 因为Scala语言源自于Java,所以ja ...