Еще во времена laravel 3 поступило мне задание от очередного оптимизатора, которое заключалось в следующем: 1. Постраничный вывод должен генерировать ссылки вида %%(t)/news/page2%%, %%(t)/news/page3%% и тд 2. Страницы %%(t)/news/page1%% не должно быть вообще, должно быть просто %%(t)/news%% 3. В %%(t)title%% нужно добавить номер страницы как-то так: "оригинальный тайтл" - страница "номер страницы" 4. Автоматическая генерация %%(t)link rel="canonical"%% для страниц с номером, добавление %%(t)link rel="prev"%% и %%(t)link rel="next"%% Посмотрев исходники я понял что проще написать свой FPagination. F - потому что --fucking-- friendly. Надежный как автомат Калашникова и простой как сатиновые трусы. {{cut Собственно код:}} %% items = $items; $this->currentPage = $currentPage; $this->lastPage = $lastPage; $this->pageName = $pageName; $this->url = $url; } public function links() { if($this->lastPage > 1) { if($this->lastPage < 13) { $content = $this->getPageRange(1, $this->lastPage); } else { $content = $this->getPageSlider(); } $pagination = ''; } else { $pagination = ''; } return $pagination; } public function getPageRange($start, $end) { $pages = ''; for($page = $start; $page <= $end; $page++) { if($this->currentPage == $page) { $pages .= $this->getActivePageWrapper($page); } else if($page == 1) { $pages .= $this->getBase($page); } else { $pages .= $this->getLink($page); } } return $pages; } public function getActivePageWrapper($text) { return ''.$text.''; } public function getBase($page) { $link = ''.$page.''; return $this->getPageLinkWrapper($link); } public function getPageLinkWrapper($link) { return '
  • '.$link.'
  • '; } public function getLink($page) { $link = ''.$page.''; return $this->getPageLinkWrapper($link); } protected function getPageSlider() { $window = 6; if($this->currentPage <= $window) { $content = $this->getPageRange(1, $window + 2).$this->getFinish(); } else if($this->currentPage >= $this->lastPage - $window) { $start = $this->lastPage - 8; $content = $this->getStart().$this->getPageRange($start, $this->lastPage); } else { $content = $this->getStart().$this->getAdjacentRange().$this->getFinish(); } return $content; } public function getFinish() { return $this->getDots().$this->getPageRange($this->lastPage - 1, $this->lastPage); } public function getDots() { return '
  • ...
  • '; } public function getStart() { return $this->getPageRange(1, 2).$this->getDots(); } public function getAdjacentRange() { return $this->getPageRange($this->currentPage - 3, $this->currentPage + 3); } public function getPreviousTouch($text = '« Предыдущая') { if($this->currentPage <= 1) { $link = ''.$text.''; } else { $link = ''.$text.''; } return $link; } public function prevUrl() { if($this->currentPage <= 2) { $url = $this->url; } else { $url = $this->url.'/'.$this->pageName.($this->currentPage - 1); } return $url; } public function getNextTouch($text = 'Следующая »') { if($this->currentPage >= $this->lastPage) { $link = ''.$text.''; } else { $link = ''.$text.''; } return $link; } public function nextUrl() { return $this->url.'/'.$this->pageName.($this->currentPage + 1); } public function getPrevious($text = '«') { if($this->currentPage <= 1) { return $this->getDisabledTextWrapper($text); } else { $link = ''.$text.''; } return $this->getPageLinkWrapper($link); } public function getDisabledTextWrapper($text) { return ''; } public function getNext($text = '»') { if($this->currentPage >= $this->lastPage) { return $this->getDisabledTextWrapper($text); } $link = ''.$text.''; return $this->getPageLinkWrapper($link); } public function getTitleAppend($text) { if($this->currentPage > 1) { $title = $text.' - страница '.$this->currentPage; } else { $title = $text; } return $title; } public function getSeoBlock() { $canonical = ''; $prev = ''; $next = ''; if($this->currentPage <= 1) { $content = $next; } else if($this->currentPage > 1 && $this->currentPage < $this->lastPage) { $content = $canonical.$prev.$next; } else { $content = $canonical.$prev; } return $content; } } %% Данная реализация заточена под ((http://bulma.io/ Bulma framework)) но поменять классы на верстку Bootstrap или любую другую не сложно. Как этим чудом пользоваться в Laravel? Я делаю так: Создаю функцию помощника, даже две %% //resources/helpers.php count(); $lastPage = ceil($total / $perPage); if($currentPage > $lastPage) { abort(404); } else { $items = $sql->skip(($currentPage * $perPage) - $perPage) ->take($perPage) ->get(); $routeParameters = array_values(\Route::current() ->parameters()); $count = count($routeParameters); if($count >= 1) { if(starts_with($routeParameters[$count - 1], $pageName)) { unset($routeParameters[$count - 1]); } } $url = action($action, $routeParameters); return new \App\Classes\FPagination($items, $currentPage, $lastPage, $perPage, $pageName, $url); } } %% Еще нужно добавить scope в модель. Можно сделать глобальный, но я предпочитаю локальные, на случай дополнительных доработок. Можно и без него, это скорее для красоты. %% news = \App\Models\News::pagination($currentPage, 30); return $view; } } %% Если метод контроллера принимает больше одного параметра, $currentPage = null должен быть последним. В представлении 'news/index' %% @extends('base/page') @section('meta') {{ $users->getSeoBlock() }} @endsection @section('title') {{ $users->getTitleAppend('Новости') }} @endsection @section('content') @foreach($news->items as $item) @endforeach {{ $news->links() }} @endsection %% Данный класс удобно тягать с собой из проекта в проект, довольно просто настраивается под любую верстку, если почесать репу можно прикрутить и к другим фреймворкам или формировать им постраничный вывод для массивов\коллекций. --Composter-- Composer пакет собирать лениво, мне проще так - как в старое доброе время. Навеяно ((768 этим)).