pagy 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +31 -0
- data/lib/locales/pagy.yml +25 -0
- data/lib/pagy/backend.rb +42 -0
- data/lib/pagy/frontend.rb +155 -0
- data/lib/pagy.rb +61 -0
- data/lib/templates/bootstrap-no-dep.html.haml +28 -0
- data/lib/templates/bootstrap-no-dep.html.slim +37 -0
- data/lib/templates/bootstrap-rails-dep.html.erb +46 -0
- data/lib/templates/default-no-dep.html.haml +31 -0
- data/lib/templates/default-no-dep.html.slim +30 -0
- data/lib/templates/default-rails-dep.html.erb +32 -0
- data/lib/templates/default-rails-dep.html.haml +24 -0
- data/lib/templates/default-rails-dep.html.slim +23 -0
- data/pagy.gemspec +32 -0
- metadata +173 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b23ad1b8bfd60d555fd55e0b5534c34b29055447c41116454f73892ffc7eef73
|
4
|
+
data.tar.gz: 0a8d532508344459576ab5d3c89e772ef0ee626cd3671d56fa21b611815f8d11
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d035e9a3319e63353dd743ef0da6c05b995f5f66c5effea233cdecb52bae17bee7f50730a18ed4ccda818b0e29b52ab79db48e37db9f7dfe9c719908c6ebd1b8
|
7
|
+
data.tar.gz: d487d610feef6697c625677d4332b474a3f8876a434edfcefa321c371838ef6552ad7bc246cbcb0a5340dc55302d4d9f728032e823ce964c04cc09a577817a04
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2017-2018 Domizio Demichelis
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Pagy
|
2
|
+
|
3
|
+
Dead simple pagination in pure ruby. Easy, fast and very light. No restrictions imposed: use it with any MVC framework, any ORM, any DB type, any templating system or none at all. Use the built-in templates or create yours the way you want.
|
4
|
+
|
5
|
+
## Alpha Version!
|
6
|
+
|
7
|
+
This gem is still missing documentation. TBD... soon ;).
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
gem 'pagy'
|
15
|
+
```
|
16
|
+
|
17
|
+
And then execute:
|
18
|
+
|
19
|
+
$ bundle
|
20
|
+
|
21
|
+
Or install it yourself as:
|
22
|
+
|
23
|
+
$ gem install pagy
|
24
|
+
|
25
|
+
## Contributing
|
26
|
+
|
27
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/ddnexus/pagy.
|
28
|
+
|
29
|
+
## License
|
30
|
+
|
31
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Pagy uses an internal I18n-like :pagy_t helper that lookup
|
2
|
+
# into this file at Pagy.root.join('locale', 'pagy.yml')
|
3
|
+
# If you want to customize it you should set:
|
4
|
+
# Pagy::Opts.i18n_file = 'path/to/your/file.yaml'
|
5
|
+
|
6
|
+
# If you need to use this method with pluralization different than english
|
7
|
+
# (i.e. not 'zero', 'one', 'other' plurals) then you should define the
|
8
|
+
# Pagy::Opts.i18n_plurals proc to return the plural key based on the passed count.
|
9
|
+
|
10
|
+
en:
|
11
|
+
pagy:
|
12
|
+
nav:
|
13
|
+
prev: "‹ Prev"
|
14
|
+
next: "Next ›"
|
15
|
+
gap: "…"
|
16
|
+
info:
|
17
|
+
single_page:
|
18
|
+
zero: "No %{item_name} found"
|
19
|
+
one: "Displaying <b>1</b> %{item_name}"
|
20
|
+
other: "Displaying <b>all %{count}</b> %{item_name}"
|
21
|
+
multiple_pages: "Displaying %{item_name} <b>%{from}-%{to}</b> of <b>%{count}</b>"
|
22
|
+
item:
|
23
|
+
zero: "items"
|
24
|
+
one: "item"
|
25
|
+
other: "items"
|
data/lib/pagy/backend.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
class Pagy
|
2
|
+
# Including this module (usually in your controller) is handy but totally optional.
|
3
|
+
# It basically just encapsulates a couple of verbose statement in one single slick
|
4
|
+
# #pagy method, but it does not add any functionality on its own.
|
5
|
+
#
|
6
|
+
# Using the module allows you to have a predefined method and a few sub-methods
|
7
|
+
# (i.e. methods called only by the predefine method) handy if you need to override
|
8
|
+
# some aspect of the predefined #pagy method.
|
9
|
+
#
|
10
|
+
# However, you can just explicitly write your own pagy method in just a couple of
|
11
|
+
# lines of code, specially if you need to override two or more methods. For example:
|
12
|
+
#
|
13
|
+
# def pagy(scope, opts={})
|
14
|
+
# pagy = Pagy.new scope.count, page: params[:page], **opts
|
15
|
+
# return pagy, scope.offset(pagy.offset).limit(pagy.limit)
|
16
|
+
# end
|
17
|
+
|
18
|
+
module Backend ; private # the whole module is private so no problem including it in a controller
|
19
|
+
|
20
|
+
def pagy(obj, opts={})
|
21
|
+
pagy = Pagy.new(count: pagy_get_count(obj), page: pagy_get_page, i18n_key: pagy_get_i18n_key(obj), **opts)
|
22
|
+
return pagy, pagy_get_items(obj, pagy)
|
23
|
+
end
|
24
|
+
|
25
|
+
def pagy_get_count(obj)
|
26
|
+
obj.count
|
27
|
+
end
|
28
|
+
|
29
|
+
def pagy_get_page
|
30
|
+
params[:page]
|
31
|
+
end
|
32
|
+
|
33
|
+
def pagy_get_i18n_key(obj) end
|
34
|
+
|
35
|
+
# this should work with ActiveRecord, Sequel, Mongoid...
|
36
|
+
# override it if obj does not implement it that way
|
37
|
+
def pagy_get_items(obj, pagy)
|
38
|
+
obj.offset(pagy.offset).limit(pagy.limit)
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
class Pagy
|
3
|
+
# This module supplies a few methods to deal with the navigation aspect of the pagination.
|
4
|
+
# You will usually include it in some helper module, eventually overriding the #pagy_url_for
|
5
|
+
# in order to fit its behavior with your app needs (e.g.: removing and adding some param or
|
6
|
+
# allowing fancy routes, etc.)
|
7
|
+
#
|
8
|
+
# All the code has been optimized for speed and low memory usage.
|
9
|
+
# In particular there are a couple of very specialized methods (pagy_t and pagy_linker_proc)
|
10
|
+
# that can be used in place of the equivalent (but general-purpose) framework helpers,
|
11
|
+
# in order to dramatically boost speed and reduce memory usage.
|
12
|
+
#
|
13
|
+
# For example if you use the rails link_to in order to link each page in the pagination bar,
|
14
|
+
# you will call 10 or 20 times the same method that has to do a lot of things again and again
|
15
|
+
# just to get you (almost) the same string repeated with just the page number replaced.
|
16
|
+
# Since pagination is a very specialized process, it is possible to do the same by using
|
17
|
+
# a one-line proc that uses just one single string interpolation. Compared to the general-purpose
|
18
|
+
# link_to method, the pagy_linker_proc is tens of times faster and uses a very small fraction of the memory.
|
19
|
+
#
|
20
|
+
# Notice: The code in this module may not look very pretty (as most code dealing with many long strings),
|
21
|
+
# but its performance makes it very sexy! ;)
|
22
|
+
|
23
|
+
module Frontend
|
24
|
+
|
25
|
+
# Notice: Each long tag-string of the nav methods is written on one single line with a long
|
26
|
+
# interpolation in the middle for performance and... (hard to believe) readability reasons.
|
27
|
+
#
|
28
|
+
# Performance:
|
29
|
+
# using the '%' method like in the following example:
|
30
|
+
#
|
31
|
+
# case item
|
32
|
+
# when Integer; '<span class="page">%s</span>' % linker.call(item)
|
33
|
+
# when String ; '<span class="page active">%s</span>' % item
|
34
|
+
# when :gap ; '<span class="page gap">%s</span>' % pagy_t('pagy.nav.gap')
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# would look a lot better but the benchmark really sucks! :/
|
38
|
+
#
|
39
|
+
# Readability:
|
40
|
+
# If you disable soft-wrapping in your editor, you can focus on the very simple ruby logic
|
41
|
+
# unfolding at the beginning of the lines, without any string-distraction.
|
42
|
+
# For the strings: each tag-string has only one interpolation, so at the end they are
|
43
|
+
# simple to deal with, even if they look a bit ugly.
|
44
|
+
|
45
|
+
# Generic pagination: it returns the html with the series of links to the pages
|
46
|
+
def pagy_nav(pagy, opts=nil)
|
47
|
+
pagy.opts.merge!(opts) if opts ; linker = pagy_linker_proc(pagy) ; tags = [] # init all vars
|
48
|
+
|
49
|
+
tags << (pagy.prev ? %(<span class="page prev">#{linker.call pagy.prev, pagy_t('pagy.nav.prev'.freeze), 'aria-label="previous"'.freeze}</span>)
|
50
|
+
: %(<span class="page prev disabled">#{pagy_t('pagy.nav.prev'.freeze)}</span>))
|
51
|
+
pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
|
52
|
+
tags << case item
|
53
|
+
when Integer; %(<span class="page">#{linker.call item}</span>) # page link
|
54
|
+
when String ; %(<span class="page active">#{item}</span>) # current page
|
55
|
+
when :gap ; %(<span class="page gap">#{pagy_t('pagy.nav.gap'.freeze)}</span>) # page gap
|
56
|
+
end
|
57
|
+
end
|
58
|
+
tags << (pagy.next ? %(<span class="page next">#{linker.call pagy.next, pagy_t('pagy.nav.next'.freeze), 'aria-label="next"'.freeze}</span>)
|
59
|
+
: %(<span class="page next disabled">#{pagy_t('pagy.nav.next'.freeze)}</span>))
|
60
|
+
%(<nav class="#{pagy.opts[:class]||'pagination'.freeze}" role="navigation" aria-label="pager">#{tags.join(pagy.opts[:separator]||' '.freeze)}</nav>)
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
# Pagination for bootstrap: it returns the html with the series of links to the pages
|
65
|
+
def pagy_nav_bootstrap(pagy, opts=nil)
|
66
|
+
pagy.opts.merge!(opts) if opts ; linker = pagy_linker_proc(pagy) ; tags = [] # init all vars
|
67
|
+
|
68
|
+
tags << (pagy.prev ? %(<li class="page-item prev">#{linker.call pagy.prev, pagy_t('pagy.nav.prev'.freeze), 'class="page-link" aria-label="previous"'.freeze}</li>)
|
69
|
+
: %(<li class="page-item prev disabled"><a href="#" class="page-link">#{pagy_t('pagy.nav.prev'.freeze)}</a></li>))
|
70
|
+
pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
|
71
|
+
tags << case item
|
72
|
+
when Integer; %(<li class="page-item">#{linker.call item, item, 'class="page-link"'.freeze}</li>) # page link
|
73
|
+
when String ; %(<li class="page-item active">#{linker.call item, item, 'class="page-link"'.freeze}</li>) # active page
|
74
|
+
when :gap ; %(<li class="page-item gap disabled"><a href="#" class="page-link">#{pagy_t('pagy.nav.gap'.freeze)}</a></li>) # page gap
|
75
|
+
end
|
76
|
+
end
|
77
|
+
tags << (pagy.next ? %(<li class="page-item next">#{linker.call pagy.next, pagy_t('pagy.nav.next'.freeze), 'class="page-link" aria-label="next"'.freeze}</li>)
|
78
|
+
: %(<li class="page-item next disabled"><a href="#" class="page-link">#{pagy_t('pagy.nav.next'.freeze)}</a></li>))
|
79
|
+
%(<nav class="#{pagy.opts[:class]||'pagination'.freeze}" role="navigation" aria-label="pager"><ul class="pagination">#{tags.join}</ul></nav>)
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
# return examples: "Displaying items 41-60 of 324" or "Displaying Products 41-60 of 324"
|
84
|
+
def pagy_info(pagy, vars=nil)
|
85
|
+
name = vars && vars[:item_name] || pagy_t(pagy.opts[:i18n_key] || 'pagy.info.item'.freeze, count: pagy.count)
|
86
|
+
name = pagy_t('pagy.info.item'.freeze, count: pagy.count) if name.start_with?('translation missing:'.freeze)
|
87
|
+
key = pagy.pages == 1 ? 'single_page'.freeze : 'multiple_pages'.freeze
|
88
|
+
pagy_t "pagy.info.#{key}", item_name: name, count: pagy.count, from: pagy.from, to: pagy.to
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
# this works with all Rack-based frameworks (Sinatra, Padrino, Rails, ...)
|
93
|
+
def pagy_url_for(n)
|
94
|
+
url = File.join(request.script_name.to_s, request.path_info)
|
95
|
+
params = request.GET.merge('page' => n.to_s)
|
96
|
+
url << '?' << Rack::Utils.build_nested_query(params)
|
97
|
+
end
|
98
|
+
|
99
|
+
# The :pagy_t method is the internal implementation of I18n.t, used when I18n is missing or
|
100
|
+
# not needed (for example when your application is a single-locale app, e.g. only 'en', or only 'fr'...).
|
101
|
+
#
|
102
|
+
# It implements only the very basic functionality of the I18n.t method
|
103
|
+
# but it is a lot faster, it uses less memory and it's still good enough for the limited Pagy's needs.
|
104
|
+
#
|
105
|
+
# You can still use this method with a pluralization different than English
|
106
|
+
# (i.e. not 'zero', 'one', 'other' plurals). In that case you should define the
|
107
|
+
# Pagy::Opts.i18n_plurals proc to return the plural key based on the passed count.
|
108
|
+
#
|
109
|
+
# If you need full I18n functionality, you should override this method with something like:
|
110
|
+
# def pagy_t(*a); I18n.t(*a) end
|
111
|
+
# and add your translations to the I18n usual locales files
|
112
|
+
|
113
|
+
hash = YAML.load_file Opts.i18n_file || Pagy.root.join('locales', 'pagy.yml')
|
114
|
+
DATA = hash[hash.keys.first].freeze
|
115
|
+
|
116
|
+
# Similar to I18n.t for interpolation and pluralization, with the following constraints:
|
117
|
+
# - the path/keys option is supported only in dot-separated string or symbol format
|
118
|
+
# - the :scope and :default options are not supported
|
119
|
+
# - no exception are raised: the errors are returned as translated strings
|
120
|
+
def pagy_t(path, vars={})
|
121
|
+
value = DATA.dig(*path.to_s.split('.'.freeze))
|
122
|
+
if value.is_a?(Hash)
|
123
|
+
vars.has_key?(:count) or return value
|
124
|
+
plural = (Opts.i18n_plurals ||= -> (c) {c==0 && 'zero' || c==1 && 'one' || 'other'}).call(vars[:count])
|
125
|
+
value.has_key?(plural) or return %(invalid pluralization data: "#{path}" cannot be used with count: #{vars[:count]}; key "#{plural}" is missing.)
|
126
|
+
value = value[plural]
|
127
|
+
end
|
128
|
+
value or return %(translation missing: "#{path}")
|
129
|
+
sprintf value, Hash.new{|h,k| "%{#{k}}"}.merge!(vars) # interpolation
|
130
|
+
end
|
131
|
+
|
132
|
+
# This method returns a very efficient proc to produce the page links.
|
133
|
+
# The proc is somewhat similar to link_to, but it works a lot faster
|
134
|
+
# with a simple one-string-only interpolation.
|
135
|
+
# The proc also adds the eventual :link_extra string option to the link tag
|
136
|
+
#
|
137
|
+
# Notice: all the rendering methods in this module use only strings for fast performance,
|
138
|
+
# so use the :link_extra option to add string-formatted attributes like for example:
|
139
|
+
# :link_extra => 'data-remote="true" class="special"'
|
140
|
+
#
|
141
|
+
# This method calls the (possibly overridden and slow) pagy_url_for only once to get the url
|
142
|
+
# with the MARKER in place of the page number, then it splits the beginning tag-string at the MARKER
|
143
|
+
# and defines a proc that interpolates the two fragments around the real page number with the rest of the tag.
|
144
|
+
# Tricky but very fast!
|
145
|
+
|
146
|
+
MARKER = "-pagy-#{'pagy'.hash}-".freeze
|
147
|
+
|
148
|
+
def pagy_linker_proc(pagy)
|
149
|
+
rel = { pagy.prev=>' rel="prev"'.freeze, pagy.next=>' rel="next"'.freeze }
|
150
|
+
a, b = %(<a href="#{pagy_url_for(MARKER)}" #{pagy.opts[:link_extra]}).split(MARKER)
|
151
|
+
-> (n, name=n.to_s, extra=''.freeze) { "#{a}#{n}#{b}#{rel[n]||''.freeze} #{extra}>#{name}</a>"}
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
end
|
data/lib/pagy.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
# This class takes a few integers (such as collection-count, page-number,
|
5
|
+
# items-per-page-limit, etc.), does some simple aritmetic and creates a very
|
6
|
+
# small object (~3k) with all is needed for pagination and navigation.
|
7
|
+
# Notice that it doesn't actually do any pagination, nor navigation... that is
|
8
|
+
# done with a few helpers in the Pagy::Backend and Pagy::Frontend modules.
|
9
|
+
|
10
|
+
class Pagy ; VERSION = '0.3.0'
|
11
|
+
|
12
|
+
autoload :Backend, 'pagy/backend'
|
13
|
+
autoload :Frontend, 'pagy/frontend'
|
14
|
+
|
15
|
+
class OutOfRangeError < StandardError; end
|
16
|
+
|
17
|
+
# root pathname to get the path of pagy files like templates or locales
|
18
|
+
def self.root; Pathname.new(__FILE__).dirname end
|
19
|
+
|
20
|
+
# default options
|
21
|
+
# limit: max items per page: it gets adjusted for the last page,
|
22
|
+
# so it will pull the right items if the collection was pre-limit(ed)
|
23
|
+
# offset: the initial offset of the whole collection before pagination
|
24
|
+
# set it only if the collection was pre-offset(ted): it gets added to the final offset
|
25
|
+
# initial/final: max pages to show from the first/last page
|
26
|
+
# before/after: max pages before/after the current page
|
27
|
+
Opts = OpenStruct.new(limit:20, offset:0, initial:1, before:4, after:4, final:1)
|
28
|
+
|
29
|
+
attr_reader :count, :page, :limit, :opts, :pages, :last, :offset, :from, :to, :prev, :next, :series
|
30
|
+
|
31
|
+
# merge and validate the options, do some simple aritmetic and set the instance variables
|
32
|
+
def initialize(opts)
|
33
|
+
@opts = Opts.to_h.merge!(opts) # global opts + instance opts (bang faster)
|
34
|
+
@opts[:page] = (@opts[:page]||1).to_i # set page to 1 if nil
|
35
|
+
[:count, :limit, :offset, :initial, :before, :page, :after, :final].each do |k|
|
36
|
+
@opts[k] >= 0 rescue nil || raise(ArgumentError, "expected #{k} >= 0; got #{@opts[k].inspect}")
|
37
|
+
instance_variable_set(:"@#{k}", @opts.delete(k)) # set all the metrics variables
|
38
|
+
end
|
39
|
+
@pages = @last = [(@count.to_f / @limit).ceil, 1].max # cardinal and ordinal meanings
|
40
|
+
(1..@last).cover?(@page) || raise(OutOfRangeError, "expected :page in 1..#{last}; got #{@page.inspect}")
|
41
|
+
@offset += @limit * (@page - 1) # initial offset + offset for pagination
|
42
|
+
@limit = @count % @limit if @page == @last # adjust limit for last page (for pre-limit(ed) collection)
|
43
|
+
@from = @count.zero? ? 0 : @offset+1 # page begins from item
|
44
|
+
@to = @offset + @limit # page ends to item
|
45
|
+
@prev = (@page-1 unless @page == 1) # nil if no prev page
|
46
|
+
@next = (@page+1 unless @page == @last) # nil if no next page
|
47
|
+
@series = [] # e.g. [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
|
48
|
+
all = (0..@last+1) # page range with boundaries
|
49
|
+
arund = ([@page-@before, 1].max .. [@page+@after, @last].min).to_a # before..after pages
|
50
|
+
row = (all.first(@initial+1) | arund | all.last(@final+1)).sort # pages with boundaries
|
51
|
+
row.each_cons(2) do |a, b| # loop in consecutive pairs
|
52
|
+
if a+1 == b; @series.push(a) # no gap -> no additions
|
53
|
+
elsif a+2 == b; @series.push(a, a+1) # 1 page gap -> fill with next page
|
54
|
+
else @series.push(a, :gap) # larger gap -> add :gap
|
55
|
+
end # skip the right boundary (last+1)
|
56
|
+
end
|
57
|
+
@series.shift # remove the left boundary (0)
|
58
|
+
@series[@series.index(@page)] = @page.to_s # convert the current page to String
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
-# This template uses only the pagy_url_for helper, no dependency on any framework
|
2
|
+
-# No special optimization for speed and memory. Use the pagy helpers if speed and memory are important.
|
3
|
+
|
4
|
+
- rel = { pagy.prev => 'prev', pagy.next => 'next' }
|
5
|
+
|
6
|
+
%nav.pagination{"aria-label" => "pager", :role => "navigation"}
|
7
|
+
|
8
|
+
%ul.pagination
|
9
|
+
|
10
|
+
%li.page-item.prev{:class => ('disabled' unless pagy.prev)}
|
11
|
+
%a.page-link{:href => (pagy.prev ? pagy_url_for(pagy.prev) : '#'), :rel => "prev", "aria-label"=>"previous"}!= pagy_t('pagy.nav.prev')
|
12
|
+
|
13
|
+
- pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
|
14
|
+
- case item
|
15
|
+
- when Integer # page link
|
16
|
+
%li.page-item
|
17
|
+
%a.page-link{:href => pagy_url_for(item), :rel => rel[item]}= item
|
18
|
+
|
19
|
+
- when String # current page
|
20
|
+
%li.page-item.active
|
21
|
+
%a.page-link{:href => pagy_url_for(item)}= item
|
22
|
+
|
23
|
+
- when :gap # page gap
|
24
|
+
%li.page-item.disabled.gap
|
25
|
+
%a.page-link{:href => "#"}!= pagy_t('pagy.nav.gap')
|
26
|
+
|
27
|
+
%li.page-item.next{:class => ('disabled' unless pagy.next)}
|
28
|
+
%a.page-link{:href => (pagy.next ? pagy_url_for(pagy.next) : '#'), :rel => "next", "aria-label"=>"next"}!= pagy_t('pagy.nav.next')
|
@@ -0,0 +1,37 @@
|
|
1
|
+
/ This template uses only the pagy_url_for helper, no dependency on any framework
|
2
|
+
/ No special optimization for speed and memory. Use the pagy helpers if speed and memory are important.
|
3
|
+
|
4
|
+
- rel = { pagy.prev => 'prev', pagy.next => 'next' }
|
5
|
+
|
6
|
+
nav.pagination role="navigation" aria-label="pager"
|
7
|
+
|
8
|
+
ul.pagination
|
9
|
+
|
10
|
+
- if pagy.prev
|
11
|
+
li.page-item.prev
|
12
|
+
a.page-link href=pagy_url_for(pagy.prev) rel="prev" aria-label="previous" == pagy_t('pagy.nav.prev')
|
13
|
+
- else
|
14
|
+
li.page-item.prev.disabled
|
15
|
+
a.page-link href="#" == pagy_t('pagy.nav.prev')
|
16
|
+
|
17
|
+
- pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
|
18
|
+
- case item
|
19
|
+
|
20
|
+
- when Integer # page link
|
21
|
+
li.page-item
|
22
|
+
a.page-link href=(pagy_url_for(item)) rel=(rel[item]) == item
|
23
|
+
|
24
|
+
- when String # current page
|
25
|
+
li.page-item.active
|
26
|
+
a.page-link href=(pagy_url_for(item)) == item
|
27
|
+
|
28
|
+
- when :gap # page gap
|
29
|
+
li.page-item.disabled.gap
|
30
|
+
a.page-link href="#" == pagy_t('pagy.nav.gap')
|
31
|
+
|
32
|
+
- if pagy.next
|
33
|
+
li.page-item.next
|
34
|
+
a.page-link href=pagy_url_for(pagy.next) rel="next" aria-label="next" == pagy_t('pagy.nav.next')
|
35
|
+
- else
|
36
|
+
li.page-item.next.disabled
|
37
|
+
a.page-link href="#" == pagy_t('pagy.nav.next')
|
@@ -0,0 +1,46 @@
|
|
1
|
+
<%#
|
2
|
+
This template uses only the pagy_url_for helper from pagy and link_to from rails
|
3
|
+
No special optimization for speed and memory. Use the pagy helpers if speed and memory are important.
|
4
|
+
-%>
|
5
|
+
<% rel = { pagy.prev => 'prev', pagy.next => 'next' } %>
|
6
|
+
|
7
|
+
<nav aria-label="pager" class="pagination" role="navigation">
|
8
|
+
<ul class="pagination">
|
9
|
+
|
10
|
+
<% if pagy.prev -%>
|
11
|
+
<li class="page-item prev">
|
12
|
+
<%= link_to pagy_t('pagy.nav.prev').html_safe, pagy_url_for(pagy.prev), rel: 'prev', class: 'page-link', 'aria-label': "previous" %>
|
13
|
+
</li>
|
14
|
+
<% else -%>
|
15
|
+
<li class="page-item prev disabled">
|
16
|
+
<%= link_to pagy_t('pagy.nav.prev').html_safe, pagy_url_for('#'), class: 'page-link'%>
|
17
|
+
</li>
|
18
|
+
<% end -%>
|
19
|
+
|
20
|
+
|
21
|
+
<% pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36] -%>
|
22
|
+
<% case item
|
23
|
+
when Integer -%>
|
24
|
+
<li class="page-item"><%== link_to item, pagy_url_for(item), rel: rel[item], class: 'page-link' %></li>
|
25
|
+
|
26
|
+
<% when String -%>
|
27
|
+
<li class="page-item active"><%== link_to item, pagy_url_for(item), class: 'page-link'%></li>
|
28
|
+
|
29
|
+
<% when :gap -%>
|
30
|
+
<li class="page-item disabled gap"><%== link_to pagy_t('pagy.nav.gap').html_safe, '#', class: 'page-link'%></li>
|
31
|
+
|
32
|
+
<% end -%>
|
33
|
+
<% end -%>
|
34
|
+
|
35
|
+
<% if pagy.next -%>
|
36
|
+
<li class="page-item next">
|
37
|
+
<%= link_to pagy_t('pagy.nav.next').html_safe, pagy_url_for(pagy.next), rel: 'next', class: 'page-link', 'aria-label': "next" %>
|
38
|
+
</li>
|
39
|
+
<% else -%>
|
40
|
+
<li class="page-item next disabled">
|
41
|
+
<%= link_to pagy_t('pagy.nav.next').html_safe, pagy_url_for('#'), class: 'page-link'%>
|
42
|
+
</li>
|
43
|
+
<% end -%>
|
44
|
+
|
45
|
+
</ul>
|
46
|
+
</nav>
|
@@ -0,0 +1,31 @@
|
|
1
|
+
-# This template uses only the pagy_url_for helper, no dependency on any framework
|
2
|
+
-# No special optimization for speed and memory. Use the pagy helpers if speed and memory are important.
|
3
|
+
|
4
|
+
- rel = { pagy.prev => 'prev', pagy.next => 'next' }
|
5
|
+
|
6
|
+
%nav.pagination{"aria-label" => "pager", :role => "navigation"}
|
7
|
+
|
8
|
+
%span{:class => "page prev #{'disabled' unless pagy.prev}"}
|
9
|
+
- if pagy.prev
|
10
|
+
%a{:href => pagy_url_for(pagy.prev), :rel => "prev", "aria-label"=>"previous"}!= pagy_t('pagy.nav.prev')
|
11
|
+
- else
|
12
|
+
!= pagy_t('pagy.nav.prev')
|
13
|
+
|
14
|
+
- pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
|
15
|
+
- case item
|
16
|
+
|
17
|
+
- when Integer # page link
|
18
|
+
%span.page
|
19
|
+
%a{:href => pagy_url_for(item), :rel => rel[item]}= item
|
20
|
+
|
21
|
+
- when String # current page
|
22
|
+
%span.page.current= item
|
23
|
+
|
24
|
+
- when :gap # page gap
|
25
|
+
%span.page.gap!= pagy_t('pagy.nav.gap')
|
26
|
+
|
27
|
+
%span{:class => "page next #{'disabled' unless pagy.next}"}
|
28
|
+
- if pagy.next
|
29
|
+
%a{:href => pagy_url_for(pagy.next), :rel => "next", "aria-label"=>"next"}!= pagy_t('pagy.nav.next')
|
30
|
+
- else
|
31
|
+
!= pagy_t('pagy.nav.next')
|
@@ -0,0 +1,30 @@
|
|
1
|
+
/ This template uses only the pagy_url_for helper, no dependency on any framework
|
2
|
+
/ No special optimization for speed and memory. Use the pagy helpers if speed and memory are important.
|
3
|
+
|
4
|
+
- rel = { pagy.prev => 'prev', pagy.next => 'next' }
|
5
|
+
|
6
|
+
nav.pagination role="navigation" aria-label="pager"
|
7
|
+
|
8
|
+
span.page.prev> class=('disabled' unless pagy.prev)
|
9
|
+
- if pagy.prev
|
10
|
+
a href=(pagy_url_for(pagy.prev)) rel="prev" aria-label="previous" == pagy_t('pagy.nav.prev')
|
11
|
+
- else
|
12
|
+
== pagy_t('pagy.nav.prev')
|
13
|
+
|
14
|
+
- pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
|
15
|
+
- case item
|
16
|
+
- when Integer # page link
|
17
|
+
span.page>
|
18
|
+
a href=(pagy_url_for(item)) rel=(rel[item]) == item
|
19
|
+
|
20
|
+
- when String # current page
|
21
|
+
span.page.current ==> item
|
22
|
+
|
23
|
+
- when :gap # page gap
|
24
|
+
span.page.gap ==> pagy_t('pagy.nav.gap')
|
25
|
+
|
26
|
+
span.page.next class=('disabled' unless pagy.next)
|
27
|
+
- if pagy.next
|
28
|
+
a href=(pagy_url_for(pagy.next)) rel="next" aria-label="next" == pagy_t('pagy.nav.next')
|
29
|
+
- else
|
30
|
+
== pagy_t('pagy.nav.next')
|
@@ -0,0 +1,32 @@
|
|
1
|
+
<%#
|
2
|
+
This template uses only the pagy_url_for helper from pagy and link_to/link_to_if from rails
|
3
|
+
No special optimization for speed and memory. Use the pagy helpers if speed and memory are important.
|
4
|
+
-%>
|
5
|
+
<% rel = { pagy.prev => 'prev', pagy.next => 'next' } %>
|
6
|
+
|
7
|
+
<nav aria-label="pager" class="pagination" role="navigation">
|
8
|
+
|
9
|
+
<span class="page prev <%= 'disabled' unless pagy.prev %>">
|
10
|
+
<%= link_to_if pagy.prev, pagy_t('pagy.nav.prev').html_safe, pagy_url_for(pagy.prev), rel: 'prev', 'aria-label': "previous" %>
|
11
|
+
</span>
|
12
|
+
|
13
|
+
<% pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36] -%>
|
14
|
+
<% case item
|
15
|
+
|
16
|
+
when Integer -%>
|
17
|
+
<span class="page"><%= link_to item, pagy_url_for(item), rel: rel[item] %></span>
|
18
|
+
|
19
|
+
<% when String -%>
|
20
|
+
<span class="page current"><%= item %></span>
|
21
|
+
|
22
|
+
<% when :gap -%>
|
23
|
+
<span class="page gap"><%== pagy_t('pagy.nav.gap') %></span>
|
24
|
+
|
25
|
+
<% end -%>
|
26
|
+
<% end -%>
|
27
|
+
|
28
|
+
<span class="page next <%= 'disabled' unless pagy.next %>">
|
29
|
+
<%= link_to_if pagy.next, pagy_t('pagy.nav.next').html_safe, pagy_url_for(pagy.next), rel: 'next', 'aria-label': "next" %>
|
30
|
+
</span>
|
31
|
+
|
32
|
+
</nav>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
-# This template uses only the pagy_url_for helper from pagy and link_to/link_to_if from rails
|
2
|
+
-# No special optimization for speed and memory. Use the pagy helpers if speed and memory are important.
|
3
|
+
|
4
|
+
- rel = { pagy.prev => 'prev', pagy.next => 'next' }
|
5
|
+
|
6
|
+
%nav.pagination{"aria-label" => "pager", :role => "navigation"}
|
7
|
+
|
8
|
+
%span{:class => "page prev #{'disabled' unless pagy.prev}"}
|
9
|
+
= link_to_if pagy.prev, pagy_t('pagy.nav.prev').html_safe, pagy_url_for(pagy.prev), rel: 'prev', 'aria-label': "previous"
|
10
|
+
|
11
|
+
- pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
|
12
|
+
- case item
|
13
|
+
|
14
|
+
- when Integer # page link
|
15
|
+
%span.page= link_to item, pagy_url_for(item), rel: rel[item]
|
16
|
+
|
17
|
+
- when String # current page
|
18
|
+
%span.page.current= item
|
19
|
+
|
20
|
+
- when :gap # page gap
|
21
|
+
%span.page.gap!= pagy_t('pagy.nav.gap')
|
22
|
+
|
23
|
+
%span{:class => "page next #{'disabled' unless pagy.next}"}
|
24
|
+
= link_to_if pagy.next, pagy_t('pagy.nav.next').html_safe, pagy_url_for(pagy.next), rel: 'next', 'aria-label': "next"
|
@@ -0,0 +1,23 @@
|
|
1
|
+
/ This template uses only the pagy_url_for helper from pagy and link_to/link_to_if from rails
|
2
|
+
/ No special optimization for speed and memory. Use the pagy helpers if speed and memory are important.
|
3
|
+
|
4
|
+
- rel = { pagy.prev => 'prev', pagy.next => 'next' }
|
5
|
+
|
6
|
+
nav.pagination role="navigation" aria-label="pager"
|
7
|
+
|
8
|
+
span.page.prev> class=('disabled' unless pagy.prev)
|
9
|
+
== link_to_if pagy.prev, pagy_t('pagy.nav.prev').html_safe, pagy_url_for(pagy.prev), rel: 'prev', 'aria-label': "previous"
|
10
|
+
|
11
|
+
- pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
|
12
|
+
- case item
|
13
|
+
- when Integer # page link
|
14
|
+
span.page ==> link_to item, pagy_url_for(item), rel: rel[item]
|
15
|
+
|
16
|
+
- when String # current page
|
17
|
+
span.page.current ==> item
|
18
|
+
|
19
|
+
- when :gap # page gap
|
20
|
+
span.page.gap ==> pagy_t('pagy.nav.gap')
|
21
|
+
|
22
|
+
span.page.next class=('disabled' unless pagy.next)
|
23
|
+
== link_to_if pagy.next, pagy_t('pagy.nav.next').html_safe, pagy_url_for(pagy.next), rel: 'next', 'aria-label': "next"
|
data/pagy.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'pagy'
|
5
|
+
require 'date'
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = 'pagy'
|
9
|
+
s.version = Pagy::VERSION
|
10
|
+
s.authors = ['Domizio Demichelis']
|
11
|
+
s.email = ['dd.nexus@gmail.com']
|
12
|
+
s.date = Date.today.to_s
|
13
|
+
|
14
|
+
s.summary = %q{Because pagination should not suck!}
|
15
|
+
s.description = %q{Dead simple pagination in pure ruby. Easy, fast and very light. No restrictions imposed: use it with any MVC framework, any ORM, any DB type, any templating system or none at all. Use the built-in templates or create yours the way you want.}
|
16
|
+
s.homepage = 'https://github.com/ddnexus/pagy'
|
17
|
+
s.license = 'MIT'
|
18
|
+
s.require_paths = ['lib']
|
19
|
+
|
20
|
+
s.files = `git ls-files -z`.split("\x0")
|
21
|
+
.reject{|f| f.start_with? '.', 'test', 'Gemfile', 'Rakefile' }
|
22
|
+
|
23
|
+
s.add_development_dependency 'bundler', '~> 1.16'
|
24
|
+
s.add_development_dependency 'rake', '~> 10.0'
|
25
|
+
s.add_development_dependency 'minitest', '~> 5.0'
|
26
|
+
s.add_development_dependency 'slim'
|
27
|
+
s.add_development_dependency 'haml'
|
28
|
+
s.add_development_dependency 'benchmark-ips'
|
29
|
+
s.add_development_dependency 'kalibera'
|
30
|
+
s.add_development_dependency 'memory_profiler'
|
31
|
+
|
32
|
+
end
|
metadata
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pagy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Domizio Demichelis
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-02-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.16'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.16'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '5.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '5.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: slim
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: haml
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: benchmark-ips
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: kalibera
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: memory_profiler
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
description: 'Dead simple pagination in pure ruby. Easy, fast and very light. No restrictions
|
126
|
+
imposed: use it with any MVC framework, any ORM, any DB type, any templating system
|
127
|
+
or none at all. Use the built-in templates or create yours the way you want.'
|
128
|
+
email:
|
129
|
+
- dd.nexus@gmail.com
|
130
|
+
executables: []
|
131
|
+
extensions: []
|
132
|
+
extra_rdoc_files: []
|
133
|
+
files:
|
134
|
+
- LICENSE.txt
|
135
|
+
- README.md
|
136
|
+
- lib/locales/pagy.yml
|
137
|
+
- lib/pagy.rb
|
138
|
+
- lib/pagy/backend.rb
|
139
|
+
- lib/pagy/frontend.rb
|
140
|
+
- lib/templates/bootstrap-no-dep.html.haml
|
141
|
+
- lib/templates/bootstrap-no-dep.html.slim
|
142
|
+
- lib/templates/bootstrap-rails-dep.html.erb
|
143
|
+
- lib/templates/default-no-dep.html.haml
|
144
|
+
- lib/templates/default-no-dep.html.slim
|
145
|
+
- lib/templates/default-rails-dep.html.erb
|
146
|
+
- lib/templates/default-rails-dep.html.haml
|
147
|
+
- lib/templates/default-rails-dep.html.slim
|
148
|
+
- pagy.gemspec
|
149
|
+
homepage: https://github.com/ddnexus/pagy
|
150
|
+
licenses:
|
151
|
+
- MIT
|
152
|
+
metadata: {}
|
153
|
+
post_install_message:
|
154
|
+
rdoc_options: []
|
155
|
+
require_paths:
|
156
|
+
- lib
|
157
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
158
|
+
requirements:
|
159
|
+
- - ">="
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: '0'
|
162
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
requirements: []
|
168
|
+
rubyforge_project:
|
169
|
+
rubygems_version: 2.7.4
|
170
|
+
signing_key:
|
171
|
+
specification_version: 4
|
172
|
+
summary: Because pagination should not suck!
|
173
|
+
test_files: []
|