Dans cette leçon, nous allons faire un aperçu des différents types de listes dans SilverStripe et nous utiliserons PaginatedList pour ajouter une pagination à nos résultats de recherche.
Jusqu’à présent, nous ne travaillions qu’avec SilverStripe\ORM\DataListle rendu d’une collection de données, mais il est important de noter que SilverStripe Framework vous propose toutes sortes de listes, chacune d’entre elles abordant un problème particulier. Voici quelques listes courantes que vous pouvez utiliser dans l’ SilverStripe\ORMespace de noms:
ArrayList: Le type de liste le plus primitif. Il contient des données arbitraires et ne fait rien de particulier.
DataList: Utilisé pour les données extraites de la base de données et fournit une API pour la mise à jour de la requête qui définit sa collection d’enregistrements.
PaginatedList: Attribue une limite et un décalage au jeu de résultats en fonction d’une page dérivée du paramètre request, et expose une API permettant de déterminer quelle page est active et quelles pages sont disponibles.
GroupedList: Permet de regrouper le jeu de résultats en sous-listes, chacune avec son propre en-tête, par exemple, regroupées par catégorie ou par nom de ville.
Toutes ces listes implémentent l’ SilverStripe\ORM\SS_Listinterface, qui spécifie qu’elles doivent toutes savoir exécuter les fonctions de base d’une liste, notamment:
Itérant sur la liste
Ajout à la fin de la liste ( ->add())
Obtenir le premier ou le dernier membre de la liste ( ->first())
Supprimer un élément de la liste ( ->remove($item))
Obtenir un résultat de la liste qui correspond ( ->find($key, $val))
Transformer la liste en un simple tableau ( ->toArray())
Obtenir la taille de la liste ( ->count())
Comme vous pouvez le constater, ce PaginatedListn’est qu’une des implémentations de cette spécification, et en plus de toutes les fonctionnalités ci-dessus, elle nous fournit des outils très précieux pour gérer la pagination, et nous examinerons tout cela à la suite.
Créer une liste paginée
Dans la leçon précédente, nous avons créé un formulaire de recherche qui a généré une liste de résultats. À l’heure actuelle, les résultats sont artificiellement limités à 20, pour des raisons de performances, car la base de données contient plus de 100 enregistrements. En regardant le modèle, nous avons déjà du HTML statique pour la pagination, alors travaillons à l’activer.
Comme dit précédemment, la PaginatedListclasse de SilverStripe est essentiellement une enveloppe pour ceux DataListqui font beaucoup de travail pour nous. Il examinera automatiquement la demande et ajoutera la LIMITclause correcte à la liste de données, et fournira également une API publique permettant de déterminer quelle page est active et quelles pages, le cas échéant, sont disponibles.
Regardons à PropertySearchPage.phpnouveau et trouvons la valeur de retour de notre index()action. En ce moment, ça retourne un DataList. Faisons-le retourner un à la PaginatedListplace.
Tout d’abord, supprimons l’artificiel que ->limit()nous avons appliqué.
C’est vraiment aussi simple que cela. Nous ne faisons que transmettre l’ SS_Listinstance avec laquelle nous travaillons (généralement une DataList), et dans l’intérêt de garder la liste faiblement couplée, nous transmettons également la demande. Cela peut sembler étrange que nous devions le faire, mais si la liste était informée de la demande, elle introduirait un couplage étroit, ce qui rend les tests unitaires plus difficiles et rend la classe moins extensible.
Grâce à une multitude de valeurs par défaut prédéfinies PaginatedList, nous sommes prêts à restituer ces résultats sur le modèle.
Ajout de liens de pagination au modèle
Jetons un coup d’œil à notre PropertySearchPage.ssmodèle et trouvons le code HTML pour la pagination.
Jusqu’à présent, la seule syntaxe que nous ayons réellement utilisée dans une liste était celle de <% loop %>blocs, mais la liste elle-même a également des propriétés, un peu comme un DataObject.
Utilisons certaines des propriétés que nous obtenons PaginatedListpour rendre cette pagination.
Nous encapsulons l’interface utilisateur entière dans la condition qui $Results.MoreThanOnePagerenvoie true. Rien de tout cela ne devrait s’afficher s’il n’y a que quelques résultats. Ensuite, si nous sommes sur autre chose que la première page, nous utiliserons le $Results.PrevLinkpour fournir un lien vers la page précédente. Nous ferons la même chose $Results.NextLinksi nous sommes sur autre chose que la dernière page. Au milieu, nous parcourons en boucle $Results.Pages, chaque membre de la liste fournissant trois propriétés:
$PageNum: Le numéro de page
$CurrentBool: True si la page est actuelle
$Link: Le lien vers la page
Essayez la pagination et voyez comment cela fonctionne. Notez qu’il injecte un paramètre de requête appelé startdans l’URL. Notez également que les paramètres de recherche persistent tout au long de la pagination.
Utilisons quelques propriétés supplémentaires de la liste paginée pour créer un résumé des résultats.
Enfin, si nous avons beaucoup de pages, cela peut casser l’UI. Au lieu de $Results.Pages, utilisons $Results.PaginationSummary, qui nous montrera juste quelques unes des pages proches de la page active. En d’autres termes, nous n’avons pas besoin de voir la page 17 sur 30 si nous sommes à la page 2.
Notez que nous devons vérifier si $Linkrenvoie rien. Si ce n’est pas le cas, nous savons que cet élément est le résultat vide destiné à montrer l’existence de pages supprimées.
De plus, vous pouvez personnaliser le contexte souhaité en transmettant un entier PaginationSummary. Par défaut, il affiche 4 pages de contexte.
Personnaliser la liste paginée
Tout cela fonctionne très bien, mais la pagination est toujours configurée avec des valeurs par défaut, notamment une limite de 10 résultats par page. Mettons à jour cela.
Un autre paramètre que nous pourrions vouloir personnaliser est le paramètre de requête utilisé. Dans certains cas, vous pouvez avoir un conflit avec la variable startou préférez simplement quelque chose de plus court. Dans ce cas, utilisez setPaginationGetVar().
Dépôt de code à télécharger
Ce que nous allons couvrir
Un bref aperçu des listes
Jusqu’à présent, nous ne travaillions qu’avec
SilverStripe\ORM\DataList
le rendu d’une collection de données, mais il est important de noter que SilverStripe Framework vous propose toutes sortes de listes, chacune d’entre elles abordant un problème particulier. Voici quelques listes courantes que vous pouvez utiliser dans l’SilverStripe\ORM
espace de noms:ArrayList
: Le type de liste le plus primitif. Il contient des données arbitraires et ne fait rien de particulier.DataList
: Utilisé pour les données extraites de la base de données et fournit une API pour la mise à jour de la requête qui définit sa collection d’enregistrements.PaginatedList
: Attribue une limite et un décalage au jeu de résultats en fonction d’une page dérivée du paramètre request, et expose une API permettant de déterminer quelle page est active et quelles pages sont disponibles.GroupedList
: Permet de regrouper le jeu de résultats en sous-listes, chacune avec son propre en-tête, par exemple, regroupées par catégorie ou par nom de ville.Toutes ces listes implémentent l’
SilverStripe\ORM\SS_List
interface, qui spécifie qu’elles doivent toutes savoir exécuter les fonctions de base d’une liste, notamment:->add()
)->first()
)->remove($item)
)->find($key, $val)
)->toArray()
)->count()
)Comme vous pouvez le constater, ce
PaginatedList
n’est qu’une des implémentations de cette spécification, et en plus de toutes les fonctionnalités ci-dessus, elle nous fournit des outils très précieux pour gérer la pagination, et nous examinerons tout cela à la suite.Créer une liste paginée
Dans la leçon précédente, nous avons créé un formulaire de recherche qui a généré une liste de résultats. À l’heure actuelle, les résultats sont artificiellement limités à 20, pour des raisons de performances, car la base de données contient plus de 100 enregistrements. En regardant le modèle, nous avons déjà du HTML statique pour la pagination, alors travaillons à l’activer.
Comme dit précédemment, la
PaginatedList
classe de SilverStripe est essentiellement une enveloppe pour ceuxDataList
qui font beaucoup de travail pour nous. Il examinera automatiquement la demande et ajoutera laLIMIT
clause correcte à la liste de données, et fournira également une API publique permettant de déterminer quelle page est active et quelles pages, le cas échéant, sont disponibles.Regardons à
PropertySearchPage.php
nouveau et trouvons la valeur de retour de notreindex()
action. En ce moment, ça retourne unDataList
. Faisons-le retourner un à laPaginatedList
place.Tout d’abord, supprimons l’artificiel que
->limit()
nous avons appliqué.app / src / PropertySearchPageController.php
Maintenant, emballons les résultats dans un fichier
PaginatedList
.app / src / PropertySearchPageController.php
C’est vraiment aussi simple que cela. Nous ne faisons que transmettre l’
SS_List
instance avec laquelle nous travaillons (généralement uneDataList
), et dans l’intérêt de garder la liste faiblement couplée, nous transmettons également la demande. Cela peut sembler étrange que nous devions le faire, mais si la liste était informée de la demande, elle introduirait un couplage étroit, ce qui rend les tests unitaires plus difficiles et rend la classe moins extensible.Grâce à une multitude de valeurs par défaut prédéfinies
PaginatedList
, nous sommes prêts à restituer ces résultats sur le modèle.Ajout de liens de pagination au modèle
Jetons un coup d’œil à notre
PropertySearchPage.ss
modèle et trouvons le code HTML pour la pagination.Jusqu’à présent, la seule syntaxe que nous ayons réellement utilisée dans une liste était celle de
<% loop %>
blocs, mais la liste elle-même a également des propriétés, un peu comme unDataObject
.Utilisons certaines des propriétés que nous obtenons
PaginatedList
pour rendre cette pagination.app / templates / SilverStripe / Lessons / Layout / PropertySearchPage.ss`
Nous encapsulons l’interface utilisateur entière dans la condition qui
$Results.MoreThanOnePage
renvoie true. Rien de tout cela ne devrait s’afficher s’il n’y a que quelques résultats. Ensuite, si nous sommes sur autre chose que la première page, nous utiliserons le$Results.PrevLink
pour fournir un lien vers la page précédente. Nous ferons la même chose$Results.NextLink
si nous sommes sur autre chose que la dernière page. Au milieu, nous parcourons en boucle$Results.Pages
, chaque membre de la liste fournissant trois propriétés:$PageNum
: Le numéro de page$CurrentBool
: True si la page est actuelle$Link
: Le lien vers la pageEssayez la pagination et voyez comment cela fonctionne. Notez qu’il injecte un paramètre de requête appelé
start
dans l’URL. Notez également que les paramètres de recherche persistent tout au long de la pagination.Utilisons quelques propriétés supplémentaires de la liste paginée pour créer un résumé des résultats.
app / templates / SilverStripe / Lessons / Layout / PropertySearchPage.ss
Enfin, si nous avons beaucoup de pages, cela peut casser l’UI. Au lieu de
$Results.Pages
, utilisons$Results.PaginationSummary
, qui nous montrera juste quelques unes des pages proches de la page active. En d’autres termes, nous n’avons pas besoin de voir la page 17 sur 30 si nous sommes à la page 2.* app / templates / SilverStripe / Lessons / Layout / PropertySearchPage.ss`
Notez que nous devons vérifier si
$Link
renvoie rien. Si ce n’est pas le cas, nous savons que cet élément est le résultat vide destiné à montrer l’existence de pages supprimées.De plus, vous pouvez personnaliser le contexte souhaité en transmettant un entier
PaginationSummary
. Par défaut, il affiche 4 pages de contexte.Personnaliser la liste paginée
Tout cela fonctionne très bien, mais la pagination est toujours configurée avec des valeurs par défaut, notamment une limite de 10 résultats par page. Mettons à jour cela.
app / src / PropertySearchPageController.php
Un autre paramètre que nous pourrions vouloir personnaliser est le paramètre de requête utilisé. Dans certains cas, vous pouvez avoir un conflit avec la variable
start
ou préférez simplement quelque chose de plus court. Dans ce cas, utilisezsetPaginationGetVar()
.app / src / PropertySearchPageController.php