Customizing Laravel Pagination for Pseudo‑Static URLs

This guide explains how to override Laravel's built‑in pagination component to generate clean pseudo‑static URLs by creating a custom LengthAwarePaginator, rewriting its url method, and providing a staticPaginate scope for selective use.

php Courses
php Courses
php Courses
Customizing Laravel Pagination for Pseudo‑Static URLs

In a Laravel project the built‑in pagination component generates URLs with query parameters, which does not satisfy the requirement for pseudo‑static URLs such as /software/3dmax/created_at/page-1.html.

The desired routing pattern is /software/{category}/{order}/page-{page}.html, but the default paginator produces URLs like

/software/3dmax/created_at/page-1.html?category=3dmax&order=created_at&page=2

.

To achieve the required format we need to override the Laravel paginator. First create a custom paginator class that extends Illuminate\Pagination\LengthAwarePaginator:

mkdir app/Pagination
touch app/Pagination/LengthAwarePaginator.php

File app/Pagination/LengthAwarePaginator.php:

<?php

namespace App\Pagination;

use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\Pagination\LengthAwarePaginator as BasePaginator;

class LengthAwarePaginator extends BasePaginator
{
}

Then rewrite the url method to move route parameters from the query string into the path while preserving other query parameters:

public function url($page)
{
    if ($page <= 0) {
        $page = 1;
    }

    $parameters = [$this->pageName => $page];

    if (count($this->query) > 0) {
        $parameters = array_merge($this->query, $parameters);
    }

    // parameters bound to the route
    $params = \request()->route()->parameters();

    if (!empty($params)) {
        foreach ($parameters as $key => $parameter) {
            if (isset($params[$key])) {
                $params[$key] = $parameter;
                unset($parameters[$key]);
            }
        }

        $path = route(\request()->route()->getAction('as'), $params);
    } else {
        $path = $this->path;
    }

    // if no remaining query parameters
    if (empty(Arr::query($parameters))) {
        return $path . $this->buildFragment();
    }

    return $path
        . (Str::contains($this->path, '?') ? '&' : '?')
        . Arr::query($parameters)
        . $this->buildFragment();
}

Next, replace the default paginator with the custom one in the application’s service container:

# replace
use App\Pagination\LengthAwarePaginator;
# --- use  Illuminate\Contracts\Pagination\LengthAwarePaginator;  // commented

...

/**
 * @param \Illuminate\Support\Collection $items
 * @param int $total
 * @param int $perPage
 * @param int $currentPage
 * @param array $options
 * @return LengthAwarePaginator
 */
protected function paginator($items, $total, $perPage, $currentPage, $options)
{
    return Container::getInstance()->makeWith(LengthAwarePaginator::class, compact(
        'items', 'total', 'perPage', 'currentPage', 'options'
    ));
}

For cases where only some pages need pseudo‑static URLs, define a local scope staticPaginate in a base model class:

public function scopeStaticPaginate($builder, $perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
{
    if (request('page')) {
        request()->offsetSet('page', request('page'));
    }

    $page = $page ?: Paginator::resolveCurrentPage($pageName);
    $perPage = $perPage ?: $builder->getModel()->getPerPage();

    $results = ($total = $builder->toBase()->getCountForPagination())
        ? $builder->forPage($page, $perPage)->get($columns)
        : $builder->getModel()->newCollection();

    return $this->paginator($results, $total, $perPage, $page, [
        'path' => Paginator::resolveCurrentPath(),
        'pageName' => $pageName,
    ]);
}

Finally, use the custom paginator in code:

Model::query()->staticPaginate($pageSize);

By following these steps the Laravel application will generate clean pseudo‑static pagination URLs while still supporting normal query‑based pagination where needed.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendpaginationPHPcustom-componentLaravelPseudo-Static
php Courses
Written by

php Courses

php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.