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