SimplePaginator bundle for Symfony2/Doctrine2/Twig
This package contains a bundle to easily paginate complex queries efficiently and without effort.
Dependencies
For the bundle to work properly you should also install DoctrineExtensions\Paginate
.
Bundle and instructions at https://github.com/beberlei/DoctrineExtensions
Installation using composer
Add IdeupSimplePaginatorBundle in your composer.json:
"require": {
"php": ">=5.3.3",
"symfony/symfony": "2.1.*",
.
.
.
.
.
"ideup/simple-paginator-bundle":"*"
}
Now download and install the bundle
$ php composer.phar update ideup/simple-paginator-bundle
Composer will install the bundle to your project's vendor/ideup
directory.
How to include SimplePaginatorBundle in your code
You should clone this repository in your Symfony's vendor/bundles
directory, add it into autoload.php
file:
<?php
$loader->registerNamespaces(array(
'Symfony' => array(__DIR__.'/../vendor/symfony/src', __DIR__.'/../vendor/bundles'),
...
'Ideup' => __DIR__.'/../vendor/bundles',
);
... and in your AppKernel.php
file:
<?php
public function registerBundles()
{
$bundles = array(
...
new Ideup\SimplePaginatorBundle\IdeupSimplePaginatorBundle(),
);
}
... so you are ready now to use IdeupSimplePaginatorBundle as a service.
Since the Paginator::paginate()
method needs a Query
object to work with, you need to change slightly your entity Repository classes:
- Before
<?php
class User extends EntityRepository
{
public function findByMyCriteria() {
$query = $this->_em->createQuery('...');
return $query->getResult();
}
}
- After
<?php
class User extends EntityRepository
{
public function findByMyCriteria() {
return $this->findByMyCriteriaDQL()->getResult();
}
public function findByMyCriteriaDQL() {
$query = $this->_em->createQuery('...');
return $query;
}
}
In your controller you can be able to instantiate the paginator service. SimplePaginatorBundle
is smart enough to
detect the current page and the maximum items per page from the Request
context, so you don't need to type more
boilerplate code!
- Before
<?php
class MyController extends Controller
{
public function listAction() {
$paginator = $this->get('ideup.simple_paginator');
$users = $paginator->paginate($em->getRepository('MyBundle:User')->findByMyCriteriaDQL())->getResult();
$vars = array(
'users' => $users,
'paginator' => $paginator);
return $this->render('MyBundle:User:list.html.twig', $vars);
}
}
Note that the variable $users
contains only the paginated subset of the Doctrine collection and you can query
$paginator
object to obtain information about the pagination process; such as how many items are in the full
collection, in wich page are we, wich is the last page, etc.
- After
<?php
class MyController extends Controller
{
public function listAction() {
$paginator = $this->get('ideup.simple_paginator');
$users = $paginator->paginate($em->getRepository('MyBundle:User')->findByMyCriteriaDQL())->getResult();
$vars = array(
'users' => $users,
);
return $this->render('MyBundle:User:list.html.twig', $vars);
}
}
Note that now you don't need to pass $paginator
variable to template unless you want to obtain information about
pagination process.
How to render a paginator in your view
- Before
<ul id="paginate_elements">
{% if paginator.currentPage > 1 %}
<li><a href="{{ path('my_controller_route', {'page': paginator.previousPage}) }}">previous</a></li>
{% else %}
<li class="left_disabled"><a href="#">previous</a></li>
{% endif %}
{% for page in paginator.minPageInRange..paginator.maxPageInRange %}
{% if page == paginator.currentPage %}
<li><a class="current" href="#">{{ page }}</a></li>
{% else %}
<li><a href="{{ path('my_controller_route', {'page': page}) }}">{{ page }}</a></li>
{% endif %}
{% endfor %}
{% if paginator.currentPage < paginator.lastPage %}
<li class="right"><a href="{{ path('my_controller_route', {'page': paginator.nextPage}) }}">next</a></li>
{% else %}
<li class="right_disabled">next</li>
{% endif %}
</ul>
- After
{{ simple_paginator_render('my_controller_route') }}
You can to customize paginator view as follows:
{{ simple_paginator_render('my_controller_route', null, { params }) }}
where params
may be:
routeParams
, the params needed by the controller route (default:{}
)container_class
, the CSS class applied to the<ul>
element that wraps the paginator (default:simple_paginator
)firstPageText
, the text shown on the first page link (default:first
)firstEnabledClass
, the CSS class applied to the first page link if there is a first page (default:first
)firstDisabledClass
, the CSS class applied to the first page text when there is no first page (default:first_disabled
)previousPageText
, the text shown on the previous page link (default:previous
)previousEnabledClass
, the CSS class applied to the previous page link if there is a previous page (default:left
)previousDisabledClass
, the CSS class applied to the previous page text when there is no previous page (default:left_disabled
)currentClass
, the CSS class applied to the<li>
element that wraps the current page link (default:current
)nextPageText
, the text shown on the next page link (default:next
)nextEnabledClass
, the CSS class applied to the next page link if there is a next page (default:right
)nextDisabledClass
, the CSS class applied to the next page text when there is no next page (default:right_disabled
)lastPageText
, the text shown on the last page link (default:last
)lastEnabledClass
, the CSS class applied to the last page link if there is a last page (default:last
)lastDisabledClass
, the CSS class applied to the last page text when there is no last page (default:last_disabled
)
For example, if you want to customize paginator view to show a route that receive a
parameter id
and you want to change container class:
{{ simple_paginator_render('my_controller_route', null, {
'routeParams' : {'id' : id},
'container_class' : 'custom_simple_paginator_class'
})
}}
If your needs are out of this sight you can customize it in your own view:
{{ simple_paginator_render('my_controller_route', null, {....}, 'MyBundle:MyViewFolder:MyViewFile.html.twig') }}
To create MyBundle:MyViewFolder:MyViewFile.html.twig
copy from default template that is included inside the bundle
Resources\views\Paginator\simple-paginator-list-view.html.twig
and customize it in your own Bundle.
For example, if you want only to show paginator numbers, your template sounds like this
MyBundle\Resources\views\MyViewFolder\MyViewFile.html.twig
:
<ul class="{{ container_class }}">
<!-- NUMBERS -->
{% for page in minPage..maxPage %}
{% if page == currentPage %}
<li class="{{ currentClass }}">
{{ page }}
</li>
{% else %}
{% set rParams = {'page': page, 'paginatorId': id} | merge(routeParams) %}
<li>
<a href="{{ path(route, rParams) }}">{{ page }}</a>
</li>
{% endif %}
{% endfor %}
</ul>
How to include more than one paginator in a single view
SimplePaginatorBundle
supports multiple paginators, you should specify an id in your controller and view calls. Note
that you can modify the particular properties of each paginator.
- Before
<?php
class MyController extends Controller
{
public function listAction() {
$paginator = $this->get('ideup.simple_paginator');
$paginator->setItemsPerPage(25, 'users');
$users = $paginator->paginate($em->getRepository('MyBundle:User')->findByMyCriteriaDQL(), 'users')->getResult();
$paginator->setItemsPerPage(5, 'groups');
$groups = $paginator->paginate($em->getRepository('MyBundle:User')->findByMyCriteriaDQL(), 'groups')->getResult();
$vars = array(
'users' => $users,
'groups' => $groups,
'paginator' => $paginator);
return $this->render('MyBundle:User:list.html.twig', $vars);
}
}
In the view you also need to specify the paginator id:
<ul id="paginate_elements">
{% if paginator.currentPage('users') > 1 %}
<li><a href="{{ path('my_controller_route', {'page': paginator.previousPage('users'), 'paginatorId': 'users'}) }}">previous</a></li>
{% else %}
<li class="left_disabled"><a href="#">previous</a></li>
{% endif %}
{% for page in paginator.minPageInRange('users')..paginator.maxPageInRange('users') %}
{% if page == paginator.currentPage('users') %}
<li><a class="current" href="#">{{ page }}</a></li>
{% else %}
<li><a href="{{ path('my_controller_route', {'page': page, 'paginatorId': 'users'}) }}">{{ page }}</a></li>
{% endif %}
{% endfor %}
{% if paginator.currentPage('users') < paginator.lastPage('users') %}
<li class="right"><a href="{{ path('my_controller_route', {'page': paginator.nextPage('users'), 'paginatorId': 'users'}) }}">next</a></li>
{% else %}
<li class="right_disabled">next</li>
{% endif %}
</ul>
- After
<?php
class MyController extends Controller
{
public function listAction() {
$paginator = $this->get('ideup.simple_paginator');
$users = $paginator
->setItemsPerPage(25, 'users');
->paginate($em->getRepository('MyBundle:User')->findByMyCriteriaDQL(), 'users')
->getResult()
;
// Now also we can paginate arrays
$allGroups = array('group1', 'group2', 'group3', 'group4', 'group5');
$groups = $paginator
->setItemsPerPage(3, 'groups')
->paginate($allGroups, 'groups')
->getResult()
;
$vars = array(
'users' => $users,
'groups' => $groups,
);
return $this->render('MyBundle:User:list.html.twig', $vars);
}
}
In the view you also need to specify the paginator id:
{{ simple_paginator_render('my_controller_route', 'users', {....}) }}
{{ simple_paginator_render('my_controller_route', 'groups', {....}) }}
Changelog
v0.91
Added support to paginate arrays.
Changed setter methods. Now this methods return paginate object.
Added twig support.
v0.9
Added dependency to DoctrineExtensions\Paginate to handle proper pagination (see https://github.com/beberlei/DoctrineExtensions)
Added support to paginate multiple lists at once
Changed the Paginador class name to Paginator, this is how services.xml defines our service, with a parameter set to the class implementing pagination and passing a service id
<parameters>
<parameter key="simple_paginador.class">Ideup\SimplePaginatorBundle\Paginator\Paginator</parameter>
</parameters>
<services>
<service id="ideup.simple_paginator" class="%simple_paginator.class%">
<argument type="service" id="request" strict="false" />
</service>
</services>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-
Merge pull request #30 from criscosg/master
By javiacei, 5 years ago
-
Merge pull request #1 from criscosg/criscosg-doc-extension-0.3.0
By criscosg, 5 years ago
-
Update composer.json
By criscosg, 5 years ago
-
Update README.md
By javiacei, 7 years ago
-
Merge pull request #27 from sethunath/master
By javiacei, 7 years ago
-
Merge pull request #28 from criscosg/master
By javiacei, 7 years ago
-
Update QueryAdapter.php
By criscosg, 7 years ago
-
installation instructions
By sethunath, 8 years ago
-
Update README.md
By sethunath, 8 years ago
-
Doctrine extension dependency bug FIXED (dev-master)
By Fco Javier Aceituno Lapido, 8 years ago
-
Update composer.json
By javiacei, 8 years ago
-
Changed berberlei/DoctrineExtensions branch name (dev-)
By javiacei, 8 years ago
-
Merge pull request #26 from nass600/master
By javiacei, 8 years ago
-
Fixed bug in ArrayCollections
By nass600, 8 years ago
-
Merge pull request #25 from nass600/master
By javiacei, 8 years ago
-
Added native support for Doctrine\Common\Collections\ArrayCollection
By nass600, 8 years ago
-
Update composer.json
By javiacei, 8 years ago
-
Merge pull request #24 from phansys/master
By javiacei, 8 years ago
-
Added composer.json
By phansys, 8 years ago
-
Merge pull request #22 from tolbier/master
By javiacei, 8 years ago
-
Added getStartPageItem & getEndPageItem
By tolbier, 8 years ago
-
Merge pull request #19 from tolbier/master
By javiacei, 8 years ago
-
Corregido error en Paginator.getCurrentPage, que no pasa a getLastPage
By tolbier, 8 years ago
-
Bug fixed when no items (<-- 1 | 0 -->)
By javiacei, 8 years ago
-
Merge pull request #18 from jcromero70/master
By mmacia, 8 years ago
-
Comprobar que $this->currentPage no sea mayor de $this->getLastPage()
By Juan Carlos Romero, 8 years ago
-
Merge pull request #17 from egulias/master
By Moisés Maciá, 9 years ago
-
#14 - Removed TODO's to Issues (#15 & #16)
By egulias, 9 years ago
-
#13 - Added pagination dependencies in installation instructions
By egulias, 9 years ago
-
Update LICENSE
By javiacei, 9 years ago