ashleydawson/simple-pagination-bundle

Symfony 扩展包,用于 Simple Pagination,这是一个简单、轻量级且通用的分页器,可以在事物集合上实现分页

5.0.0 2020-06-04 08:51 UTC

This package is auto-updated.

Last update: 2024-09-04 17:37:09 UTC


README

Build Status

感谢 BrowserStack 对此类开源项目的大力支持。

Symfony 扩展包,用于 Simple Pagination 库。

安装

您可以通过 Composer 安装 Simple Pagination 扩展包。只需简单地在 require 包中

$ composer req ashleydawson/simple-pagination-bundle

运行 composer update 以安装包。然后您需要在 app/AppKernel.php 中注册扩展包

$bundles = array(
    // ...
    new AshleyDawson\SimplePaginationBundle\AshleyDawsonSimplePaginationBundle(),
);

基本用法

我们可以使用分页服务器的最简单集合是一个数组。以下是一个使用数组分页器服务的极其简单的示例。这展示了服务对12个项目的分页。

namespace Acme\DemoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class WelcomeController extends Controller
{
    public function indexAction()
    {
        // Get the paginator service from the container
        $paginator = $this->get('ashley_dawson_simple_pagination.paginator');

        // Build a mock set of items to paginate over
        $items = array(
            'Banana',
            'Apple',
            'Cherry',
            'Lemon',
            'Pear',
            'Watermelon',
            'Orange',
            'Grapefruit',
            'Blackcurrant',
            'Dingleberry',
            'Snosberry',
            'Tomato',
        );

        // Set the item total callback, simply returning the total number of items
        $paginator->setItemTotalCallback(function () use ($items) {
            return count($items);
        });

        // Add the slice callback, simply slicing the items array using $offset and $length
        $paginator->setSliceCallback(function ($offset, $length) use ($items) {
            return array_slice($items, $offset, $length);
        });

        // Perform the pagination, passing the current page number from the request
        $pagination = $paginator->paginate((int)$this->get('request')->query->get('page', 1));

        // Pass the pagination object to the view for rendering
        return $this->render('AcmeDemoBundle:Welcome:index.html.twig', array(
            'pagination' => $pagination,
        ));
    }
}

在 twig 视图中,它看起来像这样

...

{# Iterate over items for the current page, rendering each one #}
<ul>
    {% for item in pagination.items %}
        <li>{{ item }}</li>
    {% endfor %}
</ul>

{# Iterate over the page list, rendering the page links #}
<div>
    {% for page in pagination.pages %}
        <a href="?page={{ page }}">{{ page }}</a> |
    {% endfor %}
</div>

...

您可以通过向分页器传递值来在运行时覆盖“每页项目数”和“页面范围”选项,如下所示

// ...

$paginator
    ->setItemsPerPage(20)
    ->setPagesInRange(5)
;

$pagination = $paginator->paginate((int)$this->get('request')->query->get('page', 1));

// ...

请注意,这是一个 非常简单的示例,一些高级用例和接口将很快出现(见下文)。

Doctrine 示例

我已经将上面的示例扩展到使用 Doctrine 而不是静态项目数组

namespace Acme\DemoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class WelcomeController extends Controller
{
    public function indexAction()
    {
        // Get the paginator service from the container
        $paginator = $this->get('ashley_dawson_simple_pagination.paginator');

        // Create a Doctrine query builder
        $manager = $this->getDoctrine()->getManager();
        $query = $manager->createQueryBuilder();

        // Build the initial query, including any special filters
        $query
            ->from('AcmeDemoBundle:Film', 'f')
            ->where('f.releaseAt > :threshold')
            ->setParameter('threshold', new \DateTime('1980-08-16'))
        ;

        // Pass the item total callback
        $paginator->setItemTotalCallback(function () use ($query) {

            // Run the count of all records
            $query
                ->select('COUNT(f.id)')
            ;

            // Return the total item count
            return (int)$query->getQuery()->getSingleScalarResult();
        });

        // Pass the slice callback
        $paginator->setSliceCallback(function ($offset, $length) use ($query) {

            // Select and slice the data
            $query
                ->select('f')
                ->setFirstResult($offset)
                ->setMaxResults($length)
            ;

            // Return the collection
            return $query->getQuery()->getResult();
        });

        // Finally, paginate using the current page number
        $pagination = $paginator->paginate((int)$this->get('request')->query->get('page', 1));

        // Pass the pagination object to the view
        return $this->render('AcmeDemoBundle:Welcome:index.html.twig', array(
            'pagination' => $pagination,
        ));
    }
}

在 twig 视图中,它看起来像这样

...

{# Iterate over films (Doctrine results) for the current page, rendering each one #}
<ul>
    {% for film in pagination.items %}
        <li>
            <strong>{{ film.title }}</strong>
            <time>{{ film.releaseAt | date('jS F, Y') }}</time>
        </li>
    {% endfor %}
</ul>

{# Use the pagination view helper to render the page navigation #}
<div>
    {{ simple_pagination_render(
        pagination,
        '_welcome',
        'page',
        app.request.query.all
    ) }}
</div>

...

配置

您可以通过 app/config/config.yml 配置 Simple Pager 扩展包的以下 可选 参数

ashley_dawson_simple_pagination:
    defaults:
        items_per_page: 10
        pages_in_range: 5
        template: AshleyDawsonSimplePaginationBundle:Pagination:default.html.twig

Twig 函数

我提供了一个方便的 twig 函数来渲染内置的分页模板。默认模板可以在您的 app/config/config.yml 中配置,或者简单地作为参数在 twig 函数中重写。

传递给 twig 函数的参数如下

simple_pagination_render(pagination : Pagination, routeName : string, [pageParameterName : string = 'page'], [queryParameters : array = array()], [template : string | null = null])

每个参数的简要说明如下

  • pagination: 由 AshleyDawson\SimplePagination\Paginator::paginate() 返回的 AshleyDawson\SimplePagination\Pagination 对象
  • routeName: 传递给导航 {{ path() }} 函数的路由名称,在您的路由配置中定义
  • pageParameterName: 请求中页面数字参数的名称(可选)
  • queryParameters: 要附加到路径的查询参数数组(可选)
  • template: 您想要用来覆盖默认模板的模板(可选)

以下是一个详尽的 twig 视图示例

<div>
    {{ simple_pagination_render(
        pagination,
        '_welcome',
        'page',
        app.request.query.all,
        'AcmeBundle:Default:pagination.html.twig'
    ) }}
</div>

更好的示例,附带项目列表

<div>
    <ul>
        {% for item in pagination.items %}
            <li>{{ item }}</li>
        {% endfor %}
    </ul>
</div>

<div>
    {{ simple_pagination_render(pagination, 'my_route_name', 'page', app.request.query.all) }}
</div>

自定义服务

如果您想将分页器定义为自定义服务,请使用以下服务容器配置。

在 YAML 中

services:

  my_paginator:
    class: AshleyDawson\SimplePagination\Paginator
    calls:
      - [ setItemsPerPage, [ 10 ] ]
      - [ setPagesInRange, [ 5 ] ]

或者在 XML 中

<services>
    <service id="my_paginator" class="AshleyDawson\SimplePagination\Paginator">
        <call method="setItemsPerPage">
            <argument>10</argument>
        </call>
        <call method="setPagesInRange">
            <argument>5</argument>
        </call>
    </service>
</services>

然后像这样在控制器中使用它

// Get my paginator service from the container
$paginator = $this->get('my_paginator');

// ...