Un paginateur à base de portée et de moteur, propre, puissant, personnalisable et sophistiqué pour les frameworks d'applications Web modernes et ORMS
Ne pollue pas à l' Array
mondiale, Hash
, Object
ou AR::Base
.
Il suffit de regrouper la gemme, puis vos modèles sont prêts à être paginés. Aucune configuration requise. Je n'ai rien à définir dans vos modèles ou vos aides.
Tout est chaînable par des méthodes avec moins de "harite". Vous savez, c'est la manière moderne des Rails. Aucune classe de collecte spéciale ou quoi que ce soit pour les valeurs paginées, à la place en utilisant une instance General AR::Relation
. Ainsi, bien sûr, vous pouvez enchaîner d'autres conditions avant ou après la portée du paginateur.
Comme toute l'assistance de pagination n'est essentiellement qu'une collection de liens et de non-liens, Kaminari les rend chacun via son propre modèle partiel à l'intérieur du moteur. Ainsi, vous pouvez facilement modifier leur comportement, leur style ou quoi que ce soit en remplaçant des modèles partiels.
Kaminari prend en charge plusieurs orms (ActiveRecord, Datamapper, Mongoid, Mongomapper), plusieurs cadres Web (Rails, Sinatra, Grape) et plusieurs moteurs de modèle (Erb, Haml, Slim).
L'assistance de pagination sortit la balise HTML5 <nav>
par défaut. De plus, l'assistance prend en charge les rails discrets Ajax.
Ruby 2.1, 2.2, 2,3, 2,4, 2,5, 2,6, 2,7, 3,0, 3.1, 3.2, 3,3
Rails 4.1, 4.2, 5.0, 5.1, 5.2, 6.0, 6.1, 7.0, 7.1, 7.2, 8.0
Sinatra 1.4, 2.0
Haml 3+
Mongoïde 3+
Mongomapper 0.9+
Datamapper 1.1.0+
Pour installer Kaminari sur la pile de rails par défaut, placez simplement cette ligne dans votre gemfile:
gem 'kaminari'
Puis paquet:
% bundle
Si vous créez une application non rails ou non active et que vous souhaitez la fonction de pagination dessus, veuillez jeter un œil à la section d'assistance Framework / Library.
page
Pour récupérer la 7e page des utilisateurs (par défaut per_page
est de 25)
User . page ( 7 )
Remarque: La pagination commence à la page 1, pas à la page 0 (page (0) renverra les mêmes résultats que la page (1)).
Kaminari n'ajoute pas d' order
aux requêtes. Pour éviter les surprises, vous devez généralement inclure une commande dans les requêtes paginées. Par exemple:
User . order ( :name ) . page ( 7 )
Vous pouvez obtenir des numéros de page ou des conditions de page en utilisant des méthodes ci-dessous.
User . count #=> 1000
User . page ( 1 ) . limit_value #=> 20
User . page ( 1 ) . total_pages #=> 50
User . page ( 1 ) . current_page #=> 1
User . page ( 1 ) . next_page #=> 2
User . page ( 2 ) . prev_page #=> 1
User . page ( 1 ) . first_page? #=> true
User . page ( 50 ) . last_page? #=> true
User . page ( 100 ) . out_of_range? #=> true
per
Pour afficher beaucoup plus d'utilisateurs pour chaque page (modifiez la per
)
User . order ( :name ) . page ( 7 ) . per ( 50 )
Notez que la lunette per
n'est pas directement définie sur les modèles mais n'est qu'une méthode définie sur la portée de la page. Ceci est absolument raisonnable car vous n'utiliserez jamais réellement per
sans spécifier le numéro page
.
Gardez à l'esprit que per
Utilise Interly limit
et qu'il remplacera donc toute limit
qui a été fixée précédemment. Et si vous souhaitez obtenir la taille de tous les enregistrements de demande, vous pouvez utiliser la méthode total_count
:
User . count #=> 1000
a = User . limit ( 5 ) ; a . count #=> 5
a . page ( 1 ) . per ( 20 ) . size #=> 20
a . page ( 1 ) . per ( 20 ) . total_count #=> 1000
padding
Parfois, vous devez remplir un certain nombre d'enregistrements qui n'est pas un multiple de la taille de la page.
User . order ( :name ) . page ( 7 ) . per ( 50 ) . padding ( 3 )
Notez que la portée padding
n'est pas non plus directement définie sur les modèles.
Si, pour une raison quelconque, vous devez vous page
et per
méthodes, vous pouvez appeler except(:limit, :offset)
users = User . order ( :name ) . page ( 7 ) . per ( 50 )
unpaged_users = users . except ( :limit , :offset ) # unpaged_users will not use the kaminari scopes
Vous pouvez configurer les valeurs par défaut suivantes en remplaçant ces valeurs à l'aide de la méthode Kaminari.configure
.
default_per_page # 25 by default
max_per_page # nil by default
max_pages # nil by default
window # 4 by default
outer_window # 0 by default
left # 0 by default
right # 0 by default
page_method_name # :page by default
param_name # :page by default
params_on_first_page # false by default
Il y a un générateur pratique qui génère le fichier de configuration par défaut dans le répertoire config / initialisers. Exécutez la commande du générateur suivant, puis modifiez le fichier généré.
% rails g kaminari:config
page_method_name
Vous pouvez modifier la page
Nom de la méthode par bonzo
ou plant
ou ce que vous voulez, afin de jouer bien avec la méthode page
ou l'association ou la portée existante ou tout autre plugin qui définit la méthode page
sur vos modèles.
paginates_per
Vous pouvez spécifier la valeur per_page
par défaut par chaque modèle en utilisant le DSL déclaratif suivant.
class User < ActiveRecord :: Base
paginates_per 50
end
max_paginates_per
Vous pouvez spécifier la valeur max per_page
par chaque modèle en utilisant le DSL déclaratif suivant. Si la variable spécifiée via per
étendue est supérieure à cette variable, max_paginates_per
est utilisée à la place. La valeur par défaut est nulle, ce qui signifie que vous n'imposez aucune valeur max per_page
.
class User < ActiveRecord :: Base
max_paginates_per 100
end
max_pages
Vous pouvez spécifier la valeur max_pages
par chaque modèle en utilisant le DSL déclaratif suivant. Cette valeur restreint le nombre total de pages qui peuvent être renvoyées. Utile pour fixer des limites sur les grandes collections.
class User < ActiveRecord :: Base
max_pages 100
end
Si vous utilisez le GEM ransack_memory
et que vous rencontrez des problèmes de retour à la page précédente ou première, définissez le paramètre params_on_first_page
sur true
.
params[:page]
En règle générale, votre code de contrôleur ressemblera à ceci:
@users = User . order ( :name ) . page params [ :page ]
Appelez simplement le paginate
Helper:
<%= paginate @users %>
Cela rendra plusieurs liens de pagination ?page=N
entourés d'une balise HTML5 <nav>
.
paginate
<%= paginate @users %>
Cela ferait plusieurs liens de pagination tels que « First ‹ Prev ... 2 3 4 5 6 7 8 9 10 ... Next › Last »
.
<%= paginate @users, window: 2 %>
Cela sortirait quelque chose comme ... 5 6 7 8 9 ...
quand 7 est la page actuelle.
<%= paginate @users, outer_window: 3 %>
Cela sortirait quelque chose comme 1 2 3 ...(snip)... 18 19 20
tout en ayant 20 pages au total.
<%= paginate @users, left: 1, right: 3 %>
Cela ferait quelque chose comme 1 ...(snip)... 18 19 20
tout en ayant 20 pages au total.
:param_name
) pour les liens <%= paginate @users, param_name: :pagina %>
Cela modifierait le nom du paramètre de requête sur chaque lien.
:params
) pour les liens <%= paginate @users, params: {controller: 'foo', action: 'bar', format: :turbo_stream} %>
Cela modifierait url_option
de chaque lien. :controller
et :action
peut être les clés en commun.
<%= paginate @users, remote: true %>
Cela ajouterait data-remote="true"
à tous les liens à l'intérieur.
<%= paginate @users, views_prefix: 'templates' %>
Cela rechercherait des partiels dans app/views/templates/kaminari
. Cette option facilite les choses comme les modèles / thèmes de pagination de test A / B, en utilisant des modèles nouveaux / anciens en même temps ainsi qu'une meilleure intégration avec d'autres gemmes telles que les cellules.
link_to_next_page
ET link_to_previous_page
(aliasé sur link_to_prev_page
) Méthodes d'assistance <%= link_to_next_page @items, 'Next Page' %>
Cela rend simplement un lien vers la page suivante. Cela serait utile pour créer une fonction de pagination de type Twitter.
Les méthodes d'aide prennent en charge une option params
pour spécifier davantage le lien. Si format
doit être défini, incluez-le dans le hachage params
.
<%= link_to_next_page @items, 'Next Page', params: {controller: 'foo', action: 'bar', format: :turbo_stream} %>
page_entries_info
Helper <%= page_entries_info @posts %>
Cela rend un message utile avec des nombres affichés par rapport aux entrées totales.
Par défaut, le message utilisera le nom de classe humanisé des objets dans la collection: par exemple, "Types de projet" pour les modèles ProjectType. L'espace de noms sera découpé et seul le nom de famille sera utilisé. Remplacez-le avec le paramètre :entry_name
:
<%= page_entries_info @posts, entry_name: 'item' %>
#= > Displaying items 6 - 10 of 26 in total
rel_next_prev_link_tags
<%= rel_next_prev_link_tags @users %>
Cela rend les balises REL Next et PREV Link pour la tête.
path_to_next_page
Helper <%= path_to_next_page @users %>
Cela renvoie le chemin relatif du serveur vers la page suivante.
path_to_prev_page
Helper <%= path_to_prev_page @users %>
Cela renvoie le chemin relatif du serveur vers la page précédente.
Les étiquettes par défaut pour «First», «Last», «Précédent», «...» et «Next» sont stockées dans le I18N YAML à l'intérieur du moteur et rendues via une API i18n. Vous pouvez changer la valeur d'étiquette par i18n.locale pour votre application internationalisée. Les clés et les valeurs par défaut sont les suivantes. Vous pouvez les remplacer en ajoutant à un fichier YAML dans votre répertoire Rails.root/config/locales
.
en :
views :
pagination :
first : " « First "
last : " Last » "
previous : " ‹ Prev "
next : " Next › "
truncate : " … "
helpers :
page_entries_info :
one_page :
display_entries :
zero : " No %{entry_name} found "
one : " Displaying <b>1</b> %{entry_name} "
other : " Displaying <b>all %{count}</b> %{entry_name} "
more_pages :
display_entries : " Displaying %{entry_name} <b>%{first}–%{last}</b> of <b>%{total}</b> in total "
Si vous utilisez la localisation non anglaise, voir les règles i18n pour modifier un bloc one_page:display_entries
.
Kaminari comprend un générateur de modèles pratique.
Exécutez d'abord le générateur,
% rails g kaminari:views default
Modifiez ensuite les partiels dans app/views/kaminari/
répertoire.
Vous pouvez utiliser le GEM HTML2HAML ou le GEM HTML2SLIM pour convertir les modèles ERB. Le joyau de Kaminari ramassera automatiquement les modèles HAML / Slim si vous les placez dans app/views/kaminari/
.
Dans le cas où vous avez besoin de modèles différents pour votre paginateur (par exemple public et admin), vous pouvez passer --views-prefix directory
comme ceci:
% rails g kaminari:views default --views-prefix admin
Cela générera des partiels dans app/views/admin/kaminari/
répertoire.
Le générateur a la possibilité de récupérer plusieurs thèmes de modèle d'échantillonnage du référentiel externe (https://github.com/amatsuda/kaminari_themes) en plus du "par défaut" groupé, ce qui vous aidera à créer un joli paginateur.
% rails g kaminari:views THEME
Pour voir la liste complète des thèmes disponibles, jetez un œil au référentiel des thèmes ou appuyez simplement sur le générateur sans spécifier l'argument THEME
.
% rails g kaminari:views
Pour utiliser plusieurs thèmes à partir d'une seule application, créez un répertoire dans l'application / vues / kaminari / et déplacez vos fichiers de modèle personnalisés dans ce répertoire.
% rails g kaminari:views default (skip if you have existing kaminari views)
% cd app/views/kaminari
% mkdir my_custom_theme
% cp _ * .html. * my_custom_theme/
Ensuite, référence à ce répertoire lors de l'appel de la méthode paginate
:
<%= paginate @users, theme: 'my_custom_theme' %>
Personnalisez!
Remarque: Si le thème n'est pas présent ou aucun n'est spécifié, Kaminari reviendra par défaut les vues incluses dans le gemme.
Généralement, le paginateur doit connaître le nombre total d'enregistrements pour afficher les liens, mais parfois nous n'avons pas besoin du nombre total d'enregistrements et avons simplement besoin des liens "page précédente" et "page suivante". Pour un tel cas d'utilisation, Kaminari fournit le mode without_count
qui crée une collection paginatable sans compter le nombre de tous les enregistrements. Cela peut être utile lorsque vous avez affaire à un très grand ensemble de données, car le comptage sur une grande table a tendance à devenir lent sur les SGBDR.
Il suffit d'ajouter .without_count
Avec votre objet paginé:
User . page ( 3 ) . without_count
Dans votre fichier de vue, vous ne pouvez utiliser que des aides simples comme les suivantes au lieu de l'assistante paginate
à complexe:
<%= link_to_prev_page @users, 'Previous Page' %>
<%= link_to_next_page @users, 'Next Page' %>
Kaminari fournit une classe de wrapper de tableau qui adapte un objet de tableau générique à l'assistant de vue paginate
. Cependant, l'assistance paginate
ne gère pas automatiquement votre objet de tableau (c'est intentionnel et par conception). La méthode Kaminari::paginate_array
convertit votre objet de tableau en un tableau paginatable qui accepte la méthode page
.
@paginatable_array = Kaminari . paginate_array ( my_array_object ) . page ( params [ :page ] ) . per ( 10 )
Vous pouvez spécifier la valeur total_count
valeur via le hachage des options. Cela serait utile lors de la gestion d'un objet de tableau qui a une valeur count
différente du count
réel tel que le résultat de recherche RSOLR ou lorsque vous devez générer une pagination personnalisée. Par exemple:
@paginatable_array = Kaminari . paginate_array ( [ ] , total_count : 145 ) . page ( params [ :page ] ) . per ( 10 )
ou, dans le cas de l'utilisation d'une API externe pour s'approvisionner la page des données:
page_size = 10
one_page = get_page_of_data params [ :page ] , page_size
@paginatable_array = Kaminari . paginate_array ( one_page . data , total_count : one_page . total_count ) . page ( params [ :page ] ) . per ( page_size )
En raison du paramètre page
et du routage des rails, vous pouvez facilement générer des URL SEO et conviviaux. Pour toute ressource que vous souhaitez paginer, ajoutez simplement ce qui suit à vos routes.rb
:
resources :my_resources do
get 'page/:page' , action : :index , on : :collection
end
Si vous utilisez Rails 4 ou version ultérieure, vous pouvez simplifier les définitions d'itinéraire en utilisant concern
:
concern :paginatable do
get '(page/:page)' , action : :index , on : :collection , as : ''
end
resources :my_resources , concerns : :paginatable
Cela créera des URL comme /my_resources/page/33
au lieu de /my_resources?page=33
. C'est maintenant une URL amicale, mais elle a également d'autres avantages supplémentaires ...
Parce que le paramètre page
est maintenant un segment URL, nous pouvons tirer parti de la mise en cache de la page Rails!
Remarque: Dans cet exemple, j'ai pointé l'itinéraire vers mon :index
action. Vous avez peut-être défini une action de pagination personnalisée dans votre contrôleur - vous devez pointer action: :your_custom_action
à la place.
Techniquement, le joyau de Kaminari se compose de 3 composants individuels:
kaminari-core: the core pagination logic
kaminari-activerecord: Active Record adapter
kaminari-actionview: Action View adapter
Ainsi, gem 'kaminari'
est équivalente aux 2 lignes suivantes (Kaminari-core est référencé à partir des adaptateurs):
gem 'kaminari-activerecord'
gem 'kaminari-actionview'
Si vous souhaitez utiliser d'autres orms pris en charge au lieu d'ActiveRecord, par exemple mongoïde, regroupez son adaptateur au lieu de Kaminari-ActiveRecord.
gem 'kaminari-mongoid'
gem 'kaminari-actionview'
Kaminari fournit actuellement des adaptateurs pour les ORM suivants:
Si vous souhaitez utiliser d'autres frameworks Web au lieu de Rails + Action View, par exemple Sinatra, regroupez son adaptateur au lieu de Kaminari-actionView.
gem 'kaminari-activerecord'
gem 'kaminari-sinatra'
Kaminari fournit actuellement des adaptateurs pour les cadres Web suivants:
Consultez les recettes Kaminari sur le wiki GitHub pour des conseils et des techniques plus avancés. https://github.com/kaminari/kaminari/wiki/kaminari-recipes
N'hésitez pas à m'envoyer un message sur github (amatsuda) ou twitter (@a_matsuda) ☇☇☇ :)
Fork, correction, puis envoyez une demande de traction.
Pour exécuter la suite de test localement contre tous les cadres pris en charge:
% bundle install
% rake test:all
Pour cibler la suite de test contre un cadre:
% rake test:active_record_50
Vous pouvez trouver une liste des tâches de test prises en charge en exécutant rake -T
. Vous pouvez également trouver utile d'exécuter un test spécifique pour un cadre spécifique. Pour ce faire, vous devrez d'abord vous assurer que vous avez tout groupé pour cette configuration, puis vous pouvez exécuter le test spécifique:
% BUNDLE_GEMFILE= ' gemfiles/active_record_50.gemfile ' bundle install
% BUNDLE_GEMFILE= ' gemfiles/active_record_50.gemfile ' TEST=kaminari-core/test/requests/navigation_test.rb bundle exec rake test
Copyright (C) 2011- Akira Matsuda. Voir MIT-License pour plus de détails.