Pagerfanta Pagination
To handle pagination, we're going to install the WhiteOctoberPagerfantaBundle.
To install the bundle, run:
Pagerfanta is a great library for pagination, whether you're doing things on the web
or building an API. While we're waiting, enable the bundle in AppKernel:
And that…
Pagination with Pagerfanta
…click "Installation".
Copy the "composer require" line, spin over to your terminal and get it:
composer require "babdev/pagerfanta-bundle:^3.6"
Let's see what that did:
git status
Ok: nothing too interesting... though it did automatically enable the new bundle.
The controller for…
Themed Pagination Links
Pagerfanta is now controlling the query for this page and returning only the
first 5 results. So... how do we get to page 2? How can we render some pagination
links?
Pagerfanta makes this delightfully easy. Scroll down. After the endfor, render
the pagination links…
Pagination & Column Sorting
…of these doesn't matter:
Below, copy the $voyageRepository->findBySearch() line, and replace it with a Pager
object: $pager equals Pagerfanta::createForCurrentPageWithMaxPerPage():
The first argument is an adapter: new QueryAdapter then paste in the code from
before. But, that's not quite right: this method…
Pagination
…gives us unlimited power to customize. But Pagerfanta
does that can generate this for us. If you want to see how, check out the Pagerfanta docs.
The downside is that customizing the HTML is a bit more difficult.
Next, let's add more fields to…
Upgrading to Symfony 7
…babdev/pagerfanta-bundle. Apparently, it works with
Symfony 4, 5 and 6, but not 7.
There's a good chance that I probably need to upgrade this to a new version that
does support Symfony 7. Run:
composer outdated
Sure enough: there are three pagerfanta…
Pagination
…Instead
of querying for all of the mixes, like we're doing now, we're going to tell the
Pagerfanta library which page the user is currently on, how many results to show
per page, and then it will query for the correct results for…
Reusable Pagination System
…the links and any $routeParams it needs:
Go back to ProgrammerController, copy the logic, remove it and put it into PaginationFactory.
Add the missing use statements: by auto-completing the classes DoctrineORMAdapter
and Pagerfanta. Now, delete $route and $routeParams since those are passed as
arguments…
Mapping Assets
…on top, it shows the AssetMapper paths, including the assets/
directory. This project also has Pagerfanta installed. And we're already seeing
how bundles can add their own AssetMapper paths to make their own files
available publicly. This won't be important for us, but…
Upgrading to Symfony 6.0
…One of the libraries I'm using is
babdev/pagerfanta-bundle... and apparently it requires PHP 7.2... but we're using
PHP 8. If you look further, there are some errors about
pagerfanta-bundle[v2.8.0] requiring symfony/config ^3.4 || ^4…
Filtering / Searching
…But the
idea is the same: prepare some search for Elastic, then use an Elastic Search adapter
with Pagerfanta.
And that's all there is to it! Re-run the test:
Oooh a 500 error: let's see what we're doing wrong:
Parse error…
Pagination Links
…last page: $pagerfanta->getNbPages():
The last two links are next and previous... but wait! We don't always have
a next or previous page: these should be conditional. Add: if($pagerfanta->hasNextPage()),
well, then, of course we want to generate a link to $pagerfanta->getNextPage(…
Forever Scroll with Turbo Frames
…unique to the current page. Add a -, and then we can
say pager.currentPage.
Next, down at the bottom, remove the Pagerfanta links and replace them with another
Turbo Frame. Say {% if pager.hasNextPage %}, and inside of it, add a
turbo-frame, just like above…
API Pagination Done Easily
…us the ones we want. I'm just trying to keep
things simple.
If I were doing this in a real project, I'd probably use a library called
Pagerfanta. It helps you paginate
and has built-in adapters already for Doctrine, and Elastic Search…
|
babdev_pagerfanta: |
|
default_view: twig |
|
default_twig_template: '@BabDevPagerfanta/twitter_bootstrap5.html.twig' |
See Code Block in Script
|
|
// ... lines 1 - 7
|
|
use Pagerfanta\Pagerfanta; |
|
|
// ... lines 9 - 14
|
|
class MainController extends AbstractController |
|
{ |
|
|
// ... line 17
|
|
public function homepage( |
|
|
// ... lines 19 - 23
|
|
): Response |
|
{ |
|
$pager = Pagerfanta::createForCurrentPageWithMaxPerPage( |
|
|
// ... lines 27 - 29
|
|
); |
|
|
// ... lines 31 - 36
|
|
} |
|
} |
See Code Block in Script
|
|
// ... lines 1 - 6
|
|
use Pagerfanta\Doctrine\ORM\QueryAdapter; |
|
|
// ... lines 8 - 14
|
|
class MainController extends AbstractController |
|
{ |
|
|
// ... line 17
|
|
public function homepage( |
|
|
// ... lines 19 - 23
|
|
): Response |
|
{ |
|
$pager = Pagerfanta::createForCurrentPageWithMaxPerPage( |
|
new QueryAdapter($voyageRepository->findBySearchQueryBuilder($query, $searchPlanets)), |
|
$page, |
|
10 |
|
); |
|
|
// ... lines 31 - 36
|
|
} |
|
} |
See Code Block in Script
|
|
// ... lines 1 - 5
|
|
use Pagerfanta\Doctrine\ORM\QueryAdapter; |
|
use Pagerfanta\Pagerfanta; |
|
|
// ... lines 8 - 12
|
|
class VinylController extends AbstractController |
|
{ |
|
|
// ... lines 15 - 38
|
|
public function browse(VinylMixRepository $mixRepository, string $slug = null): Response |
|
{ |
|
|
// ... lines 41 - 43
|
|
$adapter = new QueryAdapter($queryBuilder); |
|
$pagerfanta = Pagerfanta::createForCurrentPageWithMaxPerPage( |
|
$adapter, |
|
1, |
|
9 |
|
); |
|
|
// ... lines 50 - 54
|
|
} |
|
} |
See Code Block in Script
|
|
// ... lines 1 - 9
|
|
use Pagerfanta\Doctrine\ORM\QueryAdapter; |
|
use Pagerfanta\Pagerfanta; |
|
|
// ... lines 12 - 17
|
|
class QuestionController extends AbstractController |
|
{ |
|
|
// ... lines 20 - 32
|
|
public function homepage(QuestionRepository $repository) |
|
{ |
|
$queryBuilder = $repository->createAskedOrderedByNewestQueryBuilder(); |
|
|
|
$pagerfanta = new Pagerfanta(new QueryAdapter($queryBuilder)); |
|
$pagerfanta->setMaxPerPage(5); |
|
|
// ... lines 39 - 42
|
|
} |
|
|
// ... lines 44 - 85
|
|
} |
See Code Block in Script
x
94