pagy 5.7.5 → 8.6.2
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 +4 -4
- data/LICENSE.txt +1 -1
- data/apps/calendar.ru +745 -0
- data/apps/demo.ru +435 -0
- data/apps/rails.ru +213 -0
- data/apps/repro.ru +177 -0
- data/apps/tmp/calendar.sqlite3 +0 -0
- data/apps/tmp/calendar.sqlite3-shm +0 -0
- data/apps/tmp/calendar.sqlite3-wal +0 -0
- data/apps/tmp/local_secret.txt +1 -0
- data/bin/pagy +100 -0
- data/{lib/config → config}/pagy.rb +72 -96
- data/javascripts/pagy-module.js +100 -0
- data/javascripts/pagy.d.ts +5 -0
- data/javascripts/pagy.js +4 -0
- data/javascripts/pagy.min.js +4 -0
- data/javascripts/pagy.min.js.map +10 -0
- data/javascripts/pagy.mjs +100 -0
- data/lib/optimist.rb +1022 -0
- data/lib/pagy/backend.rb +16 -4
- data/lib/pagy/calendar/day.rb +22 -10
- data/lib/pagy/calendar/month.rb +35 -9
- data/lib/pagy/calendar/quarter.rb +36 -10
- data/lib/pagy/calendar/unit.rb +106 -0
- data/lib/pagy/calendar/week.rb +16 -16
- data/lib/pagy/calendar/year.rb +15 -9
- data/lib/pagy/calendar.rb +60 -68
- data/lib/pagy/console.rb +3 -3
- data/lib/pagy/countless.rb +17 -12
- data/lib/pagy/exceptions.rb +1 -1
- data/lib/pagy/extras/arel.rb +2 -2
- data/lib/pagy/extras/array.rb +2 -2
- data/lib/pagy/extras/bootstrap.rb +57 -53
- data/lib/pagy/extras/bulma.rb +53 -57
- data/lib/pagy/extras/calendar.rb +54 -37
- data/lib/pagy/extras/countless.rb +3 -3
- data/lib/pagy/extras/elasticsearch_rails.rb +12 -11
- data/lib/pagy/extras/foundation.rb +59 -54
- data/lib/pagy/extras/gearbox.rb +32 -19
- data/lib/pagy/extras/headers.rb +11 -11
- data/lib/pagy/extras/i18n.rb +5 -5
- data/lib/pagy/extras/items.rb +34 -24
- data/lib/pagy/extras/{frontend_helpers.rb → js_tools.rb} +24 -24
- data/lib/pagy/extras/jsonapi.rb +79 -0
- data/lib/pagy/extras/materialize.rb +63 -47
- data/lib/pagy/extras/meilisearch.rb +26 -22
- data/lib/pagy/extras/metadata.rb +13 -9
- data/lib/pagy/extras/overflow.rb +13 -10
- data/lib/pagy/extras/pagy.rb +82 -0
- data/lib/pagy/extras/searchkick.rb +12 -11
- data/lib/pagy/extras/semantic.rb +57 -45
- data/lib/pagy/extras/size.rb +40 -0
- data/lib/pagy/extras/standalone.rb +12 -16
- data/lib/pagy/extras/trim.rb +13 -13
- data/lib/pagy/extras/uikit.rb +60 -46
- data/lib/pagy/frontend.rb +62 -45
- data/lib/pagy/i18n.rb +4 -3
- data/lib/pagy/url_helpers.rb +13 -25
- data/lib/pagy.rb +61 -59
- data/locales/ar.yml +28 -0
- data/locales/be.yml +25 -0
- data/locales/bg.yml +21 -0
- data/locales/bs.yml +25 -0
- data/locales/ca.yml +21 -0
- data/locales/ckb.yml +18 -0
- data/locales/cs.yml +23 -0
- data/locales/da.yml +21 -0
- data/locales/de.yml +21 -0
- data/locales/en.yml +21 -0
- data/locales/es.yml +21 -0
- data/locales/fr.yml +21 -0
- data/locales/hr.yml +25 -0
- data/locales/id.yml +19 -0
- data/locales/it.yml +21 -0
- data/locales/ja.yml +19 -0
- data/locales/km.yml +19 -0
- data/locales/ko.yml +17 -0
- data/locales/nb.yml +21 -0
- data/locales/nl.yml +21 -0
- data/locales/nn.yml +21 -0
- data/locales/pl.yml +25 -0
- data/locales/pt-BR.yml +21 -0
- data/locales/pt.yml +21 -0
- data/locales/ru.yml +25 -0
- data/locales/sr.yml +25 -0
- data/locales/sv-SE.yml +21 -0
- data/locales/sv.yml +21 -0
- data/locales/sw.yml +23 -0
- data/locales/ta.yml +23 -0
- data/locales/tr.yml +19 -0
- data/locales/uk.yml +25 -0
- data/locales/vi.yml +17 -0
- data/locales/zh-CN.yml +19 -0
- data/locales/zh-HK.yml +19 -0
- data/locales/zh-TW.yml +19 -0
- data/stylesheets/pagy.css +46 -0
- data/stylesheets/pagy.scss +48 -0
- data/stylesheets/pagy.tailwind.css +21 -0
- metadata +79 -66
- data/lib/javascripts/pagy-dev.js +0 -118
- data/lib/javascripts/pagy-module.d.ts +0 -30
- data/lib/javascripts/pagy-module.js +0 -117
- data/lib/javascripts/pagy.js +0 -1
- data/lib/locales/ar.yml +0 -26
- data/lib/locales/bg.yml +0 -22
- data/lib/locales/bs.yml +0 -24
- data/lib/locales/ca.yml +0 -22
- data/lib/locales/cs.yml +0 -22
- data/lib/locales/da.yml +0 -22
- data/lib/locales/de.yml +0 -22
- data/lib/locales/en.yml +0 -22
- data/lib/locales/es.yml +0 -22
- data/lib/locales/fr.yml +0 -22
- data/lib/locales/hr.yml +0 -24
- data/lib/locales/id.yml +0 -20
- data/lib/locales/it.yml +0 -22
- data/lib/locales/ja.yml +0 -20
- data/lib/locales/km.yml +0 -19
- data/lib/locales/ko.yml +0 -20
- data/lib/locales/nb.yml +0 -22
- data/lib/locales/nl.yml +0 -22
- data/lib/locales/pl.yml +0 -24
- data/lib/locales/pt-BR.yml +0 -22
- data/lib/locales/pt.yml +0 -22
- data/lib/locales/ru.yml +0 -24
- data/lib/locales/sr.yml +0 -23
- data/lib/locales/sv-SE.yml +0 -23
- data/lib/locales/sv.yml +0 -23
- data/lib/locales/sw.yml +0 -22
- data/lib/locales/ta.yml +0 -22
- data/lib/locales/tr.yml +0 -20
- data/lib/locales/uk.yml +0 -24
- data/lib/locales/zh-CN.yml +0 -20
- data/lib/locales/zh-HK.yml +0 -20
- data/lib/locales/zh-TW.yml +0 -20
- data/lib/pagy/calendar/month_mixin.rb +0 -49
- data/lib/pagy/extras/navs.rb +0 -63
- data/lib/pagy/extras/support.rb +0 -54
- data/lib/templates/bootstrap_nav.html.erb +0 -24
- data/lib/templates/bootstrap_nav.html.haml +0 -34
- data/lib/templates/bootstrap_nav.html.slim +0 -34
- data/lib/templates/bulma_nav.html.erb +0 -24
- data/lib/templates/bulma_nav.html.haml +0 -32
- data/lib/templates/bulma_nav.html.slim +0 -32
- data/lib/templates/foundation_nav.html.erb +0 -24
- data/lib/templates/foundation_nav.html.haml +0 -34
- data/lib/templates/foundation_nav.html.slim +0 -34
- data/lib/templates/nav.html.erb +0 -22
- data/lib/templates/nav.html.haml +0 -30
- data/lib/templates/nav.html.slim +0 -29
- data/lib/templates/uikit_nav.html.erb +0 -15
- data/lib/templates/uikit_nav.html.haml +0 -28
- data/lib/templates/uikit_nav.html.slim +0 -28
data/apps/demo.ru
ADDED
@@ -0,0 +1,435 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Interactive showcase for all the pagy helpers and CSS styles
|
4
|
+
|
5
|
+
# DEMO USAGE
|
6
|
+
# pagy demo
|
7
|
+
|
8
|
+
# DEV USAGE
|
9
|
+
# pagy clone demo
|
10
|
+
# pagy ./demo.ru
|
11
|
+
|
12
|
+
# URL
|
13
|
+
# http://0.0.0.0:8000
|
14
|
+
|
15
|
+
# HELP
|
16
|
+
# pagy -h
|
17
|
+
|
18
|
+
# DOC
|
19
|
+
# https://ddnexus.github.io/pagy/playground/#3-demo-app
|
20
|
+
|
21
|
+
VERSION = '8.6.2'
|
22
|
+
|
23
|
+
require 'bundler/inline'
|
24
|
+
require 'bundler'
|
25
|
+
Bundler.configure
|
26
|
+
gemfile(ENV['PAGY_INSTALL_BUNDLE'] == 'true') do
|
27
|
+
source 'https://rubygems.org'
|
28
|
+
gem 'oj'
|
29
|
+
gem 'puma'
|
30
|
+
gem 'rouge'
|
31
|
+
gem 'sinatra'
|
32
|
+
gem 'sinatra-contrib'
|
33
|
+
end
|
34
|
+
|
35
|
+
# pagy initializer
|
36
|
+
STYLES = { pagy: { extra: 'pagy', prefix: '', css_anchor: 'pagy-scss' },
|
37
|
+
bootstrap: {},
|
38
|
+
bulma: {},
|
39
|
+
tailwind: { extra: 'pagy', prefix: '', css_anchor: 'pagy-tailwind-css' } }.freeze
|
40
|
+
|
41
|
+
STYLES.each_key do |style|
|
42
|
+
require "pagy/extras/#{STYLES[style][:extra] || style}"
|
43
|
+
end
|
44
|
+
require 'pagy/extras/items'
|
45
|
+
require 'pagy/extras/trim'
|
46
|
+
Pagy::DEFAULT[:trim_extra] = false # opt-in trim
|
47
|
+
|
48
|
+
# sinatra setup
|
49
|
+
require 'sinatra/base'
|
50
|
+
|
51
|
+
# sinatra application
|
52
|
+
class PagyDemo < Sinatra::Base
|
53
|
+
configure do
|
54
|
+
enable :inline_templates
|
55
|
+
end
|
56
|
+
|
57
|
+
include Pagy::Backend
|
58
|
+
|
59
|
+
get '/' do
|
60
|
+
redirect '/pagy'
|
61
|
+
end
|
62
|
+
|
63
|
+
get '/template' do
|
64
|
+
collection = MockCollection.new
|
65
|
+
@pagy, @records = pagy(collection, trim_extra: params['trim'])
|
66
|
+
|
67
|
+
erb :template, locals: { pagy: @pagy, style: 'pagy' }
|
68
|
+
end
|
69
|
+
|
70
|
+
get('/javascripts/:file') do
|
71
|
+
format = params[:file].split('.').last
|
72
|
+
if format == 'js'
|
73
|
+
content_type 'application/javascript'
|
74
|
+
elsif format == 'map'
|
75
|
+
content_type 'application/json'
|
76
|
+
end
|
77
|
+
send_file Pagy.root.join('javascripts', params[:file])
|
78
|
+
end
|
79
|
+
|
80
|
+
get('/stylesheets/:file') do
|
81
|
+
content_type 'text/css'
|
82
|
+
send_file Pagy.root.join('stylesheets', params[:file])
|
83
|
+
end
|
84
|
+
|
85
|
+
# one route/action per style
|
86
|
+
STYLES.each_key do |style|
|
87
|
+
prefix = STYLES[style][:prefix] || "_#{style}"
|
88
|
+
|
89
|
+
get("/#{style}/?:trim?") do
|
90
|
+
collection = MockCollection.new
|
91
|
+
@pagy, @records = pagy(collection, trim_extra: params['trim'])
|
92
|
+
|
93
|
+
erb :helpers, locals: { style:, prefix: }
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
helpers do
|
98
|
+
include Pagy::Frontend
|
99
|
+
|
100
|
+
def style_menu
|
101
|
+
html = +%(<div id="style-menu"> )
|
102
|
+
STYLES.each_key { |style| html << %(<a href="/#{style}">#{style}</a>) }
|
103
|
+
html << %(<a href="/template">template</a>)
|
104
|
+
html << %(</div>)
|
105
|
+
end
|
106
|
+
|
107
|
+
def highlight(html, format: :html)
|
108
|
+
if format == :html
|
109
|
+
html = html.gsub(/>[\s]*</, '><').strip # template single line no spaces around/between tags
|
110
|
+
html = Formatter.new.format(html)
|
111
|
+
end
|
112
|
+
lexer = Rouge::Lexers::ERB.new
|
113
|
+
formatter = Rouge::Formatters::HTMLInline.new('monokai.sublime')
|
114
|
+
summary = { html: 'Served HTML (pretty formatted)', erb: 'ERB Template' }
|
115
|
+
%(<details><summary>#{summary[format]}</summary><pre>\n#{
|
116
|
+
formatter.format(lexer.lex(html))
|
117
|
+
}</pre></details>)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# Cheap pagy formatter for helpers output
|
123
|
+
class Formatter
|
124
|
+
INDENT = ' '
|
125
|
+
TEXT_SPACE = "\u00B7"
|
126
|
+
TEXT = /^([^<>]+)(.*)/
|
127
|
+
UNPAIRED = /^(<(input|link).*?>)(.*)/
|
128
|
+
PAIRED = %r{^(<(head|nav|div|span|p|a|b|label|ul|li).*?>)(.*?)(</\2>)(.*)}
|
129
|
+
WRAPPER = /<.*?>/
|
130
|
+
DATA_PAGY = /(data-pagy="([^"]+)")/
|
131
|
+
|
132
|
+
def initialize
|
133
|
+
@formatted = +''
|
134
|
+
end
|
135
|
+
|
136
|
+
def format(input, level = 0)
|
137
|
+
process(input, level)
|
138
|
+
@formatted
|
139
|
+
end
|
140
|
+
|
141
|
+
private
|
142
|
+
|
143
|
+
def process(input, level)
|
144
|
+
push = ->(content) { @formatted << ((INDENT * level) << content << "\n") }
|
145
|
+
rest = nil
|
146
|
+
if (match = input.match(TEXT))
|
147
|
+
text, rest = match.captures
|
148
|
+
push.(text.gsub(' ', TEXT_SPACE))
|
149
|
+
elsif (match = input.match(UNPAIRED))
|
150
|
+
tag, _name, rest = match.captures
|
151
|
+
push.(tag)
|
152
|
+
elsif (match = input.match(PAIRED))
|
153
|
+
tag_start, name, block, tag_end, rest = match.captures
|
154
|
+
## Handle incomplete same-tag nesting
|
155
|
+
while block.scan(/<#{name}.*?>/).size > block.scan(tag_end).size
|
156
|
+
more, rest = rest.split(tag_end, 2)
|
157
|
+
block << tag_end << more
|
158
|
+
end
|
159
|
+
if (match = tag_start.match(DATA_PAGY))
|
160
|
+
search, data = match.captures
|
161
|
+
formatted = data.scan(/.{1,76}/).join("\n")
|
162
|
+
replace = %(\n#{INDENT * (level + 1)}data-pagy="#{formatted}")
|
163
|
+
tag_start.sub!(search, replace)
|
164
|
+
end
|
165
|
+
if block.match(WRAPPER)
|
166
|
+
push.(tag_start)
|
167
|
+
process(block, level + 1)
|
168
|
+
push.(tag_end)
|
169
|
+
else
|
170
|
+
push.(tag_start << block << tag_end)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
process(rest, level) if rest
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
# Simple array-based collection that acts as a standard DB collection.
|
178
|
+
class MockCollection < Array
|
179
|
+
def initialize(arr = Array(1..1000))
|
180
|
+
super
|
181
|
+
@collection = clone
|
182
|
+
end
|
183
|
+
|
184
|
+
def offset(value)
|
185
|
+
@collection = self[value..]
|
186
|
+
self
|
187
|
+
end
|
188
|
+
|
189
|
+
def limit(value)
|
190
|
+
@collection[0, value]
|
191
|
+
end
|
192
|
+
|
193
|
+
def count(*)
|
194
|
+
size
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
run PagyDemo
|
199
|
+
|
200
|
+
# We store the template in a constant instead of writing it inline, so we can highlight it more easily
|
201
|
+
TEMPLATE = <<~ERB
|
202
|
+
<%# IMPORTANT: use '<%== ... ' instead of '<%= ... ' if you run this in rails %>
|
203
|
+
|
204
|
+
<%# The a variable below is set to a lambda that generates the a tag %>
|
205
|
+
<%# Usage: a_tag = a.(page_number, text, classes: nil, aria_label: nil) %>
|
206
|
+
<% a = pagy_anchor(pagy) %>
|
207
|
+
<nav class="pagy nav" aria-label="Pages">
|
208
|
+
<%# Previous page link %>
|
209
|
+
<% if pagy.prev %>
|
210
|
+
<%= a.(pagy.prev, '<', aria_label: 'Previous') %>
|
211
|
+
<% else %>
|
212
|
+
<a role="link" aria-disabled="true" aria-label="Previous"><</a>
|
213
|
+
<% end %>
|
214
|
+
<%# Page links (series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]) %>
|
215
|
+
<% pagy.series.each do |item| %>
|
216
|
+
<% if item.is_a?(Integer) %>
|
217
|
+
<%= a.(item) %>
|
218
|
+
<% elsif item.is_a?(String) %>
|
219
|
+
<a role="link" aria-disabled="true" aria-current="page" class="current"><%= item %></a>
|
220
|
+
<% elsif item == :gap %>
|
221
|
+
<a role="link" aria-disabled="true" class="gap">…</a>
|
222
|
+
<% end %>
|
223
|
+
<% end %>
|
224
|
+
<%# Next page link %>
|
225
|
+
<% if pagy.next %>
|
226
|
+
<%= a.(pagy.next, '>', aria_label: 'Next') %>
|
227
|
+
<% else %>
|
228
|
+
<a role="link" aria-disabled="true" aria-label="Next"><</a>
|
229
|
+
<% end %>
|
230
|
+
</nav>
|
231
|
+
ERB
|
232
|
+
|
233
|
+
__END__
|
234
|
+
|
235
|
+
@@ layout
|
236
|
+
<!DOCTYPE html>
|
237
|
+
<html lang="en">
|
238
|
+
<head>
|
239
|
+
<title>Pagy Demo App</title>
|
240
|
+
<script src="/javascripts/pagy.min.js"></script>
|
241
|
+
<script>
|
242
|
+
window.addEventListener("load", Pagy.init);
|
243
|
+
</script>
|
244
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
245
|
+
<%= erb :"#{style}_head" if defined?(style) %>
|
246
|
+
<style type="text/css">
|
247
|
+
@media screen { html, body {
|
248
|
+
font-size: 1rem;
|
249
|
+
line-height: 1.2s;
|
250
|
+
padding: 0;
|
251
|
+
margin: 0;
|
252
|
+
} }
|
253
|
+
body {
|
254
|
+
background: white !important;
|
255
|
+
margin: 0 !important;
|
256
|
+
font-family: sans-serif !important;
|
257
|
+
}
|
258
|
+
h1, h2 {
|
259
|
+
font-size: 1.8rem !important;
|
260
|
+
font-weight: 600 !important;
|
261
|
+
margin-top: 1rem !important;
|
262
|
+
margin-bottom: 0.7rem !important;
|
263
|
+
line-height: 1.5 !important;
|
264
|
+
color: rgb(90 90 90) !important;
|
265
|
+
}
|
266
|
+
h2 {
|
267
|
+
font-family: monospace;
|
268
|
+
font-size: .9rem !important;
|
269
|
+
margin-top: 1.6rem !important;
|
270
|
+
}
|
271
|
+
summary, .notes {
|
272
|
+
font-size: .8rem;
|
273
|
+
color: gray;
|
274
|
+
margin-top: .6rem;
|
275
|
+
font-style: italic;
|
276
|
+
cursor: pointer;
|
277
|
+
}
|
278
|
+
.notes {
|
279
|
+
font-family: sans-serif;
|
280
|
+
font-weight: normal;
|
281
|
+
}
|
282
|
+
.notes code{
|
283
|
+
background-color: #E8E8E8;
|
284
|
+
padding: 0 0.3rem;
|
285
|
+
font-style: normal;
|
286
|
+
border-radius: 3px;
|
287
|
+
}
|
288
|
+
.description {
|
289
|
+
margin: 1rem 0;
|
290
|
+
}
|
291
|
+
.description a {
|
292
|
+
color: blue;
|
293
|
+
text-decoration: underline;
|
294
|
+
}
|
295
|
+
pre, pre code {
|
296
|
+
display: block;
|
297
|
+
margin-top: .3rem;
|
298
|
+
margin-bottom: 1rem;
|
299
|
+
font-size: .8rem !important;
|
300
|
+
line-height: 1rem !important;
|
301
|
+
color: white;
|
302
|
+
background-color: rgb(30 30 30);
|
303
|
+
padding: 1rem;
|
304
|
+
overflow: auto;
|
305
|
+
}
|
306
|
+
.content {
|
307
|
+
padding: 0 1.5rem 2rem !important;
|
308
|
+
}
|
309
|
+
|
310
|
+
#style-menu {
|
311
|
+
flex;
|
312
|
+
font-family: sans-serif;
|
313
|
+
font-size: 1.1rem;
|
314
|
+
line-height: 1.5rem;
|
315
|
+
white-space: nowrap;
|
316
|
+
color: white;
|
317
|
+
background-color: gray;
|
318
|
+
padding: .2rem 1.5rem;
|
319
|
+
}
|
320
|
+
#style-menu > :not([hidden]) ~ :not([hidden]) {
|
321
|
+
--space-reverse: 0;
|
322
|
+
margin-right: calc(0.5rem * var(--space-reverse));
|
323
|
+
margin-left: calc(0.5rem * calc(1 - var(--space-reverse)));
|
324
|
+
}
|
325
|
+
#style-menu a {
|
326
|
+
color: inherit;
|
327
|
+
text-decoration: none;
|
328
|
+
}
|
329
|
+
/* Quick demo for overriding the element style attribute of certain pagy helpers
|
330
|
+
.pagy input[style] {
|
331
|
+
width: 5rem !important;
|
332
|
+
}
|
333
|
+
*/
|
334
|
+
</style>
|
335
|
+
</head>
|
336
|
+
<body>
|
337
|
+
<!-- each different class used by each style -->
|
338
|
+
<%= style_menu %>
|
339
|
+
<div class="content">
|
340
|
+
<%= yield %>
|
341
|
+
</div>
|
342
|
+
</body>
|
343
|
+
</html>
|
344
|
+
|
345
|
+
|
346
|
+
@@ pagy_head
|
347
|
+
<!-- copy and paste the pagy style in order to edit it -->
|
348
|
+
<link rel="stylesheet" href="/stylesheets/pagy.css">
|
349
|
+
|
350
|
+
@@ bootstrap_head
|
351
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css">
|
352
|
+
|
353
|
+
@@ bulma_head
|
354
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
|
355
|
+
|
356
|
+
@@ tailwind_head
|
357
|
+
<script src="https://cdn.tailwindcss.com?plugins=forms,typography,aspect-ratio"></script>
|
358
|
+
<!-- copy and paste the pagy.tailwind style in order to edit it -->
|
359
|
+
<style type="text/tailwindcss">
|
360
|
+
<%= Pagy.root.join('stylesheets', 'pagy.tailwind.css').read %>
|
361
|
+
</style>
|
362
|
+
|
363
|
+
|
364
|
+
@@ helpers
|
365
|
+
<h1><%= style %></h1>
|
366
|
+
<% extra = STYLES[style][:extra] || "#{style}" %>
|
367
|
+
<% css_anchor = STYLES[style][:css_anchor] %>
|
368
|
+
|
369
|
+
<p class="description">See the <a href="http://ddnexus.github.io/pagy/docs/extras/<%= extra %>" target="blank"><%= extra %> extra</a>
|
370
|
+
documentation
|
371
|
+
<% if css_anchor %>
|
372
|
+
and the <a href="http://ddnexus.github.io/pagy/docs/api/stylesheets/#<%= css_anchor %>" target="blank"><%= css_anchor.gsub('-', '.') %></a>
|
373
|
+
<% end %>
|
374
|
+
for details</p>
|
375
|
+
|
376
|
+
<h2>Collection</h2>
|
377
|
+
<p id="records">@records: <%= @records.join(',') %></p>
|
378
|
+
|
379
|
+
<h2>pagy<%= prefix %>_nav <span class="notes">Simple nav <code>size: 5</code></span></h2>
|
380
|
+
<%= html = send(:"pagy#{prefix}_nav", @pagy, id: 'simple-nav', aria_label: 'Pages simple-nav', size: 5) %>
|
381
|
+
<%= highlight(html) %>
|
382
|
+
|
383
|
+
<h2>pagy<%= prefix %>_nav <span class="notes">Fast nav <code>size: 7</code></span></h2>
|
384
|
+
<%= html = send(:"pagy#{prefix}_nav", @pagy, id: 'nav', aria_label: 'Pages nav') %>
|
385
|
+
<%= highlight(html) %>
|
386
|
+
|
387
|
+
<h2>pagy<%= prefix %>_nav_js <span class="notes">Fast nav <code>size: 7</code></span></h2>
|
388
|
+
<%= html = send(:"pagy#{prefix}_nav_js", @pagy, id: 'nav-js', aria_label: 'Pages nav_js') %>
|
389
|
+
<%= highlight(html) %>
|
390
|
+
|
391
|
+
<h2>pagy<%= prefix %>_nav_js <span class="notes">Responsive nav <code>steps: {...}</code> (Resize the window to see)</span></h2>
|
392
|
+
<%= html = send(:"pagy#{prefix}_nav_js", @pagy, id: 'nav-js-responsive',
|
393
|
+
aria_label: 'Pages nav_js_responsive',
|
394
|
+
steps: { 0 => 5, 500 => 7, 750 => 9, 1000 => 11 }) %>
|
395
|
+
<%= highlight(html) %>
|
396
|
+
|
397
|
+
<h2>pagy<%= prefix %>_combo_nav_js</h2>
|
398
|
+
<%= html = send(:"pagy#{prefix}_combo_nav_js", @pagy, id: 'combo-nav-js', aria_label: 'Pages combo_nav_js') %>
|
399
|
+
<%= highlight(html) %>
|
400
|
+
|
401
|
+
<h2>pagy_info</h2>
|
402
|
+
<%= html = pagy_info(@pagy, id: 'pagy-info') %>
|
403
|
+
<%= highlight(html) %>
|
404
|
+
|
405
|
+
<% if style.match(/pagy|tailwind/) %>
|
406
|
+
<h2>pagy_items_selector_js</h2>
|
407
|
+
<%= html = pagy_items_selector_js(@pagy, id: 'items-selector-js') %>
|
408
|
+
<%= highlight(html) %>
|
409
|
+
|
410
|
+
<h2>pagy_prev_a / pagy_next_a</h2>
|
411
|
+
<%= html = '<nav class="pagy" id="prev-next" aria-label="Pagy prev-next">' << pagy_prev_a(@pagy) << pagy_next_a(@pagy) << '</nav>' %>
|
412
|
+
<%= highlight(html) %>
|
413
|
+
|
414
|
+
<h2>pagy_prev_link / pagy_next_link <span class="notes">Link not rendered<span></h2>
|
415
|
+
<% html = '<head>' << (pagy_prev_link(@pagy)||'') << (pagy_next_link(@pagy)||'') << '</head>' %>
|
416
|
+
<%= highlight(html) %>
|
417
|
+
<% end %>
|
418
|
+
|
419
|
+
|
420
|
+
@@ template
|
421
|
+
<h1>Pagy Template Demo</h1>
|
422
|
+
|
423
|
+
<p class="description">
|
424
|
+
See the <a href="https://ddnexus.github.io/pagy/docs/how-to/#using-your-pagination-templates">
|
425
|
+
Custom Templates</a> documentation.
|
426
|
+
</p>
|
427
|
+
<h2>Collection</h2>
|
428
|
+
<p id="records">@records: <%= @records.join(',') %></p>
|
429
|
+
|
430
|
+
<h2>Rendered ERB template</h2>
|
431
|
+
|
432
|
+
<%# We don't inline the template here, so we can highlight it more easily %>
|
433
|
+
<%= html = ERB.new(TEMPLATE).result(binding) %>
|
434
|
+
<%= highlight(TEMPLATE, format: :erb) %>
|
435
|
+
<%= highlight(html) %>
|
data/apps/rails.ru
ADDED
@@ -0,0 +1,213 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Starting point to reproduce rails related pagy issues
|
4
|
+
|
5
|
+
# DEV USAGE
|
6
|
+
# pagy clone rails
|
7
|
+
# pagy ./rails.ru
|
8
|
+
|
9
|
+
# URL
|
10
|
+
# http://0.0.0.0:8000
|
11
|
+
|
12
|
+
# HELP
|
13
|
+
# pagy -h
|
14
|
+
|
15
|
+
# DOC
|
16
|
+
# https://ddnexus.github.io/pagy/playground/#2-rails-app
|
17
|
+
|
18
|
+
VERSION = '8.6.2'
|
19
|
+
|
20
|
+
# Gemfile
|
21
|
+
require 'bundler/inline'
|
22
|
+
require 'bundler'
|
23
|
+
Bundler.configure
|
24
|
+
gemfile(ENV['PAGY_INSTALL_BUNDLE'] == 'true') do
|
25
|
+
source 'https://rubygems.org'
|
26
|
+
gem 'oj'
|
27
|
+
gem 'puma'
|
28
|
+
gem 'rails'
|
29
|
+
# activerecord/sqlite3_adapter.rb probably useless) constraint !!!
|
30
|
+
# https://github.com/rails/rails/blame/v7.1.3.4/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb#L14
|
31
|
+
gem 'sqlite3', '~> 1.4.0'
|
32
|
+
end
|
33
|
+
|
34
|
+
# require 'rails/all' # too much stuff
|
35
|
+
require 'action_controller/railtie'
|
36
|
+
require 'active_record'
|
37
|
+
|
38
|
+
OUTPUT = Rails.env.showcase? ? IO::NULL : $stdout
|
39
|
+
|
40
|
+
# Rails config
|
41
|
+
class PagyRails < Rails::Application # :nodoc:
|
42
|
+
config.root = __dir__
|
43
|
+
config.session_store :cookie_store, key: 'cookie_store_key'
|
44
|
+
Rails.application.credentials.secret_key_base = 'absolute_secret'
|
45
|
+
|
46
|
+
config.logger = Logger.new(OUTPUT)
|
47
|
+
Rails.logger = config.logger
|
48
|
+
|
49
|
+
routes.draw do
|
50
|
+
root to: 'comments#index'
|
51
|
+
get '/javascripts/:file', to: 'pagy#javascripts', file: /.*/
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# AR config
|
56
|
+
dir = Rails.env.development? ? '.' : Dir.pwd # app dir in dev or pwd otherwise
|
57
|
+
unless File.writable?(dir)
|
58
|
+
warn "ERROR: directory #{dir.inspect} is not writable (the pagy-rails-app needs to create DB files)"
|
59
|
+
exit 1
|
60
|
+
end
|
61
|
+
|
62
|
+
# Pagy initializer
|
63
|
+
require 'pagy/extras/pagy'
|
64
|
+
require 'pagy/extras/items'
|
65
|
+
require 'pagy/extras/overflow'
|
66
|
+
Pagy::DEFAULT[:items] = 10
|
67
|
+
Pagy::DEFAULT[:overflow] = :empty_page
|
68
|
+
Pagy::DEFAULT.freeze
|
69
|
+
|
70
|
+
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: "#{dir}/tmp/pagy-rails.sqlite3")
|
71
|
+
ActiveRecord::Schema.define do
|
72
|
+
create_table :posts, force: true do |t|
|
73
|
+
t.string :title
|
74
|
+
end
|
75
|
+
|
76
|
+
create_table :comments, force: true do |t|
|
77
|
+
t.string :body
|
78
|
+
t.integer :post_id
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# Models
|
83
|
+
class Post < ActiveRecord::Base # :nodoc:
|
84
|
+
has_many :comments
|
85
|
+
end # :nodoc:
|
86
|
+
|
87
|
+
class Comment < ActiveRecord::Base # :nodoc:
|
88
|
+
belongs_to :post
|
89
|
+
end # :nodoc:
|
90
|
+
|
91
|
+
# DB seed
|
92
|
+
1.upto(11) do |pi|
|
93
|
+
Post.create(title: "Post #{pi + 1}")
|
94
|
+
end
|
95
|
+
Post.all.each_with_index do |post, pi|
|
96
|
+
2.times { |ci| Comment.create(post:, body: "Comment #{ci + 1} to Post #{pi + 1}") }
|
97
|
+
end
|
98
|
+
|
99
|
+
# Down here to avoid logging the DB seed above at each restart
|
100
|
+
ActiveRecord::Base.logger = Logger.new(OUTPUT)
|
101
|
+
|
102
|
+
# Helpers
|
103
|
+
module CommentsHelper
|
104
|
+
include Pagy::Frontend
|
105
|
+
end
|
106
|
+
|
107
|
+
# Controllers
|
108
|
+
class CommentsController < ActionController::Base # :nodoc:
|
109
|
+
include Rails.application.routes.url_helpers
|
110
|
+
include Pagy::Backend
|
111
|
+
|
112
|
+
def index
|
113
|
+
@pagy, @comments = pagy(Comment.all)
|
114
|
+
render inline: TEMPLATE
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# You don't need this in real rails apps (see https://ddnexus.github.io/pagy/docs/api/javascript/setup/#2-configure)
|
119
|
+
class PagyController < ActionController::Base
|
120
|
+
def javascripts
|
121
|
+
format = params[:file].split('.').last
|
122
|
+
if format == 'js'
|
123
|
+
render js: Pagy.root.join('javascripts', params[:file]).read
|
124
|
+
elsif format == 'map'
|
125
|
+
render json: Pagy.root.join('javascripts', params[:file]).read
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
run PagyRails
|
131
|
+
|
132
|
+
TEMPLATE = <<~ERB
|
133
|
+
<!DOCTYPE html>
|
134
|
+
<html lang="en">
|
135
|
+
<html>
|
136
|
+
<head>
|
137
|
+
<title>Pagy Rails App</title>
|
138
|
+
<script src="/javascripts/pagy.min.js"></script>
|
139
|
+
<script>
|
140
|
+
window.addEventListener("load", Pagy.init);
|
141
|
+
</script>
|
142
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
143
|
+
<style type="text/css">
|
144
|
+
@media screen { html, body {
|
145
|
+
font-size: 1rem;
|
146
|
+
line-height: 1.2s;
|
147
|
+
padding: 0;
|
148
|
+
margin: 0;
|
149
|
+
} }
|
150
|
+
body {
|
151
|
+
background: white !important;
|
152
|
+
margin: 0 !important;
|
153
|
+
font-family: sans-serif !important;
|
154
|
+
}
|
155
|
+
.content {
|
156
|
+
padding: 1rem 1.5rem 2rem !important;
|
157
|
+
}
|
158
|
+
|
159
|
+
/* Quick demo for overriding the element style attribute of certain pagy helpers
|
160
|
+
.pagy input[style] {
|
161
|
+
width: 5rem !important;
|
162
|
+
}
|
163
|
+
*/
|
164
|
+
|
165
|
+
/*
|
166
|
+
If you want to customize the style,
|
167
|
+
please replace the line below with the actual file content
|
168
|
+
*/
|
169
|
+
<%== Pagy.root.join('stylesheets', 'pagy.css').read %>
|
170
|
+
</style>
|
171
|
+
</head>
|
172
|
+
|
173
|
+
<body>
|
174
|
+
|
175
|
+
<div class="content">
|
176
|
+
<h1>Pagy Rails App</h1>
|
177
|
+
<p> Self-contained, standalone Rails app usable to easily reproduce any rails related pagy issue.</p>
|
178
|
+
<p>Please, report the following versions in any new issue.</p>
|
179
|
+
<h2>Versions</h2>
|
180
|
+
<ul>
|
181
|
+
<li>Ruby: <%== RUBY_VERSION %></li>
|
182
|
+
<li>Rack: <%== Rack::RELEASE %></li>
|
183
|
+
<li>Rails: <%== Rails.version %></li>
|
184
|
+
<li>Pagy: <%== Pagy::VERSION %></li>
|
185
|
+
</ul>
|
186
|
+
|
187
|
+
<h3>Collection</h3>
|
188
|
+
<div id="records" class="collection">
|
189
|
+
<% @comments.each do |comment| %>
|
190
|
+
<p style="margin: 0;"><%= comment.body %></p>
|
191
|
+
<% end %>
|
192
|
+
</div>
|
193
|
+
<hr>
|
194
|
+
|
195
|
+
<h4>pagy_nav</h4>
|
196
|
+
<%== pagy_nav(@pagy, id: 'nav', aria_label: 'Pages nav') %>
|
197
|
+
|
198
|
+
<h4>pagy_nav_js</h4>
|
199
|
+
<%== pagy_nav_js(@pagy, id: 'nav-js', aria_label: 'Pages nav_js') %>
|
200
|
+
|
201
|
+
<h4>pagy_combo_nav_js</h4>
|
202
|
+
<%== pagy_combo_nav_js(@pagy, id: 'combo-nav-js', aria_label: 'Pages combo_nav_js') %>
|
203
|
+
|
204
|
+
<h4>pagy_items_selector_js</h4>
|
205
|
+
<%== pagy_items_selector_js(@pagy, id: 'items-selector-js') %>
|
206
|
+
|
207
|
+
<h4>pagy_info</h4>
|
208
|
+
<%== pagy_info(@pagy, id: 'pagy-info') %>
|
209
|
+
</div>
|
210
|
+
|
211
|
+
</body>
|
212
|
+
</html>
|
213
|
+
ERB
|