tobento / service-pagination
轻松构建分页控件。
1.0.1
2021-10-31 07:26 UTC
Requires
- php: >=8.0
- tobento/service-menu: ^1.0
Requires (Dev)
- phpunit/phpunit: ^9.5
- tobento/service-view: ^1.0
- vimeo/psalm: ^4.0
README
分页服务提供了一种轻松构建分页控件的方法。
目录
入门
运行以下命令安装分页服务项目的最新版本。
composer require tobento/service-pagination
需求
- PHP 8.0 或更高版本
亮点
- 框架无关,可与任何项目一起使用
- 解耦设计
- 自定义渲染
- 自定义URL生成
截图
简单示例
use Tobento\Service\Pagination\Pagination; $pagination = new Pagination( totalItems: 200, currentPage: 3, );
渲染分页
<?= $pagination->render() ?> // or just <?= $pagination ?>
文档
分页
创建分页
use Tobento\Service\Pagination\Pagination; use Tobento\Service\Pagination\PaginationInterface; use Tobento\Service\Pagination\UrlGenerator; use Tobento\Service\Pagination\MenuRenderer; $pagination = new Pagination( totalItems: 200, currentPage: 3, itemsPerPage: 50, maxPagesToShow: 10, maxItemsPerPage: 1000, urlGenerator: (new UrlGenerator())->addPageUrl('#{num}'), renderer: new MenuRenderer('prev', 'next'), ); var_dump($pagination instanceof PaginationInterface); // bool(true)
使用方法
您可以通过以下“使用方法”更改一些数据或实现,并返回一个新实例。
withCurrentPage
use Tobento\Service\Pagination\Pagination; $pagination = new Pagination(totalItems: 200); $newPagination = $pagination->withCurrentPage(6); var_dump($pagination === $newPagination); // bool(false)
withItemsPerPage
use Tobento\Service\Pagination\Pagination; $pagination = new Pagination(totalItems: 200); $newPagination = $pagination->withItemsPerPage(30); var_dump($pagination === $newPagination); // bool(false)
withMaxPagesToShow
use Tobento\Service\Pagination\Pagination; $pagination = new Pagination(totalItems: 200); $newPagination = $pagination->withMaxPagesToShow(6); var_dump($pagination === $newPagination); // bool(false)
withUrlGenerator
use Tobento\Service\Pagination\Pagination; use Tobento\Service\Pagination\UrlGenerator; $pagination = new Pagination(totalItems: 200); $newPagination = $pagination->withUrlGenerator(new UrlGenerator()); var_dump($pagination === $newPagination); // bool(false)
withRenderer
use Tobento\Service\Pagination\Pagination; use Tobento\Service\Pagination\MenuRenderer; $pagination = new Pagination(totalItems: 200); $newPagination = $pagination->withRenderer(new MenuRenderer()); var_dump($pagination === $newPagination); // bool(false)
分页数据
对于自定义渲染器,您可能需要以下数据,以验证页码或限制查询。
use Tobento\Service\Pagination\Pagination; use Tobento\Service\Pagination\PageInterface; $pagination = new Pagination( totalItems: 200, currentPage: 3, itemsPerPage: 50, maxPagesToShow: 10, ); var_dump($pagination->getTotalItems()); // int(200) var_dump($pagination->getTotalItemsFrom()); // int(101) var_dump($pagination->getTotalItemsTo()); // int(150) var_dump($pagination->getItemsPerPage()); // int(50) var_dump($pagination->getItemsOffset()); // int(100) var_dump($pagination->hasPages()); // bool(true) $pages = $pagination->getPages(); // array<int, PageInterface> $pages = $pagination->getTotalPages(); // int(4) var_dump($pagination->hasPage(num: 5)); // bool(false) var_dump($pagination->hasCurrentPage()); // bool(true) var_dump($pagination->getCurrentPage()); // int(3) var_dump($pagination->getPrevPageUrl()); // string(6) "page/2" var_dump($pagination->getNextPageUrl()); // NULL
当前页验证
建议检查当前页是否存在,特别是如果您从用户输入或基于URL参数设置当前页。
use Tobento\Service\Pagination\Pagination; $pagination = new Pagination( totalItems: 200, currentPage: 12, itemsPerPage: 50, ); if (! $pagination->hasCurrentPage()) { // handle if current page does not exist. // redirect, page not found or whatever fits your application design. $pagination = $pagination->withCurrentPage(1); }
渲染分页
根据您的需求,有多种渲染分页的方法。
菜单渲染器
菜单渲染器是默认的分页渲染器。它使用 菜单服务 生成分页HTML。
use Tobento\Service\Pagination\Pagination; use Tobento\Service\Pagination\MenuRenderer; $pagination = new Pagination( totalItems: 200, currentPage: 3, itemsPerPage: 30, renderer: new MenuRenderer(previousText: 'prev', nextText: 'next'), ); echo $pagination;
输出
<ul class="pagination"> <li><a href="page/2">prev</a></li> <li class="page"><a href="page/1">1</a></li> <li class="page"><a href="page/2">2</a></li> <li class="current"><span>3</span></li> <li class="page"><a href="page/4">4</a></li> <li class="page"><a href="page/5">5</a></li> <li class="page"><a href="page/6">6</a></li> <li class="page"><a href="page/7">7</a></li> <li><a href="page/4">next</a></li> </ul>
自定义渲染器
您可以为您的应用程序编写自己的渲染器。以下示例使用 视图服务 生成分页HTML。
use Tobento\Service\Pagination\Pagination; use Tobento\Service\Pagination\RendererInterface; use Tobento\Service\Pagination\PaginationInterface; use Tobento\Service\View\ViewInterface; use Tobento\Service\View\View; use Tobento\Service\View\PhpRenderer; use Tobento\Service\Dir\Dirs; use Tobento\Service\Dir\Dir; use Tobento\Service\View\Data; use Tobento\Service\View\Assets; $view = new View( new PhpRenderer( new Dirs( new Dir('home/private/views/') ) ), new Data(), new Assets('home/public/src/', 'https://www.example.com/src/') ); class ViewRenderer implements RendererInterface { public function __construct( private ViewInterface $view, private string $viewToRender = 'service/pagination', ) {} public function render(PaginationInterface $pagination): string { return $this->view->render( $this->viewToRender, ['pagination' => $pagination] ); } } $pagination = new Pagination( totalItems: 500, currentPage: 2, renderer: new ViewRenderer($view), ); echo $pagination;
视图模板
<?php if ($pagination->getTotalPages() > 1) { ?> <nav class="pagination"> <ul class="pagination"> <?php if ($pagination->getPrevPageUrl()) { ?> <li><a href="<?= $view->esc($pagination->getPrevPageUrl()) ?>">Previous</a></li> <?php } ?> <?php foreach($pagination->getPages() as $page) { ?> <?php if ($page->url() && ! $page->current()) { ?> <li><a href="<?= $view->esc($page->url()) ?>"><?= $view->esc($page->name()) ?></a></li> <?php } else { ?> <li><span class="<?= $page->current() ? 'current': '' ?>"><?= $view->esc($page->name()) ?></span></li> <?php } ?> <?php } ?> <?php if ($pagination->getNextPageUrl()) { ?> <li><a href="<?= $view->esc($pagination->getNextPageUrl()) ?>">Next</a></li> <?php } ?> </ul> </nav> <?php } ?> <div class="pagination-info"> <p> Showing <?= $view->esc($pagination->getTotalItemsFrom()) ?> - <?= $view->esc($pagination->getTotalItemsTo()) ?> from <?= $view->esc($pagination->getTotalItems()) ?> records. </p> </div>
URL生成
默认URL生成器
use Tobento\Service\Pagination\Pagination; use Tobento\Service\Pagination\UrlGenerator; $urlGenerator = new UrlGenerator(); // url pattern for all pages: $urlGenerator->addPageUrl(url: 'page/{num}', placeholder: '{num}'); // url pattern for page number 1 only: $urlGenerator->addPageUrl(url: 'page', placeholder: null, page: 1); $pagination = new Pagination( totalItems: 500, currentPage: 3, urlGenerator: $urlGenerator, ); echo $pagination;
自定义URL生成器
您可以为您的应用程序设计编写自定义的URL生成器。
use Tobento\Service\Pagination\Pagination; use Tobento\Service\Pagination\UrlGeneratorInterface; class CustomUrlGenerator implements UrlGeneratorInterface { /** * Generate the url for the specified page number. * * @param int $pageNumber * @return string The generated url. */ public function generate(int $pageNumber): string { // generate the url for the specified page number. return ''; } } $pagination = new Pagination( totalItems: 500, currentPage: 3, urlGenerator: new CustomUrlGenerator(), ); echo $pagination;
致谢
一些想法和代码片段取自 Jasongrimes php-paginator。