I'm using laravel-5.4 pagination like the following:
public function index()
{
$jobs = Job::paginate(5);
return view('job.index', compact('jobs'));
}
In the view:
{{ $jobs->links() }}
There is a problem of generating two typical pages: /job
and /job?page=1
the two page has the same contents.
I want to do anything that removes the query string page
from the first page of the pagination.
I have tried the following:
if ($jobs->onFirstPage()){
$jobs->setPageName('');
}
But this corrupt the pagination, i.e the links of pages does not load correctly and the query string value remains for all pages.
The effective solution for this issue that I have found is to edit the pagination template.
First publish the pagination template from the vendors using the following command from the root of the project:
php artisan vendor:publish --tag=laravel-pagination
Now a file at resources/views/vendor/pagination/default.blade.php
should be found and it could be edited like the following using str_replace()
for the urls of each page and back navigation button:
<li><a href="{{str_replace('?page=1','',$paginator->previousPageUrl())}}" title="{{__('Previous')}}" rel="prev">{{$foxPrev}}</a></li>
and
<li><a href="{{str_replace('?page=1','',$url)}}">{{ $page }}</a></li>
A bug was found with ?page=10
so instead of using str_replace
we should using preg_replace
like the following:
<li><a href="{{preg_replace('/\?page=[1]$/','',$url)}}">{{ $page }}</a></li>
In case of using any customized name for the page number parameter other than page
, we could use the paginator getter for the $pageName property like the following in the pagination template:
<li><a href="{{preg_replace('/\?'.$paginator->getPageName().'=[1]$/','',$url)}}">{{ $page }}</a></li>
To know more about how to use more than one pagination on the same page or how to customize the page number parameter $pageName
from view, checkout this answer
You can extend LengthAwarePaginator method url($page)
/**
* Get the URL for a given page number.
*
* @param int $page
* @return string
*/
public function url($page)
{
if ($page <= 0) {
$page = 1;
}
// If we have any extra query string key / value pairs that need to be added
// onto the URL, we will put them in query string form and then attach it
// to the URL. This allows for extra information like sortings storage.
$parameters = ($page > 1) ? [$this->pageName => $page] : [];
if (count($this->query) > 0) {
$parameters = array_merge($this->query, $parameters);
}
return rtrim($this->path
.(Str::contains($this->path, '?') ? '&' : '?')
.http_build_query($parameters, '', '&')
.$this->buildFragment(), '?');
}
improved Aksi answer
app/Services/CustomLengthAwarePaginator.php
<?php
namespace App\Services;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
class CustomLengthAwarePaginator extends LengthAwarePaginator
{
/**
* Get the URL for a given page number.
*
* @param int $page
* @return string
*/
public function url($page)
{
if ($page <= 0) {
$page = 1;
}
// If we have any extra query string key / value pairs that need to be added
// onto the URL, we will put them in query string form and then attach it
// to the URL. This allows for extra information like sortings storage.
$parameters = ($page > 1) ? [$this->pageName => $page] : [];
if (count($this->query) > 0) {
$parameters = array_merge($this->query, $parameters);
}
return $this->path()
. (count($parameters) > 0
? (Str::contains($this->path(), '?') ? '&' : '?')
: '')
. Arr::query($parameters)
. $this->buildFragment();
}
}
in AppServiceProvider.php or another
public function boot()
{
app()->bind(LengthAwarePaginator::class, CustomLengthAwarePaginator::class);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With