class Pagy

main class

See Pagy::Backend API documentation: ddnexus.github.io/pagy/api/backend

See the Pagy documentation: ddnexus.github.io/pagy/extras/arel

See the Pagy documentation: ddnexus.github.io/pagy/extras/array

See the Pagy documentation: ddnexus.github.io/pagy/extras/elasticsearch_rails

See the Pagy documentation: ddnexus.github.io/pagy/extras/headers

See the Pagy documentation: ddnexus.github.io/pagy/extras/i18n

See the Pagy documentation: ddnexus.github.io/pagy/extras/metadata

See the Pagy documentation: ddnexus.github.io/pagy/extras/overflow

See the Pagy documentation: ddnexus.github.io/pagy/extras/searchkick

See the Pagy documentation: ddnexus.github.io/pagy/extras/support

See the Pagy documentation: ddnexus.github.io/pagy/extras/trim

Constants

I18n

I18n static hash loaded at startup, used as default alternative to the i18n gem. see ddnexus.github.io/pagy/api/frontend#i18n

INSTANCE_VARS_MIN
ITEMS_PLACEHOLDER
PAGE_PLACEHOLDER
VARS

default vars

VERSION

Attributes

count[R]
from[R]
items[R]
last[R]
next[R]
offset[R]
page[R]
pages[R]
prev[R]
to[R]
vars[R]

Public Class Methods

deprecated_arg(arg, val, new_key, new_val) click to toggle source

deprecated posiitioal arguments

# File lib/pagy/deprecation.rb, line 20
def deprecated_arg(arg, val, new_key, new_val)
  value = val || new_val  # we use the new_val if present
  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.)
  value
end
deprecated_order(pagy, page) click to toggle source

deprecated pagy_url_for argument order

# File lib/pagy/deprecation.rb, line 13
def deprecated_order(pagy, page)
  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.)
  [page, pagy]
end
deprecated_var(var, val, new_var, new_val) click to toggle source

deprecated variables

# File lib/pagy/deprecation.rb, line 6
def deprecated_var(var, val, new_var, new_val)
  value = val || new_val
  Warning.warn %([PAGY WARNING] deprecated use of '#{var}' var will not be supported in 5.0! Use '#{new_var}: #{value.inspect}' instead.)
  value
end
new(vars) click to toggle source

Merge and validate the options, do some simple arithmetic and set the instance variables

# File lib/pagy.rb, line 24
def initialize(vars)
  @vars = VARS.merge( vars.delete_if{|k,v| VARS.key?(k) && (v.nil? || v == '') } )
  @vars[:fragment] = Pagy.deprecated_var(:anchor, @vars[:anchor], :fragment, @vars[:fragment]) if @vars[:anchor]

  INSTANCE_VARS_MIN.each do |name,min|
    raise VariableError.new(self), "expected :#{name} >= #{min}; got #{@vars[name].inspect}" \
          unless @vars[name] && instance_variable_set(:"@#{name}", @vars[name].to_i) >= min
  end
  @pages = @last = [(@count.to_f / @items).ceil, 1].max
  raise OverflowError.new(self), "expected :page in 1..#{@last}; got #{@page.inspect}" \
        if @page > @last

  @offset = @items * (@page - 1) + @outset
  @items  = @count - ((@pages - 1) * @items) if @page == @last && @count.positive?
  @from   = @count.zero? ? 0 : @offset + 1 - @outset
  @to     = @count.zero? ? 0 : @offset + @items - @outset
  @prev   = (@page - 1 unless @page == 1)
  @next   = @page == @last ? (1 if @vars[:cycle]) : @page + 1
end
new_from_elasticsearch_rails(response, vars={}) click to toggle source

create a Pagy object from an Elasticsearch::Model::Response::Response object

# File lib/pagy/extras/elasticsearch_rails.rb, line 21
def self.new_from_elasticsearch_rails(response, vars={})
  vars[:items] = response.search.options[:size] || 10
  vars[:page]  = (response.search.options[:from] || 0) / vars[:items] + 1
  total        = response.respond_to?(:raw_response) ? response.raw_response['hits']['total'] : response.response['hits']['total']
  vars[:count] = total.is_a?(Hash) ? total['value'] : total
  new(vars)
end
new_from_meilisearch(results, vars={}) click to toggle source

create a Pagy object from a Meilisearch results

# File lib/pagy/extras/meilisearch.rb, line 17
def self.new_from_meilisearch(results, vars={})
  vars[:items] = results.raw_answer['limit']
  vars[:page]  = [results.raw_answer['offset'] / vars[:items], 1].max
  vars[:count] = results.raw_answer['nbHits']
  new(vars)
end
new_from_searchkick(results, vars={}) click to toggle source

create a Pagy object from a Searchkick::Results object

# File lib/pagy/extras/searchkick.rb, line 21
def self.new_from_searchkick(results, vars={})
  vars[:items] = results.options[:per_page]
  vars[:page]  = results.options[:page]
  vars[:count] = results.total_count
  new(vars)
end
root() click to toggle source

Root pathname to get the path of Pagy files like templates or dictionaries

# File lib/pagy.rb, line 11
def self.root
  @root ||= Pathname.new(__dir__).freeze
end

Public Instance Methods

pagy_countless_get_items(collection, pagy) click to toggle source

Sub-method called only by pagy_countless: here for easy customization of record-extraction by overriding

# File lib/pagy/extras/countless.rb, line 27
def pagy_countless_get_items(collection, pagy)
  # This should work with ActiveRecord, Sequel, Mongoid...
  return collection.offset(pagy.offset).limit(pagy.items) if pagy.vars[:countless_minimal]

  items      = collection.offset(pagy.offset).limit(pagy.items + 1).to_a
  items_size = items.size
  items.pop if items_size == pagy.items + 1
  # finalize may adjust pagy.items, so must be used after checking the size
  pagy.finalize(items_size)
  items
end
pagy_countless_get_vars(_collection, vars) click to toggle source

Sub-method called only by pagy_countless: here for easy customization of variables by overriding

# File lib/pagy/extras/countless.rb, line 20
def pagy_countless_get_vars(_collection, vars)
  pagy_set_items_from_params(vars) if defined?(UseItemsExtra)
  vars[:page] ||= params[ vars[:page_param] || VARS[:page_param] ]
  vars
end
pagy_get_items(collection, pagy) click to toggle source

Sub-method called only by pagy: here for easy customization of record-extraction by overriding

# File lib/pagy/backend.rb, line 29
def pagy_get_items(collection, pagy)
  # This should work with ActiveRecord, Sequel, Mongoid...
  collection.offset(pagy.offset).limit(pagy.items)
end
pagy_get_vars(collection, vars) click to toggle source

Sub-method called only by pagy: here for easy customization of variables by overriding

# File lib/pagy/backend.rb, line 21
def pagy_get_vars(collection, vars)
  pagy_set_items_from_params(vars) if defined?(UseItemsExtra)
  vars[:count] ||= (c = collection.count(:all)).is_a?(Hash) ? c.size : c
  vars[:page]  ||= params[ vars[:page_param] || VARS[:page_param] ]
  vars
end
sequels(steps=nil) click to toggle source

`Pagy` instance method used by the `pagy*_nav_js` helpers. It returns the sequels of width/series generated from the :steps hash Example: >> pagy = Pagy.new(count:1000, page: 20, steps: {0 => [1,2,2,1], 350 => [2,3,3,2], 550 => [3,4,4,3]}) >> pagy.sequels #=> { “0” => [1, :gap, 18, 19, “20”, 21, 22, :gap, 50],

"350" => [1, 2, :gap, 17, 18, 19, "20", 21, 22, 23, :gap, 49, 50],
"550" => [1, 2, 3, :gap, 16, 17, 18, 19, "20", 21, 22, 23, 24, :gap, 48, 49, 50] }

Notice: if :steps is false it will use the single {0 => @vars} size

# File lib/pagy/extras/shared.rb, line 19
def sequels(steps=nil)
  steps ||= @vars[:steps] || {0 => @vars[:size]}
  raise VariableError.new(self), "expected :steps to define the 0 width; got #{steps.inspect}" \
        unless steps.key?(0)
  {}.tap do |sequels|
    steps.each {|width, size| sequels[width.to_s] = series(size)}
  end
end
series(size=@vars[:size]) click to toggle source

Return the array of page numbers and :gap items e.g. [1, :gap, 7, 8, “9”, 10, 11, :gap, 36]

# File lib/pagy.rb, line 45
def series(size=@vars[:size])
  return [] if size.empty?
  raise VariableError.new(self), "expected 4 items >= 0 in :size; got #{size.inspect}" \
        unless size.size == 4 && size.all?{ |num| !num.negative? rescue false }  # rubocop:disable Style/RescueModifier
  # This algorithm is up to ~5x faster and ~2.3x lighter than the previous one (pagy < 4.3)
  left_gap_start  =     1 + size[0]
  left_gap_end    = @page - size[1] - 1
  right_gap_start = @page + size[2] + 1
  right_gap_end   = @last - size[3]
  left_gap_end    = right_gap_end  if left_gap_end   > right_gap_end
  right_gap_start = left_gap_start if left_gap_start > right_gap_start
  series = []
  start  = 1
  if (left_gap_end - left_gap_start).positive?
    series.push(*start..(left_gap_start - 1), :gap)
    start = left_gap_end + 1
  end
  if (right_gap_end - right_gap_start).positive?
    series.push(*start..(right_gap_start - 1), :gap)
    start = right_gap_end + 1
  end
  series.push(*start..@last)
  series[series.index(@page)] = @page.to_s
  series
end