首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

Laravel Pagination 分頁元件擴展:自訂「上一頁/下一頁」與簡易分頁樣式

     編輯:PHP 綜合知識

Laravel 內建的 LengthAwarePaginator 與 Paginator 透過 Presenter 模式渲染分頁 HTML,預設輸出 Bootstrap 3 風格。本文示範如何建立自訂 Presenter 類別,分別擴展 paginate()(完整分頁)與 simplePaginate()(簡易上一頁/下一頁)樣式,並說明在 Blade 模板中套用方式。

核心原理:Presenter Contract

Laravel 透過 Illuminate\Contracts\Pagination\Presenter 介面定義渲染規約:

interface Presenter {
    public function render();      // 輸出 HTML
    public function hasPages();    // 是否有分頁
}

LengthAwarePaginator::render() 內部實例化 BootstrapThreePresenter,我們只需實作自己的 Presenter 即可替換輸出樣式。

一、自訂完整分頁 Presenter(顯示頁碼 + 上一頁/下一頁)

建立 app/Foundations/Pagination/CustomerPresenter.php:

<?php
namespace App\Foundations\Pagination;

use Illuminate\Contracts\Pagination\Presenter as PresenterContract;
use Illuminate\Contracts\Pagination\LengthAwarePaginator as PaginatorContract;
use Illuminate\Pagination\UrlWindow;
use Illuminate\Support\HtmlString;
use Illuminate\Pagination\BootstrapThreeNextPreviousButtonRendererTrait;
use Illuminate\Pagination\UrlWindowPresenterTrait;

class CustomerPresenter implements PresenterContract {
    use BootstrapThreeNextPreviousButtonRendererTrait, UrlWindowPresenterTrait;

    protected $paginator;
    protected $window;

    public function __construct(PaginatorContract $paginator, UrlWindow $window = null) {
        $this->paginator = $paginator;
        $this->window = is_null($window) ? UrlWindow::make($paginator) : $window->get();
    }

    public function hasPages() {
        return $this->paginator->hasPages();
    }

    public function render() {
        if ($this->hasPages()) {
            return new HtmlString(sprintf(
                '<ul class="pagination">%s %s %s</ul>',
                $this->getPreviousButton('上一頁'),  // 自訂文字
                $this->getLinks(),                    // 頁碼連結
                $this->getNextButton('下一頁')        // 自訂文字
            ));
        }
        return '';
    }

    // 以下方法可視需求覆寫 HTML 結構
    protected function getAvailablePageWrapper($url, $page, $rel = null) {
        $rel = is_null($rel) ? '' : ' rel="' . $rel . '"';
        return '<li><a href="' . htmlentities($url) . '"' . $rel . '>' . $page . '</a></li>';
    }
    protected function getDisabledTextWrapper($text) {
        return '<li class="disabled hide"><span>' . $text . '</span></li>';
    }
    protected function getActivePageWrapper($text) {
        return '<li class="active"><span>' . $text . '</span></li>';
    }
    protected function getDots() {
        return $this->getDisabledTextWrapper('...');
    }
    protected function currentPage() { return $this->paginator->currentPage(); }
    protected function lastPage() { return $this->paginator->lastPage(); }
}

Blade 模板套用

{!! with(new \App\Foundations\Pagination\CustomerPresenter($categories))->render() !!}

二、自訂簡易分頁 Presenter(僅上一篇/下一篇)

繼承上述 Presenter,覆寫 render() 與 hasPages():

<?php
namespace App\Foundations\Pagination;

use Illuminate\Support\HtmlString;
use Illuminate\Contracts\Pagination\Paginator as PaginatorContract;

class CustomerSimplePresenter extends CustomerPresenter {
    public function __construct(PaginatorContract $paginator) {
        $this->paginator = $paginator;
    }

    public function hasPages() {
        return $this->paginator->hasPages() && count($this->paginator->items()) > 0;
    }

    public function render() {
        if ($this->hasPages()) {
            return new HtmlString(sprintf(
                '<ul class="pager">%s %s</ul>',
                $this->getPreviousButton('上一篇'),
                $this->getNextButton('下一篇')
            ));
        }
        return '';
    }
}

Blade 套用

{!! with(new \App\Foundations\Pagination\CustomerSimplePresenter($categories))->render() !!}

三、進階擴展建議

  • 跳頁輸入框:在 render() 中加入 <input type="number"> 並綁定 JS 跳轉。
  • 顯示總筆數/當前範圍:呼叫 $this->paginator->total(), firstItem(), lastItem()。
  • 語系化:將「上一頁」等文字改用 __('pagination.previous') 透過語系檔管理。
  • Tailwind/UIKit 等框架:調整 ul class 與按鈕結構即可。

四、原理回顧

  1. paginate() 回傳 LengthAwarePaginator,需實作 LengthAwarePaginatorContract。
  2. simplePaginate() 回傳 Paginator,需實作 PaginatorContract。
  3. 兩者皆透過 render(Presenter $presenter) 委派輸出,預設用 BootstrapThreePresenter。
  4. 自訂 Presenter 只需實作 PresenterContract 兩個方法,極度彈性。

小結

掌握 Presenter 模式後,Laravel 分頁樣式客製化變得直觀且可維護。建立專屬 Presenter 類別、覆寫 render() 輸出所需 HTML,即可滿足任何設計需求,無需修改核心檔案,完美符合 SOLID 原則。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved