Skip to content

Commit

Permalink
Better request
Browse files Browse the repository at this point in the history
  • Loading branch information
ddnexus committed Mar 8, 2025
1 parent 2539e52 commit c7286fd
Show file tree
Hide file tree
Showing 7 changed files with 25 additions and 23 deletions.
2 changes: 1 addition & 1 deletion docs/resources/javascript.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ image: ""

!!!warning The helpers and paginators named `*_js*` require Pagy JavaScript support.

Simply add the appropriate files and statements as outlined below.
Simply add the appropriate file(s) and statements as outlined below.
!!!

#### 1. Choose the format that matches your app's configuration
Expand Down
24 changes: 13 additions & 11 deletions gem/lib/pagy/classes/request.rb
Original file line number Diff line number Diff line change
@@ -1,27 +1,29 @@
# frozen_string_literal: true

class Pagy
# Decouple the reuest from the env, allowing non-rack apps to use pagy by passing a hash.
# Resolve :page and :limit, supporting the :jsonapi option. Support URL composition.
class Request
def initialize(request, options = {})
@base_url, @path, @query_hash = if request.is_a?(Hash)
request.values_at(:base_url, :path, :query_hash)
else
[request.base_url, request.path, request.GET]
end
@base_url, @path, @query_hash, @cookie =
if request.is_a?(Hash)
request.values_at(:base_url, :path, :query_hash, :cookie)
else
[request.base_url, request.path, request.GET, request.cookies['pagy']]
end
@jsonapi = @query_hash['page'] && options[:jsonapi]
raise JsonapiReservedParamError, @query_hash['page'] if @jsonapi && !@query_hash['page'].respond_to?(:fetch)
end
attr_reader :base_url, :path, :query_hash

# Get the page
def page(options, force_integer: true)
attr_reader :base_url, :path, :query_hash, :cookie

def resolve_page(options, force_integer: true)
page_key = options[:page_key] || DEFAULT[:page_key]
page = @jsonapi ? @query_hash['page'][page_key] : @query_hash[page_key]
page = @jsonapi ? @query_hash['page'][page_key] : @query_hash[page_key]
force_integer ? (page || 1).to_i : page
end

# Get the limit
def limit(options)
def resolve_limit(options)
limit_key = options[:limit_key] || DEFAULT[:limit_key]
return options[:limit] || DEFAULT[:limit] \
unless options[:requestable_limit] &&
Expand Down
4 changes: 2 additions & 2 deletions gem/lib/pagy/modules/searcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ module Searcher
def wrap(context, pagy_search_args, options)
context.instance_exec do
options[:request] = Request.new(options[:request] || request, options)
options[:page] ||= options[:request].page(options)
options[:limit] ||= options[:request].limit(options)
options[:page] ||= options[:request].resolve_page(options)
options[:limit] ||= options[:request].resolve_limit(options)
end
pagy, results = yield
calling = pagy_search_args[4..]
Expand Down
4 changes: 2 additions & 2 deletions gem/lib/pagy/toolbox/paginators/countless.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ def paginate(context, collection, **options)
context.instance_eval do
request = Request.new(options[:request] || self.request, options)
if options[:page].nil?
page = request.page(options, force_integer: false) # accept nil and strings
page = request.resolve_page(options, force_integer: false) # accept nil and strings
if page.is_a?(String)
p, l = page.split(/ /, 2).map(&:to_i)
options[:page] = p if p.positive?
options[:last] = l if l&.positive?
end
end
options[:limit] = request.limit(options)
options[:limit] = request.resolve_limit(options)
pagy = Offset::Countless.new(**options, request:)
[pagy, pagy.records(collection)]
end
Expand Down
6 changes: 3 additions & 3 deletions gem/lib/pagy/toolbox/paginators/keynav_js.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ module KeynavJsPaginator
def paginate(context, set, **options)
context.instance_eval do
request = Request.new(options[:request] || self.request, options)
page = request.page(options, force_integer: false) # allow nil
page = request.resolve_page(options, force_integer: false) # allow nil
if page&.match(' ') # countless page -> no augmentation -> fallback
return pagy(:countless, set, page:, **options)
elsif page.is_a?(String) # keynav page param
page_arguments = JSON.parse(B64.urlsafe_decode(page))
# Restart the pagination from page 1 if the url has been requested from another browser
options[:page] = page_arguments if self.request.cookies['pagy'] == page_arguments.shift
options[:page] = page_arguments if request.cookie == page_arguments.shift
end

options[:limit] = request.limit(options)
options[:limit] = request.resolve_limit(options)
pagy = Keyset::Keynav.new(set, **options, request:)
[pagy, pagy.records]
end
Expand Down
4 changes: 2 additions & 2 deletions gem/lib/pagy/toolbox/paginators/keyset.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ module KeysetPaginator
def paginate(context, set, **options)
context.instance_eval do
request = Request.new(options[:request] || self.request, options)
options[:page] ||= request.page(options, force_integer: false) # allow nil
options[:limit] = request.limit(options)
options[:page] ||= request.resolve_page(options, force_integer: false) # allow nil
options[:limit] = request.resolve_limit(options)
pagy = Keyset.new(set, **options, request:)
[pagy, pagy.records]
end
Expand Down
4 changes: 2 additions & 2 deletions gem/lib/pagy/toolbox/paginators/offset.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ module OffsetPaginator
def paginate(context, collection, **options)
context.instance_eval do
request = Request.new(options[:request] || self.request, options)
options[:page] ||= request.page(options)
options[:limit] = request.limit(options)
options[:page] ||= request.resolve_page(options)
options[:limit] = request.resolve_limit(options)
options[:count] ||= collection.instance_of?(Array) ? collection.size : OffsetPaginator.get_count(collection, options)
pagy = Offset.new(**options, request:)
[pagy, collection.instance_of?(Array) ? collection[pagy.offset, pagy.limit] : pagy.records(collection)]
Expand Down

0 comments on commit c7286fd

Please sign in to comment.