Skip to content

Commit

Permalink
WIP: Removed i18n extra and better calendar localization
Browse files Browse the repository at this point in the history
  • Loading branch information
ddnexus committed Jan 23, 2025
1 parent 5143268 commit eb4e45e
Show file tree
Hide file tree
Showing 17 changed files with 121 additions and 122 deletions.
11 changes: 10 additions & 1 deletion CHANGELOG-10.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ Updated the support for the pagy helpers and keynav pagination. Added the plain
- If you used the `:params` variable set to a lambda, ensure that it modifies the passed `query_params` directly. The returned
value is now ignored for a sligtly better performance.

#### Extras Replacement
#### Extras Changes

##### `arel`, `array`, `boostrap`, `bulma`, `calendar`, `countless`, `pagy`

Expand All @@ -142,6 +142,15 @@ Updated the support for the pagy helpers and keynav pagination. Added the plain
- Rename any existing `:scaffold_url` to `url_template`
- Remove any existing `Pagy::DEFAULT[:metadata]` variable and pass it to the paginator method

##### `i18n` (discontinued)

- Remove the `require 'pagy/extras/headers'` from the initializer.
- Ucomment the last 2 lines of the `pagy.rb` new initializer, or add them to yours:
```ruby
Pagy::Frontend.prepend(Module.new { def pagy_t(...) = I18n.t(...) })
I18n.load_path += Dir[Pagy::ROOT.join('locales/*.yml')]
```

##### `jsonapi`

- Remove the `require 'pagy/extras/jsonapi'` from the initializer.
Expand Down
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ group :test do
gem 'mutex_m' # for RubyMine
gem 'oj', require: false # false is for testing with or without it
gem 'rack'
gem 'rails-i18n'
gem 'rematch'
gem 'rubocop'
gem 'rubocop-minitest'
Expand Down
4 changes: 4 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,9 @@ GEM
rails-html-sanitizer (1.6.2)
loofah (~> 2.21)
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
rails-i18n (8.0.1)
i18n (>= 0.7, < 2)
railties (>= 8.0.0, < 9)
railties (8.0.1)
actionpack (= 8.0.1)
activesupport (= 8.0.1)
Expand Down Expand Up @@ -365,6 +368,7 @@ DEPENDENCIES
rack
rackup
rails (~> 8.0)
rails-i18n
rake
reline
rematch
Expand Down
62 changes: 33 additions & 29 deletions gem/config/pagy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,37 @@

# Pagy initializer file (9.3.3)

##### Pagy::DEFAULT #######################

##### Pagy::DEFAULT #######################
#
# Customizing the static and frozen Pagy::DEFAULT is NOT SUPPORTED since version 10.0.0.
# Pass the variables to the constructor, or pass your own PAGY_DEFAULT hash.
# For example:
# Pass the variables to the paginator method, or pass your own PAGY_DEFAULT hash. For example:
#
# PAGY_DEFAULT = { ... }
# pagy_offset(collection, **PAGY_DEFAULT, ...)


##### Extras #######################
# PAGY_DEFAULT = { limit: 10 }
# pagy_offset(collection, **PAGY_DEFAULT, **other_vars)

# The extras are almost all converted to autoloaded mixins, or integrated in the core code at zero-cost.
# You can use the methods that you need, and they will just work without the need of any explicit `require`.
#
# The only extras that are left (for different compelling reasons) are listed below:
# gearbox, i18n and size. They must be required in the initializer as usual.

##### Extras ##############################

# Gearbox extra: Automatically change the limit per page depending on the page number
# (e.g. `gearbox_limit: [15, 30, 60, 100]`
# See https://ddnexus.github.io/pagy/docs/extras/gearbox
# require 'pagy/extras/gearbox'
# Then pass e.g.: `gearbox_limit: [15, 30, 60, 100]` to the paginator method to activate the feature


# I18n extra: uses the standard i18n gem which is ~18x slower using ~10x more memory
# than the default pagy internal i18n (see below)
# See https://ddnexus.github.io/pagy/docs/extras/i18n
# require 'pagy/extras/i18n'


# Size extra: Enable the Array type for the `:size` variable (e.g. `size: [1,4,4,1]`)
# Size extra: Enable the legacy and deprecated Array type for the `:size` variable (e.g. `size: [1,4,4,1]`)
# See https://ddnexus.github.io/pagy/docs/extras/size
# require 'pagy/extras/size' # must be required before the other extras
# require 'pagy/extras/size'


# IMPORTANT: No need to configure anything below this line if your app uses only the :en locale

##### Pagy::I18n configuration #######################

# Pagy internal I18n: ~18x faster using ~10x less memory than the i18n gem
# See https://ddnexus.github.io/pagy/docs/api/i18n
# Notice: No need to configure anything in this section if your app uses only "en"
# or if you use the i18n extra below
##### Pagy Translation Besides :en #######################
#
# Examples:
# Use the pagy internal I18n: ~18x faster using ~10x less memory than the i18n gem
# If you want to use the slower I18n gem, skip this and look at the end of this file.
#
# Examples (use only one statement):
# load the "de" built-in locale:
# Pagy::I18n.load(locale: 'de')
#
Expand All @@ -66,3 +53,20 @@
# { locale: 'xyz', # not built-in
# filepath: 'path/to/pagy-xyz.yml',
# pluralize: lambda{ |count| ... } )


##### Use the slower I18n gem for translation ###############
#
# Uncomment the following line to switch to the standard I18n gem translation
#
# Pagy.translate_with_the_slower_i18n_gem!


##### Pagy Calendar Localization Besides :en ###############
#
# The calendar localization data beside :en (which is included), is provided by the rails-i18n gem,
# which should be requested/added by your Gemfile.
# Add the list of locale symbols and comment the following line to enable it,
# regardless if you use the I18n gem for translations or not.
#
# Pagy::Offset::Calendar.localize_with_rails_i18n_gem(*your_locales)
5 changes: 5 additions & 0 deletions gem/lib/pagy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ class Pagy

alias pages last

def self.translate_with_the_slower_i18n_gem!
Frontend.prepend(Module.new { def pagy_t(...) = ::I18n.t(...) })
::I18n.load_path += Dir[ROOT.join('locales/*.yml')]
end

# Validates and assign the passed vars: var must be present and value.to_i must be >= to min
def assign_and_check(name_min)
name_min.each do |name, min|
Expand Down
3 changes: 3 additions & 0 deletions gem/lib/pagy/exceptions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ class OverflowError < VariableError; end
# I18n configuration error
class I18nError < StandardError; end

# I18n configuration error
class RailsI18nLoadError < LoadError; end

# Generic internal error
class InternalError < StandardError; end

Expand Down
14 changes: 0 additions & 14 deletions gem/lib/pagy/extras/i18n.rb

This file was deleted.

11 changes: 11 additions & 0 deletions gem/lib/pagy/offset/calendar.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ class OutOfRangeError < VariableError; end
UNITS = %i[year quarter month week day] # rubocop:disable Style/MutableConstant

class << self
def localize_with_rails_i18n_gem(*locales)
# :nocov:
raise RailsI18nLoadError, "Pagy: Gem 'rails-i18n' is not installed!" \
unless (path = Gem.loaded_specs['rails-i18n']&.full_gem_path)
# :nocov:

path = Pathname.new(path)
::I18n.load_path += locales.map { |locale| path.join("rails/locale/#{locale}.yml") }
Unit.prepend(Module.new { def localize(...) = ::I18n.l(...) })
end

private

# Create a unit subclass instance by using the unit name (internal use)
Expand Down
2 changes: 1 addition & 1 deletion gem/lib/pagy/offset/calendar/quarter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class Quarter < Unit
def label(page: @page, **opts)
starting_time = starting_time_for(page.to_i) # page could be a string
opts[:format] = (opts[:format] || @vars[:format]).gsub('%q') { (starting_time.month / 3.0).ceil }
localize(starting_time, opts)
localize(starting_time, **opts)
end

protected
Expand Down
13 changes: 8 additions & 5 deletions gem/lib/pagy/offset/calendar/unit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def check_overflow
# The label for any page (it can pass along the I18n gem opts when it's used with the i18n extra)
def label(page: @page, **opts)
opts[:format] ||= @vars[:format]
localize(starting_time_for(page.to_i), opts) # page could be a string
localize(starting_time_for(page.to_i), **opts) # page could be a string
end

def calendar? = true
Expand Down Expand Up @@ -81,10 +81,13 @@ def assign_unit_vars
&& @ending.is_a?(ActiveSupport::TimeWithZone) && @starting <= @ending
end

# Apply the strftime format to the time (overridden by the i18n extra when localization is required)
# Calendar overriding for localization (see also the block in the calendar section of the config/pagy.rb initializer)
def localize(time, opts)
defined?(::Pagy::I18nExtra) ? ::I18n.l(time, **opts) : time.strftime(opts[:format])
# Apply the strftime format to the time.
# IMPORTANT: If you need localization of the Calendar beside :en, you must use the rails-I18n gem.
# In order to enable it, uncomment the specific lines at the end of the config/pagy.rb initializer.
# Notice that the calendar localization does not require you to use the pagy i18n extra,
# which is all about translation and not localization.
def localize(time, **opts)
time.strftime(opts[:format])
end

# Number of time units to offset from the @initial time, in order to get the ordered starting time for the page.
Expand Down
6 changes: 5 additions & 1 deletion test/pagy/backend/calendar_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,12 @@ def app(**)
end
describe '#pagy_anchor with counts' do
it 'includes title and class in page url' do
# We need this require because we use a feature of pagy_calendar that would load with pagy_calendar,
# but we don't call it because Pagy::Offset.new is easier to run, still testing the feature...
require 'pagy/backend/paginators/calendar'
app = MockApp::CalendarCounts.new
pagy = Pagy::Offset.new(count: 103, page: 1, counts: {2 => 0})
_(MockApp::CalendarCounts.new.pagy_anchor(pagy, anchor_string: 'X').call(3, classes: 'a b c')).must_equal \
_(app.pagy_anchor(pagy, anchor_string: 'X').call(3, classes: 'a b c')).must_equal \
'<a X href="/foo?page=3" title="No items found" class="a b c empty-page">3</a>'
end
end
Expand Down
2 changes: 1 addition & 1 deletion test/pagy/console_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ module PagyConsole
assert_operator(PagyConsole, :<, Pagy::Frontend)
end
it 'requires extras' do
_ { PagyConsole.pagy_extras :gearbox, :i18n }.must_output "Required extras: :gearbox, :i18n\n"
_ { PagyConsole.pagy_extras :gearbox }.must_output "Required extras: :gearbox\n"
_(Pagy::Backend.method_defined?(:pagy_array))
_(Pagy::Frontend.method_defined?(:pagy_nav_js))
end
Expand Down
60 changes: 0 additions & 60 deletions test/pagy/extras/i18n/calendar_extra_test.rb

This file was deleted.

6 changes: 0 additions & 6 deletions test/pagy/extras/i18n/extra_test.rb.yaml

This file was deleted.

33 changes: 33 additions & 0 deletions test/pagy/extras/i18n_calendar_localization_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true

require_relative '../../test_helper'
require_relative '../../mock_helpers/app' # load after the extra

Time.zone = 'EST'
Date.beginning_of_week = :sunday

## Test not needed: Now it's a manual patch in the pagy.rb initializer
describe 'Calendar with I18n.l' do
##### pagy.rb initializer ###############
Pagy::Offset::Calendar.localize_with_rails_i18n_gem(:de)
#########################################

it 'works in :en' do
pagy = Pagy::Offset::Calendar.send(:create, :month,
period: [Time.zone.local(2021, 10, 21, 13, 18, 23, 0),
Time.zone.local(2023, 11, 13, 15, 43, 40, 0)],
page: 3, format: '%B, %A')
_(pagy.label).must_equal "December, Wednesday"
_(pagy.label(locale: :de)).must_equal "Dezember, Mittwoch"
_(pagy.label(format: '%b')).must_equal "Dec"
_(pagy.label(format: '%b', locale: :de)).must_equal "Dez"
_(pagy.label(page: 5)).must_equal "February, Tuesday"
_(pagy.label(page: 5, locale: :de)).must_equal "Februar, Dienstag"
I18n.locale = :de
_(pagy.label).must_equal "Dezember, Mittwoch"
_(pagy.label(format: '%b')).must_equal "Dez"
_(pagy.label(page: 5)).must_equal "Februar, Dienstag"
_(pagy.label(page: 5, format: '%b')).must_equal "Feb"
I18n.locale = :en
end
end
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
# frozen_string_literal: true

require_relative '../../../test_helper'
require_relative '../../../mock_helpers/app'
require 'i18n'
require 'pagy/extras/i18n'
require_relative '../../test_helper'
require_relative '../../mock_helpers/app'

describe 'pagy/extras/i18n' do
let(:app) { MockApp.new }

##### pagy.rb initializer ###############
Pagy.translate_with_the_slower_i18n_gem!
#########################################

describe '#pagy_t with I18n' do
it 'does not conflict with the I18n gem namespace' do
app.test_i18n_call
Expand Down
File renamed without changes.

0 comments on commit eb4e45e

Please sign in to comment.