pshitote's avatar

How can I use custom length aware paginator to modify posts->links() in my view blade?

I have an index page with {{ $posts->links() }} by default that renders navigation page links in my view template. My controller looks like this:

public function index(){ return view('postcards.index', [ 'posts' => Postcard::paginate(20) ]); }

What this does is that it renders navigation links in my view template such that when I click on 1, my url changes to http://localhost/?page=1. When I click on 2 I get http://localhost/?page=2.

I want to customize my laravel application using customlengthawarepaginator so that when I click on 1 I get http://localhost without page =1.

When I click on 2 in the navigation links I get http://localhost?page=2.

Links to page 1 used in the pagination and link prev and next tags should never include page=1 as a parameter. The expected approach to handling this is to implement a custom length aware paginator that will provide a custom URL if the previous link is to page 1.

0 likes
8 replies
Snapey's avatar

From the post I linked you to earlier, which you ignored

create 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();
    }
}

Then use this new paginator, inside the boot method of AppServiceProvider

public function boot()
{
    app()->bind(LengthAwarePaginator::class, CustomLengthAwarePaginator::class);
}

Credit: https://stackoverflow.com/a/64442451

pshitote's avatar

@Snapey Thanks, I tried this method, but I am getting a 500 server error.

Snapey's avatar

@pshitote For which you can look in the logs and tell us the exact error message.

/storage/logs/laravel.log

pshitote's avatar

@Snapey thanks, the above solution worked. I only had to change ``` public function boot() { app()->bind(LengthAwarePaginator::class, CustomLengthAwarePaginator::class); }

public function register(): void { $this->app->bind(LengthAwarePaginator::class, CustomLengthAwarePaginator::class); }

pshitote's avatar

@Snapey It's OK thanks. I was just highlighting that the binding is being done under register() function not boot(). All the same great thanks for your help.

Please or to participate in this conversation.