Laravel 5.5 ЧПУ ссылка в пагинации

Laravel 5.5 ЧПУ ссылка в пагинации

Как я сделал средствами Laravel красивые ссылки при пагинации.

История началась с того, что на просторах русско-язычного интернета я не смог найти рабочую схему создания средствами самого Laravel красивые ссылки при пагинации. В английском не силён, но всё таки с переводчиком кое как смог преодолеть этот казалось бы простой шаг.

Странно, что такая казалось бы актуальная ситуация не реализована в таком мощном фреймворке, как Laravel на более доступном уровне.

Собственно к делу.

Такая была задача: сайт старый, в нем много ссылок такого вида:

http://site/section/russia/page-6.html

Но по умолчанию Laravel прописывает адреса так

http://site/section/russia.html?page=6

что меня не устраивало.

Первое что я сделал - прописал маршрут таким образом

Route::get('/section/{region}/page-{page}.html', 'SiteSectionController@show')

Вроде бы все ок, переменная page есть, но Laravel не подхватывал ее, а использовал свою.

Далее, в контроллере я заменяю стандартную конструкцию пагинатора

->paginate(10);

на вот такую

->paginate(10, ['*'], 'page', $page);

Здесь я явно указываю пагинатору работать с моей пользовательской переменной page вместо его стандартной зашитой глубоко в кишках фреймворка.

Собственно на этом этапе Laravel прекрасно понимает ссылки вида

http://site/section/russia/page-6.html

что мне собственно и нужно было.

Но все равно в конце ссылки он подставляет свои ненавистные мне

?page=6

Что бы исправить это недоразумение я делал вот что. Это чисто мое представление, возможно оно и не стыкуется с философией Laravela, но на данном этапе ничего лучшего я не придумал и не нашел.

Следующий этап, с помощью консоли и вот такой команды

php artisan vendor:publish --tag=laravel-pagination

переместил стандартные шалоны пагинации Laravel в директорию

resources/views/vendor/pagination

Теперь шаблон доступен для свободного редактирования. В папке 4 файла, нужный мне называется

default.blade.php

Привожу мой отредактированный вид шаблона пагинатора, все изменения подчеркнуты

@php
    $pattern = ['~/page-d+.html?page=d+~', '~.html?page=d+~'];
@endphp

@if ($paginator->hasPages())
    <ul class="pagination">

        {{-- Previous Page Link --}}
        @if ($paginator->onFirstPage())
            <li class="disabled"><span>&laquo;</span></li>
        @else
            @if ($paginator->currentPage() == 2)
                <li><a href="{{ preg_replace($pattern, '', $paginator->previousPageUrl()) }}.html" rel="prev">&laquo;</a></li>
            @else
            <li><a href="{{ preg_replace($pattern, '/page-'.($paginator->currentPage()-1), $paginator->previousPageUrl()) }}.html" rel="prev">&laquo;</a></li>
            @endif
        @endif

        {{-- Pagination Elements --}}
        @foreach ($elements as $element)
            {{-- "Three Dots" Separator --}}
            @if (is_string($element))
                <li class="disabled"><span>{{ $element }}</span></li>
            @endif

            {{-- Array Of Links --}}
            @if (is_array($element))
                @foreach ($element as $page => $url)
                    @if ($page == $paginator->currentPage())
                        <li class="active"><span>{{ $page }}</span></li>
                    @else
                        @if ($page == 1)
                            <li><a href="{{ preg_replace($pattern, '', $url) }}.html">{{ $page }}</a></li>
                        @else
                            <li><a href="{{ preg_replace($pattern, '/page-'.$page, $url) }}.html">{{ $page }}</a></li>
                        @endif
                    @endif
                @endforeach
            @endif
        @endforeach

        {{-- Next Page Link --}}
        @if ($paginator->hasMorePages())
            <li><a href="{{ preg_replace($pattern, '/page-'.($paginator->currentPage()+1), $paginator->nextPageUrl()) }}.html" rel="next">&raquo;</a></li>
        @else
            <li class="disabled"><span>&raquo;</span></li>
        @endif
    </ul>
@endif

Если сравнить этот файл с оригиналом легко можно понять суть переделки.

С помощью регулярок я просто вычистил все мне мешающее в ссылках, а со страницы номер 1 удалил page совсем. Здесь ничего сложного, есть только php код, но его одна строка, где простой массив с паттернами. Можно конечно было передать его в параметрах вот таким образом

{{ $posts->links('vendor.pagination.default', ['pattern' => $pattern]) }}

Но я посчитал это несущественным.

Повторюсь, это мой путь, скорее всего он не совсем верный. Возможно есть более элегантное решение, если кто знает поделитесь, буду очень признателен.

А если кому-то поможет, значит не зря пост кропал.

Всем удачи.


Саша Митрахович 10.02.2018 14:32
Загрузка...

Поделиться с друзьями:

Похожие статьи:

Коментарии: (2)

Иван
Иван 27.11.2018 00:39

Костыльненько, но в инете другого варианта не нахожу

Владимир
Владимир 07.02.2021 18:37

Предлагаю просто $url в шаблоне заменить на {{ route(request()->route()->getName(), [«page» => $page]) }} так чтоб было прмерно так
<li class="page-item"><a class="page-link" href="{{ route(request()->route()->getName(), ['page' => $page]) }}">{{ $page }}</a></li>. Вопрос решается без танцев с бубном.

Каптча