pagy 4.10.2 → 5.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/config/pagy.rb +71 -44
- data/lib/javascripts/pagy.js +15 -6
- data/lib/pagy/backend.rb +9 -12
- data/lib/pagy/console.rb +6 -4
- data/lib/pagy/countless.rb +21 -21
- data/lib/pagy/exceptions.rb +16 -16
- data/lib/pagy/extras/arel.rb +6 -6
- data/lib/pagy/extras/array.rb +6 -6
- data/lib/pagy/extras/bootstrap.rb +35 -29
- data/lib/pagy/extras/bulma.rb +43 -32
- data/lib/pagy/extras/countless.rb +14 -14
- data/lib/pagy/extras/elasticsearch_rails.rb +64 -47
- data/lib/pagy/extras/foundation.rb +29 -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 +38 -39
- data/lib/pagy/extras/materialize.rb +31 -30
- data/lib/pagy/extras/meilisearch.rb +50 -45
- data/lib/pagy/extras/metadata.rb +14 -20
- data/lib/pagy/extras/navs.rb +26 -26
- data/lib/pagy/extras/overflow.rb +56 -60
- data/lib/pagy/extras/searchkick.rb +51 -45
- data/lib/pagy/extras/semantic.rb +31 -30
- data/lib/pagy/extras/shared.rb +43 -40
- data/lib/pagy/extras/standalone.rb +41 -45
- data/lib/pagy/extras/support.rb +20 -13
- data/lib/pagy/extras/trim.rb +11 -11
- data/lib/pagy/extras/uikit.rb +30 -28
- data/lib/pagy/frontend.rb +25 -49
- data/lib/pagy/i18n.rb +159 -0
- data/lib/pagy/url_helpers.rb +24 -0
- data/lib/pagy.rb +54 -29
- 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 I18nError, %(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,24 @@
|
|
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
|
+
# Return the URL for the page, relying on the params method and Rack by default.
|
7
|
+
# It supports all Rack-based frameworks (Sinatra, Padrino, Rails, ...).
|
8
|
+
# For non-rack environments you can use the standalone extra
|
9
|
+
def pagy_url_for(pagy, page, absolute: nil)
|
10
|
+
vars = pagy.vars
|
11
|
+
params = self.params.merge(vars[:params])
|
12
|
+
params[vars[:page_param]] = page
|
13
|
+
params[vars[:items_param]] = vars[:items] if vars[:items_extra]
|
14
|
+
|
15
|
+
query_string = "?#{Rack::Utils.build_nested_query(pagy_massage_params(params))}"
|
16
|
+
"#{request.base_url if absolute}#{request.path}#{query_string}#{vars[:fragment]}"
|
17
|
+
end
|
18
|
+
|
19
|
+
# Sub-method called only by #pagy_url_for: here for easy customization of params by overriding
|
20
|
+
def pagy_massage_params(params)
|
21
|
+
params
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/pagy.rb
CHANGED
@@ -3,58 +3,60 @@
|
|
3
3
|
|
4
4
|
require 'pathname'
|
5
5
|
|
6
|
-
#
|
6
|
+
# Core class
|
7
7
|
class Pagy
|
8
|
-
VERSION = '
|
8
|
+
VERSION = '5.1.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
|
-
|
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
|
33
|
-
raise OverflowError.new(self), "expected :page in 1..#{@last}; got #{@page.inspect}" \
|
34
|
-
if @page > @last
|
31
|
+
normalize_vars(vars)
|
32
|
+
setup_vars(count: 0, page: 1, outset: 0)
|
33
|
+
setup_items_var
|
34
|
+
setup_pages_var
|
35
|
+
raise OverflowError.new(self, :page, "in 1..#{@last}", @page) if @page > @last
|
35
36
|
|
36
|
-
@offset = @items * (@page - 1) + @outset
|
37
|
-
@
|
38
|
-
@
|
39
|
-
@
|
37
|
+
@offset = (@items * (@page - 1)) + @outset
|
38
|
+
@from = [@offset - @outset + 1, @count].min
|
39
|
+
@to = [@offset - @outset + @items, @count].min
|
40
|
+
@in = [@to - @from + 1, @count].min
|
40
41
|
@prev = (@page - 1 unless @page == 1)
|
41
42
|
@next = @page == @last ? (1 if @vars[:cycle]) : @page + 1
|
42
43
|
end
|
43
44
|
|
44
45
|
# Return the array of page numbers and :gap items e.g. [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
|
45
|
-
def series(size
|
46
|
+
def series(size = @vars[:size])
|
46
47
|
return [] if size.empty?
|
47
|
-
raise VariableError.new(self
|
48
|
-
unless size.size == 4 && size.all?{ |num| !num.negative? rescue false }
|
48
|
+
raise VariableError.new(self, :size, 'to contain 4 items >= 0', size) \
|
49
|
+
unless size.size == 4 && size.all? { |num| !num.negative? rescue false } # rubocop:disable Style/RescueModifier
|
50
|
+
|
49
51
|
# 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]
|
52
|
+
left_gap_start = 1 + size[0] # rubocop:disable Layout/ExtraSpacing, Layout/SpaceAroundOperators
|
51
53
|
left_gap_end = @page - size[1] - 1
|
52
54
|
right_gap_start = @page + size[2] + 1
|
53
55
|
right_gap_end = @last - size[3]
|
54
56
|
left_gap_end = right_gap_end if left_gap_end > right_gap_end
|
55
57
|
right_gap_start = left_gap_start if left_gap_start > right_gap_start
|
56
|
-
series
|
57
|
-
start
|
58
|
+
series = []
|
59
|
+
start = 1
|
58
60
|
if (left_gap_end - left_gap_start).positive?
|
59
61
|
series.push(*start..(left_gap_start - 1), :gap)
|
60
62
|
start = left_gap_end + 1
|
@@ -68,9 +70,32 @@ class Pagy
|
|
68
70
|
series
|
69
71
|
end
|
70
72
|
|
73
|
+
protected
|
74
|
+
|
75
|
+
# Apply defaults, cleanup blanks and set @vars
|
76
|
+
def normalize_vars(vars)
|
77
|
+
@vars = DEFAULT.merge(vars.delete_if { |k, v| DEFAULT.key?(k) && (v.nil? || v == '') })
|
78
|
+
end
|
79
|
+
|
80
|
+
# Setup and validates the passed vars: var must be present and value.to_i must be >= to min
|
81
|
+
def setup_vars(name_min)
|
82
|
+
name_min.each do |name, min|
|
83
|
+
raise VariableError.new(self, name, ">= #{min}", @vars[name]) \
|
84
|
+
unless @vars[name] && instance_variable_set(:"@#{name}", @vars[name].to_i) >= min
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Setup and validate the items (overridden by the gearbox extra)
|
89
|
+
def setup_items_var
|
90
|
+
setup_vars(items: 1)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Setup and validates the pages (overridden by the gearbox extra)
|
94
|
+
def setup_pages_var
|
95
|
+
@pages = @last = [(@count.to_f / @items).ceil, 1].max
|
96
|
+
end
|
71
97
|
end
|
72
98
|
|
73
|
-
require 'pagy/deprecation'
|
74
99
|
require 'pagy/backend'
|
75
100
|
require 'pagy/frontend'
|
76
101
|
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.1.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-25 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
|