pagy 4.11.0 → 5.0.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 +4 -4
- data/lib/config/pagy.rb +66 -45
- data/lib/javascripts/pagy.js +15 -6
- data/lib/pagy/backend.rb +6 -10
- data/lib/pagy/console.rb +5 -4
- data/lib/pagy/countless.rb +13 -20
- data/lib/pagy/exceptions.rb +2 -4
- data/lib/pagy/extras/arel.rb +6 -6
- data/lib/pagy/extras/array.rb +6 -6
- data/lib/pagy/extras/bootstrap.rb +32 -29
- data/lib/pagy/extras/bulma.rb +40 -32
- data/lib/pagy/extras/countless.rb +8 -9
- data/lib/pagy/extras/elasticsearch_rails.rb +64 -47
- data/lib/pagy/extras/foundation.rb +26 -26
- data/lib/pagy/extras/gearbox.rb +42 -0
- data/lib/pagy/extras/headers.rb +24 -16
- data/lib/pagy/extras/i18n.rb +7 -16
- data/lib/pagy/extras/items.rb +37 -38
- data/lib/pagy/extras/materialize.rb +28 -30
- data/lib/pagy/extras/meilisearch.rb +50 -45
- data/lib/pagy/extras/metadata.rb +29 -13
- data/lib/pagy/extras/navs.rb +24 -26
- data/lib/pagy/extras/overflow.rb +57 -60
- data/lib/pagy/extras/searchkick.rb +51 -45
- data/lib/pagy/extras/semantic.rb +28 -30
- data/lib/pagy/extras/shared.rb +44 -40
- data/lib/pagy/extras/standalone.rb +37 -42
- data/lib/pagy/extras/support.rb +14 -13
- data/lib/pagy/extras/trim.rb +10 -11
- data/lib/pagy/extras/uikit.rb +27 -28
- data/lib/pagy/frontend.rb +22 -47
- data/lib/pagy/i18n.rb +159 -0
- data/lib/pagy/url_helpers.rb +22 -0
- data/lib/pagy.rb +52 -26
- data/lib/templates/uikit_nav.html.erb +1 -1
- data/lib/templates/uikit_nav.html.slim +1 -1
- metadata +7 -10
- data/lib/locales/utils/i18n.rb +0 -17
- data/lib/locales/utils/loader.rb +0 -31
- data/lib/locales/utils/p11n.rb +0 -112
- data/lib/pagy/deprecation.rb +0 -27
data/lib/pagy/i18n.rb
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
# See Pagy::I18n API documentation https://ddnexus.github.io/pagy/api/i18n
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'yaml'
|
5
|
+
|
6
|
+
class Pagy
|
7
|
+
# Pagy i18n implementation, compatible with the I18n gem, just a lot faster and lighter
|
8
|
+
module I18n
|
9
|
+
extend self
|
10
|
+
|
11
|
+
# Pluralization rules
|
12
|
+
module P11n
|
13
|
+
# utility variables
|
14
|
+
from0to1 = [0, 1].freeze
|
15
|
+
from2to4 = [2, 3, 4].freeze
|
16
|
+
from5to9 = [5, 6, 7, 8, 9].freeze
|
17
|
+
from11to14 = [11, 12, 13, 14].freeze
|
18
|
+
from12to14 = [12, 13, 14].freeze
|
19
|
+
|
20
|
+
# Store the proc defining each pluralization RULE
|
21
|
+
# Logic adapted from https://github.com/svenfuchs/rails-i18n
|
22
|
+
RULE = {
|
23
|
+
arabic:
|
24
|
+
lambda do |n = 0|
|
25
|
+
mod100 = n % 100
|
26
|
+
case
|
27
|
+
when n == 0 then 'zero' # rubocop:disable Style/NumericPredicate
|
28
|
+
when n == 1 then 'one'
|
29
|
+
when n == 2 then 'two'
|
30
|
+
when (3..10).to_a.include?(mod100) then 'few'
|
31
|
+
when (11..99).to_a.include?(mod100) then 'many'
|
32
|
+
else 'other'
|
33
|
+
end
|
34
|
+
end,
|
35
|
+
|
36
|
+
east_slavic:
|
37
|
+
lambda do |n = 0|
|
38
|
+
mod10 = n % 10
|
39
|
+
mod100 = n % 100
|
40
|
+
case
|
41
|
+
when mod10 == 1 && mod100 != 11 then 'one'
|
42
|
+
when from2to4.include?(mod10) && !from12to14.include?(mod100) then 'few'
|
43
|
+
when mod10 == 0 || from5to9.include?(mod10) || from11to14.include?(mod100) then 'many' # rubocop:disable Style/NumericPredicate
|
44
|
+
else 'other'
|
45
|
+
end
|
46
|
+
end,
|
47
|
+
|
48
|
+
one_other:
|
49
|
+
->(n) { n == 1 ? 'one' : 'other' }, # default RULE
|
50
|
+
|
51
|
+
one_two_other:
|
52
|
+
lambda do |n|
|
53
|
+
case n
|
54
|
+
when 1 then 'one'
|
55
|
+
when 2 then 'two'
|
56
|
+
else 'other'
|
57
|
+
end
|
58
|
+
end,
|
59
|
+
|
60
|
+
one_upto_two_other:
|
61
|
+
->(n) { n && n >= 0 && n < 2 ? 'one' : 'other' },
|
62
|
+
|
63
|
+
other:
|
64
|
+
->(*) { 'other' },
|
65
|
+
|
66
|
+
polish:
|
67
|
+
lambda do |n = 0|
|
68
|
+
mod10 = n % 10
|
69
|
+
mod100 = n % 100
|
70
|
+
case
|
71
|
+
when n == 1 then 'one'
|
72
|
+
when from2to4.include?(mod10) && !from12to14.include?(mod100) then 'few'
|
73
|
+
when (from0to1 + from5to9).include?(mod10) || from12to14.include?(mod100) then 'many'
|
74
|
+
else 'other'
|
75
|
+
end
|
76
|
+
end,
|
77
|
+
|
78
|
+
west_slavic:
|
79
|
+
lambda do |n|
|
80
|
+
case n
|
81
|
+
when 1 then 'one'
|
82
|
+
when *from2to4 then 'few'
|
83
|
+
else 'other'
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
}.freeze
|
88
|
+
|
89
|
+
# Store the RULE to apply to each LOCALE
|
90
|
+
# the :one_other RULE is the default for locales missing from this list
|
91
|
+
LOCALE = Hash.new(RULE[:one_other]).tap do |hash|
|
92
|
+
hash['ar'] = RULE[:arabic]
|
93
|
+
hash['bs'] = RULE[:east_slavic]
|
94
|
+
hash['cs'] = RULE[:west_slavic]
|
95
|
+
hash['id'] = RULE[:other]
|
96
|
+
hash['fr'] = RULE[:one_upto_two_other]
|
97
|
+
hash['hr'] = RULE[:east_slavic]
|
98
|
+
hash['ja'] = RULE[:other]
|
99
|
+
hash['km'] = RULE[:other]
|
100
|
+
hash['ko'] = RULE[:other]
|
101
|
+
hash['pl'] = RULE[:polish]
|
102
|
+
hash['ru'] = RULE[:east_slavic]
|
103
|
+
hash['sr'] = RULE[:east_slavic]
|
104
|
+
hash['sv'] = RULE[:one_two_other]
|
105
|
+
hash['sv-SE'] = RULE[:one_two_other]
|
106
|
+
hash['tr'] = RULE[:other]
|
107
|
+
hash['uk'] = RULE[:east_slavic]
|
108
|
+
hash['zh-CN'] = RULE[:other]
|
109
|
+
hash['zh-HK'] = RULE[:other]
|
110
|
+
hash['zh-TW'] = RULE[:other]
|
111
|
+
end.freeze
|
112
|
+
end
|
113
|
+
|
114
|
+
# Stores the i18n DATA structure for each loaded locale
|
115
|
+
# default on the first locale DATA
|
116
|
+
DATA = Hash.new { |hash, _| hash.first[1] }
|
117
|
+
|
118
|
+
private
|
119
|
+
|
120
|
+
# Create a flat hash with dotted notation keys
|
121
|
+
def flatten(initial, prefix = '')
|
122
|
+
initial.each.reduce({}) do |hash, (key, value)|
|
123
|
+
hash.merge!(value.is_a?(Hash) ? flatten(value, "#{prefix}#{key}.") : { "#{prefix}#{key}" => value })
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# Build the DATA hash out of the passed locales
|
128
|
+
def build(*locales)
|
129
|
+
locales.each do |locale|
|
130
|
+
locale[:filepath] ||= Pagy.root.join('locales', "#{locale[:locale]}.yml")
|
131
|
+
locale[:pluralize] ||= P11n::LOCALE[locale[:locale]]
|
132
|
+
dictionary = YAML.safe_load(File.read(locale[:filepath], encoding: 'UTF-8'))
|
133
|
+
raise VariableError, %(expected :locale "#{locale[:locale]}" not found in :filepath "#{locale[:filepath].inspect}") \
|
134
|
+
unless dictionary.key?(locale[:locale])
|
135
|
+
|
136
|
+
DATA[locale[:locale]] = [flatten(dictionary[locale[:locale]]), locale[:pluralize]]
|
137
|
+
end
|
138
|
+
end
|
139
|
+
# Build the default at require time
|
140
|
+
build(locale: 'en')
|
141
|
+
|
142
|
+
public
|
143
|
+
|
144
|
+
# Public method to configure the locales: overrides the default, build the DATA and freezes it
|
145
|
+
def load(*locales)
|
146
|
+
DATA.clear
|
147
|
+
build(*locales)
|
148
|
+
DATA.freeze
|
149
|
+
end
|
150
|
+
|
151
|
+
# Translate and pluralize the key with the locale DATA
|
152
|
+
def t(locale, key, **opts)
|
153
|
+
data, pluralize = DATA[locale]
|
154
|
+
translation = data[key] || (opts[:count] && data[key += ".#{pluralize.call(opts[:count])}"]) \
|
155
|
+
or return %([translation missing: "#{key}"])
|
156
|
+
translation.gsub(/%{[^}]+?}/) { |match| opts[:"#{match[2..-2]}"] || match }
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Pagy
|
4
|
+
# Provide the helpers to handle the url in frontend and backend
|
5
|
+
module UrlHelpers
|
6
|
+
# This works with all Rack-based frameworks (Sinatra, Padrino, Rails, ...)
|
7
|
+
def pagy_url_for(pagy, page, absolute: nil)
|
8
|
+
p_vars = pagy.vars
|
9
|
+
params = request.GET.merge(p_vars[:params])
|
10
|
+
params[p_vars[:page_param].to_s] = page
|
11
|
+
params[p_vars[:items_param].to_s] = p_vars[:items] if defined?(ItemsExtra)
|
12
|
+
# we rely on Rack by default: use the standalone extra in non rack environments
|
13
|
+
query_string = "?#{Rack::Utils.build_nested_query(pagy_massage_params(params))}" unless params.empty?
|
14
|
+
"#{request.base_url if absolute}#{request.path}#{query_string}#{p_vars[:fragment]}"
|
15
|
+
end
|
16
|
+
|
17
|
+
# Sub-method called only by #pagy_url_for: here for easy customization of params by overriding
|
18
|
+
def pagy_massage_params(params)
|
19
|
+
params
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/pagy.rb
CHANGED
@@ -3,58 +3,61 @@
|
|
3
3
|
|
4
4
|
require 'pathname'
|
5
5
|
|
6
|
-
#
|
6
|
+
# Core class
|
7
7
|
class Pagy
|
8
|
-
VERSION = '
|
8
|
+
VERSION = '5.0.0'
|
9
9
|
|
10
10
|
# Root pathname to get the path of Pagy files like templates or dictionaries
|
11
11
|
def self.root
|
12
12
|
@root ||= Pathname.new(__dir__).freeze
|
13
13
|
end
|
14
14
|
|
15
|
-
#
|
16
|
-
|
17
|
-
|
15
|
+
# Default core vars: constant for easy access, but mutable for customizable defaults
|
16
|
+
DEFAULT = { page: 1, # rubocop:disable Style/MutableConstant
|
17
|
+
items: 20,
|
18
|
+
outset: 0,
|
19
|
+
size: [1, 4, 4, 1],
|
20
|
+
page_param: :page,
|
21
|
+
params: {},
|
22
|
+
fragment: '',
|
23
|
+
link_extra: '',
|
24
|
+
i18n_key: 'pagy.item_name',
|
25
|
+
cycle: false }
|
18
26
|
|
19
|
-
attr_reader :count, :page, :items, :vars, :pages, :last, :offset, :from, :to, :prev, :next
|
20
|
-
|
21
|
-
INSTANCE_VARS_MIN = { count: 0, items: 1, page: 1, outset: 0 }.freeze
|
27
|
+
attr_reader :count, :page, :items, :vars, :pages, :last, :offset, :in, :from, :to, :prev, :next
|
22
28
|
|
23
29
|
# Merge and validate the options, do some simple arithmetic and set the instance variables
|
24
30
|
def initialize(vars)
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
raise VariableError.new(self), "expected :#{name} >= #{min}; got #{@vars[name].inspect}" \
|
30
|
-
unless @vars[name] && instance_variable_set(:"@#{name}", @vars[name].to_i) >= min
|
31
|
-
end
|
32
|
-
@pages = @last = [(@count.to_f / @items).ceil, 1].max
|
31
|
+
normalize_vars(vars)
|
32
|
+
setup_vars(count: 0, page: 1, outset: 0)
|
33
|
+
setup_items_var
|
34
|
+
setup_pages_var
|
33
35
|
raise OverflowError.new(self), "expected :page in 1..#{@last}; got #{@page.inspect}" \
|
34
36
|
if @page > @last
|
35
37
|
|
36
|
-
@offset = @items * (@page - 1) + @outset
|
37
|
-
@
|
38
|
-
@
|
39
|
-
@
|
38
|
+
@offset = (@items * (@page - 1)) + @outset
|
39
|
+
@from = [@offset - @outset + 1, @count].min
|
40
|
+
@to = [@offset - @outset + @items, @count].min
|
41
|
+
@in = [@to - @from + 1, @count].min
|
40
42
|
@prev = (@page - 1 unless @page == 1)
|
41
43
|
@next = @page == @last ? (1 if @vars[:cycle]) : @page + 1
|
42
44
|
end
|
43
45
|
|
44
46
|
# Return the array of page numbers and :gap items e.g. [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
|
45
|
-
def series(size
|
47
|
+
def series(size = @vars[:size])
|
46
48
|
return [] if size.empty?
|
47
49
|
raise VariableError.new(self), "expected 4 items >= 0 in :size; got #{size.inspect}" \
|
48
|
-
unless size.size == 4 && size.all?{ |num| !num.negative? rescue false }
|
50
|
+
unless size.size == 4 && size.all? { |num| !num.negative? rescue false } # rubocop:disable Style/RescueModifier
|
51
|
+
|
49
52
|
# This algorithm is up to ~5x faster and ~2.3x lighter than the previous one (pagy < 4.3)
|
50
|
-
left_gap_start = 1 + size[0]
|
53
|
+
left_gap_start = 1 + size[0] # rubocop:disable Layout/ExtraSpacing, Layout/SpaceAroundOperators
|
51
54
|
left_gap_end = @page - size[1] - 1
|
52
55
|
right_gap_start = @page + size[2] + 1
|
53
56
|
right_gap_end = @last - size[3]
|
54
57
|
left_gap_end = right_gap_end if left_gap_end > right_gap_end
|
55
58
|
right_gap_start = left_gap_start if left_gap_start > right_gap_start
|
56
|
-
series
|
57
|
-
start
|
59
|
+
series = []
|
60
|
+
start = 1
|
58
61
|
if (left_gap_end - left_gap_start).positive?
|
59
62
|
series.push(*start..(left_gap_start - 1), :gap)
|
60
63
|
start = left_gap_end + 1
|
@@ -68,9 +71,32 @@ class Pagy
|
|
68
71
|
series
|
69
72
|
end
|
70
73
|
|
74
|
+
protected
|
75
|
+
|
76
|
+
# Apply defaults, cleanup blanks and set @vars
|
77
|
+
def normalize_vars(vars)
|
78
|
+
@vars = DEFAULT.merge(vars.delete_if { |k, v| DEFAULT.key?(k) && (v.nil? || v == '') })
|
79
|
+
end
|
80
|
+
|
81
|
+
# Setup and validates the passed vars: var must be present and value.to_i must be >= to min
|
82
|
+
def setup_vars(name_min)
|
83
|
+
name_min.each do |name, min|
|
84
|
+
raise VariableError.new(self), "expected :#{name} >= #{min}; got #{@vars[name].inspect}" \
|
85
|
+
unless @vars[name] && instance_variable_set(:"@#{name}", @vars[name].to_i) >= min
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Setup and validate the items (overridden by the gearbox extra)
|
90
|
+
def setup_items_var
|
91
|
+
setup_vars(items: 1)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Setup and validates the pages (overridden by the gearbox extra)
|
95
|
+
def setup_pages_var
|
96
|
+
@pages = @last = [(@count.to_f / @items).ceil, 1].max
|
97
|
+
end
|
71
98
|
end
|
72
99
|
|
73
|
-
require 'pagy/deprecation'
|
74
100
|
require 'pagy/backend'
|
75
101
|
require 'pagy/frontend'
|
76
102
|
require 'pagy/exceptions'
|
@@ -9,7 +9,7 @@
|
|
9
9
|
<% elsif item == :gap -%> <li class="uk-disabled"><span><%== pagy_t('pagy.nav.gap') %></span></li>
|
10
10
|
<% end -%>
|
11
11
|
<% end -%>
|
12
|
-
<% if pagy.next -%> <li><%== link.call(
|
12
|
+
<% if pagy.next -%> <li><%== link.call(pagy.next, "<span uk-pagination-next>#{pagy_t('pagy.nav.next')}</span>") %></li>
|
13
13
|
<% else -%> <li class="uk-disabled"><a href="#"><span uk-pagination-next><%== pagy_t('pagy.nav.next') %></span></a></li>
|
14
14
|
<% end -%>
|
15
15
|
<%# -%> </ul>
|
@@ -21,7 +21,7 @@ ul.uk-pagination.uk-flex-center
|
|
21
21
|
span== pagy_t('pagy.nav.gap')
|
22
22
|
|
23
23
|
- if pagy.next
|
24
|
-
li== link.call(
|
24
|
+
li== link.call(pagy.next, "<span uk-pagination-next>#{pagy_t('pagy.nav.next')}</span>")
|
25
25
|
- else
|
26
26
|
li.uk-disabled
|
27
27
|
a href="#"
|
metadata
CHANGED
@@ -1,18 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pagy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Domizio Demichelis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-10-16 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
|
-
description:
|
14
|
-
and DB type, with all kinds of collections, even pre-paginated, scopes, Arrays,
|
15
|
-
JSON data... Easy, powerful, fast and light.'
|
13
|
+
description: Agnostic pagination in plain ruby. It does it all. Better.
|
16
14
|
email:
|
17
15
|
- dd.nexus@gmail.com
|
18
16
|
executables: []
|
@@ -50,9 +48,6 @@ files:
|
|
50
48
|
- lib/locales/sw.yml
|
51
49
|
- lib/locales/tr.yml
|
52
50
|
- lib/locales/uk.yml
|
53
|
-
- lib/locales/utils/i18n.rb
|
54
|
-
- lib/locales/utils/loader.rb
|
55
|
-
- lib/locales/utils/p11n.rb
|
56
51
|
- lib/locales/zh-CN.yml
|
57
52
|
- lib/locales/zh-HK.yml
|
58
53
|
- lib/locales/zh-TW.yml
|
@@ -60,7 +55,6 @@ files:
|
|
60
55
|
- lib/pagy/backend.rb
|
61
56
|
- lib/pagy/console.rb
|
62
57
|
- lib/pagy/countless.rb
|
63
|
-
- lib/pagy/deprecation.rb
|
64
58
|
- lib/pagy/exceptions.rb
|
65
59
|
- lib/pagy/extras/arel.rb
|
66
60
|
- lib/pagy/extras/array.rb
|
@@ -69,6 +63,7 @@ files:
|
|
69
63
|
- lib/pagy/extras/countless.rb
|
70
64
|
- lib/pagy/extras/elasticsearch_rails.rb
|
71
65
|
- lib/pagy/extras/foundation.rb
|
66
|
+
- lib/pagy/extras/gearbox.rb
|
72
67
|
- lib/pagy/extras/headers.rb
|
73
68
|
- lib/pagy/extras/i18n.rb
|
74
69
|
- lib/pagy/extras/items.rb
|
@@ -85,6 +80,8 @@ files:
|
|
85
80
|
- lib/pagy/extras/trim.rb
|
86
81
|
- lib/pagy/extras/uikit.rb
|
87
82
|
- lib/pagy/frontend.rb
|
83
|
+
- lib/pagy/i18n.rb
|
84
|
+
- lib/pagy/url_helpers.rb
|
88
85
|
- lib/templates/bootstrap_nav.html.erb
|
89
86
|
- lib/templates/bootstrap_nav.html.haml
|
90
87
|
- lib/templates/bootstrap_nav.html.slim
|
@@ -122,5 +119,5 @@ requirements: []
|
|
122
119
|
rubygems_version: 3.2.3
|
123
120
|
signing_key:
|
124
121
|
specification_version: 4
|
125
|
-
summary: The
|
122
|
+
summary: The kick-ass pagination ruby gem
|
126
123
|
test_files: []
|
data/lib/locales/utils/i18n.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
# See https://ddnexus.github.io/pagy/api/frontend#i18n
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
# this file returns the I18n hash used as default alternative to the i18n gem
|
5
|
-
|
6
|
-
Hash.new{|h,_| h.first[1]}.tap do |i18n_hash| # first loaded locale used as default
|
7
|
-
i18n_hash.define_singleton_method(:load) do |*load_args|
|
8
|
-
# eval: we don't need to keep the loader proc in memory
|
9
|
-
eval(Pagy.root.join('locales', 'utils', 'loader.rb').read).call(i18n_hash, *load_args) #rubocop:disable Security/Eval
|
10
|
-
end
|
11
|
-
i18n_hash.define_singleton_method(:t) do |locale, key, **opts|
|
12
|
-
data, pluralize = self[locale]
|
13
|
-
translate = data[key] || opts[:count] && data[key+=".#{pluralize.call(opts[:count])}"] or return %([translation missing: "#{key}"])
|
14
|
-
translate.call(opts)
|
15
|
-
end
|
16
|
-
i18n_hash.load(locale: 'en')
|
17
|
-
end
|
data/lib/locales/utils/loader.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# the whole file will be eval'ed/executed and gc-collected after returning/executing the loader proc
|
4
|
-
|
5
|
-
# eval: no need for the whole file in memory
|
6
|
-
plurals, = eval Pagy.root.join('locales', 'utils', 'p11n.rb').read # rubocop:disable Security/Eval
|
7
|
-
|
8
|
-
# flatten the dictionary file nested keys
|
9
|
-
# convert each value to a simple ruby interpolation proc
|
10
|
-
flatten = lambda do |hash, key=''|
|
11
|
-
hash.each.reduce({}) do |h, (k, v)|
|
12
|
-
if v.is_a?(Hash)
|
13
|
-
h.merge! flatten.call(v, "#{key}#{k}.")
|
14
|
-
else
|
15
|
-
code = %({"#{key}#{k}" => lambda{|vars|"#{v.gsub(/%{[^}]+?}/){|m| "\#{vars[:#{m[2..-2]}]||'#{m}'}" }}"}})
|
16
|
-
h.merge! eval(code) # rubocop:disable Security/Eval
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
# loader proc
|
22
|
-
lambda do |i18n, *args|
|
23
|
-
i18n.clear
|
24
|
-
args.each do |arg|
|
25
|
-
arg[:filepath] ||= Pagy.root.join('locales', "#{arg[:locale]}.yml")
|
26
|
-
arg[:pluralize] ||= plurals[arg[:locale]]
|
27
|
-
hash = YAML.load(File.read(arg[:filepath], encoding: 'UTF-8')) #rubocop:disable Security/YAMLLoad
|
28
|
-
hash.key?(arg[:locale]) or raise VariableError, %(expected :locale "#{arg[:locale]}" not found in :filepath "#{arg[:filepath].inspect}")
|
29
|
-
i18n[arg[:locale]] = [flatten.call(hash[arg[:locale]]), arg[:pluralize]]
|
30
|
-
end
|
31
|
-
end
|
data/lib/locales/utils/p11n.rb
DELETED
@@ -1,112 +0,0 @@
|
|
1
|
-
# See https://ddnexus.github.io/pagy/api/frontend#i18n
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
# This file adds support for multiple built-in plualization types.
|
5
|
-
# It defines the pluralization procs and gets eval(ed) and gc-collected at Pagy::I18n.load time.
|
6
|
-
|
7
|
-
# utility variables
|
8
|
-
from0to1 = [0,1].freeze
|
9
|
-
from2to4 = [2,3,4].freeze
|
10
|
-
from5to9 = [5,6,7,8,9].freeze
|
11
|
-
from11to14 = [11,12,13,14].freeze
|
12
|
-
from12to14 = [12,13,14].freeze
|
13
|
-
|
14
|
-
# Pluralization (p11n)
|
15
|
-
# Compliant with the I18n gem
|
16
|
-
# A pluralization proc returns a plural type string based on the passed count
|
17
|
-
# Each proc may apply to one or more locales below.
|
18
|
-
# Pluralization logic adapted from https://github.com/svenfuchs/rails-i18n
|
19
|
-
p11n = {
|
20
|
-
one_other: -> (n){ n == 1 ? 'one' : 'other' }, # default
|
21
|
-
|
22
|
-
arabic: lambda do |n|
|
23
|
-
n ||= 0
|
24
|
-
mod100 = n % 100
|
25
|
-
|
26
|
-
case
|
27
|
-
when n == 0 then 'zero' # rubocop:disable Style/NumericPredicate
|
28
|
-
when n == 1 then 'one'
|
29
|
-
when n == 2 then 'two'
|
30
|
-
when (3..10).to_a.include?(mod100) then 'few'
|
31
|
-
when (11..99).to_a.include?(mod100) then 'many'
|
32
|
-
else 'other'
|
33
|
-
end
|
34
|
-
end,
|
35
|
-
|
36
|
-
east_slavic: lambda do |n|
|
37
|
-
n ||= 0
|
38
|
-
mod10 = n % 10
|
39
|
-
mod100 = n % 100
|
40
|
-
|
41
|
-
case
|
42
|
-
when mod10 == 1 && mod100 != 11 then 'one'
|
43
|
-
when from2to4.include?(mod10) && !from12to14.include?(mod100) then 'few'
|
44
|
-
when mod10 == 0 || from5to9.include?(mod10) || from11to14.include?(mod100) then 'many' # rubocop:disable Style/NumericPredicate
|
45
|
-
else 'other'
|
46
|
-
end
|
47
|
-
end,
|
48
|
-
|
49
|
-
one_two_other: lambda do |n|
|
50
|
-
case n
|
51
|
-
when 1 then 'one'
|
52
|
-
when 2 then 'two'
|
53
|
-
else 'other'
|
54
|
-
end
|
55
|
-
end,
|
56
|
-
|
57
|
-
one_upto_two_other: -> (n){ n && n >= 0 && n < 2 ? 'one' : 'other' },
|
58
|
-
|
59
|
-
other: -> (*){ 'other' },
|
60
|
-
|
61
|
-
polish: lambda do |n|
|
62
|
-
n ||= 0
|
63
|
-
mod10 = n % 10
|
64
|
-
mod100 = n % 100
|
65
|
-
|
66
|
-
case
|
67
|
-
when n == 1 then 'one'
|
68
|
-
when from2to4.include?(mod10) && !from12to14.include?(mod100) then 'few'
|
69
|
-
when (from0to1 + from5to9).include?(mod10) || from12to14.include?(mod100) then 'many'
|
70
|
-
else 'other'
|
71
|
-
end
|
72
|
-
end,
|
73
|
-
|
74
|
-
west_slavic: lambda do |n|
|
75
|
-
case n
|
76
|
-
when 1 then 'one'
|
77
|
-
when 2, 3, 4 then 'few'
|
78
|
-
else 'other'
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
}
|
83
|
-
|
84
|
-
# Hash of locale/pluralization pairs
|
85
|
-
# It contains all the entries for all the locales defined as dictionaries.
|
86
|
-
# The default pluralization for locales not explicitly listed here
|
87
|
-
# is the :one_other pluralization proc (used for English)
|
88
|
-
plurals = Hash.new(p11n[:one_other]).tap do |hash|
|
89
|
-
hash['ar'] = p11n[:arabic]
|
90
|
-
hash['bs'] = p11n[:east_slavic]
|
91
|
-
hash['cs'] = p11n[:west_slavic]
|
92
|
-
hash['id'] = p11n[:other]
|
93
|
-
hash['fr'] = p11n[:one_upto_two_other]
|
94
|
-
hash['hr'] = p11n[:east_slavic]
|
95
|
-
hash['ja'] = p11n[:other]
|
96
|
-
hash['km'] = p11n[:other]
|
97
|
-
hash['ko'] = p11n[:other]
|
98
|
-
hash['pl'] = p11n[:polish]
|
99
|
-
hash['ru'] = p11n[:east_slavic]
|
100
|
-
hash['sr'] = p11n[:east_slavic]
|
101
|
-
hash['sv'] = p11n[:one_two_other]
|
102
|
-
hash['sv-SE'] = p11n[:one_two_other]
|
103
|
-
hash['tr'] = p11n[:other]
|
104
|
-
hash['uk'] = p11n[:east_slavic]
|
105
|
-
hash['zh-CN'] = p11n[:other]
|
106
|
-
hash['zh-HK'] = p11n[:other]
|
107
|
-
hash['zh-TW'] = p11n[:other]
|
108
|
-
end
|
109
|
-
|
110
|
-
[ plurals, p11n ]
|
111
|
-
|
112
|
-
# PR for other locales and pluralizations are very welcome. Thanks!
|
data/lib/pagy/deprecation.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
class Pagy
|
3
|
-
class << self
|
4
|
-
|
5
|
-
# deprecated variables
|
6
|
-
def deprecated_var(var, val, new_var, new_val)
|
7
|
-
value = val || new_val
|
8
|
-
Warning.warn %([PAGY WARNING] deprecated use of '#{var}' var will not be supported in 5.0! Use '#{new_var}: #{value.inspect}' instead.)
|
9
|
-
value
|
10
|
-
end
|
11
|
-
|
12
|
-
# deprecated pagy_url_for argument order
|
13
|
-
def deprecated_order(pagy, page)
|
14
|
-
Warning.warn %([PAGY WARNING] inverted use of pagy/page in pagy_url_for will not be supported in 5.0! Use pagy_url_for(pagy, page) instead.)
|
15
|
-
[page, pagy]
|
16
|
-
end
|
17
|
-
|
18
|
-
|
19
|
-
# deprecated posiitioal arguments
|
20
|
-
def deprecated_arg(arg, val, new_key, new_val)
|
21
|
-
value = val || new_val # we use the new_val if present
|
22
|
-
Warning.warn %([PAGY WARNING] deprecated use of positional '#{arg}' arg will not be supported in 5.0! Use only the keyword arg '#{new_key}: #{value.inspect}' instead.)
|
23
|
-
value
|
24
|
-
end
|
25
|
-
|
26
|
-
end
|
27
|
-
end
|