Skip to content

Instantly share code, notes, and snippets.

@brenoperucchi
Last active August 29, 2015 14:23
Show Gist options
  • Save brenoperucchi/fec0aecd3d4b73fd02fb to your computer and use it in GitHub Desktop.
Save brenoperucchi/fec0aecd3d4b73fd02fb to your computer and use it in GitHub Desktop.
Paginate Tag with Liquid Filter using paginate gem
# Paginate a collection
#
# Usage:
#
# {% paginate contents.projects by 5 %}
# {% for project in paginate.collection %}
# {{ project.name }}
# {% endfor %}
# {% endpaginate %}
require 'i18n'
class PaginateTag < Liquid::Block
Syntax = /(#{Liquid::QuotedFragment})\s*(by\s*(\d+))?/
def initialize(tag_name, markup, options)
super
if markup =~ Syntax
@collection_name = $1
@page_size = if $2
$3.to_i
else
20
end
@attributes = { 'window_size' => 3 }
markup.scan(Liquid::TagAttributes) do |key, value|
@attributes[key] = value
end
else
raise SyntaxError.new("Syntax Error in tag 'paginate' - Valid syntax: paginate [collection] by number")
end
end
def render(context)
@context = context
context.stack do
path = context.registers[:controller].request.path
params = context.registers[:controller].params.clone
collection = context[@collection_name]
pagination = {
'page_size' => per_page,
'current_page' => current_page,
'current_offset' => (current_page-1) * per_page
}
context['paginate'] = pagination
paginate_collection = @collection_name.classify.constantize.paginate(
:page => current_page,
:per_page => per_page)
new_collection = paginate_collection.map{|product| Imentore::ProductDrop.new(product)}
context[@collection_name] = new_collection
collection_size = context[@collection_name].size
raise ArgumentError.new("Cannot paginate array '#{@collection_name}'. Not found.") if collection_size.nil?
# page_count = (collection_size.to_f / per_page.to_f).to_f.ceil + 1
page_count = paginate_collection.total_pages
pagination['current_offset'] = (current_page-1) * per_page
pagination['current_page'] = current_page
pagination['page_size'] = per_page
pagination['pages'] = page_count
pagination['items'] = paginate_collection.total_entries
pagination['items_page'] = paginate_collection.count
pagination['previous'] = link(I18n.t(:previous_label, scope: 'will_paginate').html_safe, current_page - 1) unless 1 >= current_page
pagination['next'] = link(I18n.t(:next_label, scope: 'will_paginate').html_safe, current_page + 1) unless page_count < current_page + 1
pagination['parts'] = []
hellip_break = false
if page_count > 1
1.upto(page_count) do |page|
if current_page == page
pagination['parts'] << no_link(page)
elsif page == 1
pagination['parts'] << link(page, page)
elsif page == page_count - 1
pagination['parts'] << link(page, page)
elsif page <= current_page - @attributes['window_size'] || page >= current_page + @attributes['window_size']
next if hellip_break
pagination['parts'] << no_link('&hellip;')
hellip_break = true
next
else
pagination['parts'] << link(page, page)
end
hellip_break = false
end
end
super
end
end
private
def per_page?
@context.registers[:controller].params[:per_page].present?
end
def per_page
# binding.pry
if per_page?
@context.registers[:controller].params[:per_page].to_i if per_page?
else
@page_size
end
end
def current_page
_current_page = @context.registers[:controller].params[:page]
# _current_page = 1 if @context[@collection_name].count < per_page
# _current_page
_current_page.nil? ? 1 : _current_page.to_i
end
def current_url
current_url = @context.registers[:controller].request.fullpath.gsub(/(per_page=)[0-9]+&?/, '')
current_url = current_url.gsub(/(page=)[0-9]+&?/, '')
current_url = current_url.slice(0..-2) if current_url.last == '?' || current_url.last == '&'
current_url
end
def no_link(title)
{ 'title' => title, 'is_link' => false, 'hellip_break' => title == '&hellip;' }
end
def link(title, page)
_current_url = %(#{current_url}#{current_url.include?('?') ? '&' : '?'}page=#{page})
# _current_url += "#{current_url.include?('?') ? '&' : '?'}per_page=#{per_page}" if per_page?
{ 'title' => title, 'url' => _current_url, 'is_link' => true }
end
end
Liquid::Template.register_tag('paginate', PaginateTag)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment