Skip to content

Instantly share code, notes, and snippets.

@tanraya
Created February 5, 2014 12:10
Show Gist options
  • Save tanraya/8822400 to your computer and use it in GitHub Desktop.
Save tanraya/8822400 to your computer and use it in GitHub Desktop.
# Render index page
class IndexFor
DEFAULT_OPTIONS = {
by: nil,
pagination: :bottom, # top, bottom, both
}.with_indifferent_access
attr_reader :resource, :options, :block, :h
def initialize(resource, options = {}, view_context, &block)
@resource = resource
@options = with_default_options(options)
@block = block
@h = view_context
end
def render
result = if collection?
if grouped_collection?
render_collection_groups
else
render_collection
end
else
render_entry
end
h.content_tag :div, class: wrapper_html_class do
h.concat(render_heading)
h.concat(h.raw(result))
h.concat(h.paginate(resource)) if collection?
end
end
protected
def with_default_options(options)
DEFAULT_OPTIONS.merge(options)
end
def collection?
resource.respond_to?(:each)
end
def grouped_collection?
collection? && options[:by].to_i > 0
end
def render_heading
if collection?
h.heading_with_title
h.heading_with_title(h.t("#{singular_class_name}.index.heading"))
else
h.heading_with_title(resource)
end
end
def render_collection
result = ''
if block.nil?
result = h.render(resource)
else
resource.each do |res|
result << h.capture(res, &block)
end
end
result
end
def render_collection_groups
unless options[:by].to_i.even?
raise ArgumentError, "Option `by` should be even number"
end
result = ''
html_class = "col-sm-#{12 / options[:by]}"
resource.in_groups_of(options[:by], false).each do |group|
row = h.content_tag :div, class: :row do
entries = ''
group.each do |entry|
content = if block.nil?
h.render(entry)
else
h.capture(entry, &block)
end
entries << h.content_tag(:div, content, class: html_class)
end
h.raw(entries)
end
result << row
end
result
end
def render_entry
h.capture(resource, &block)
end
def class_name
if collection?
resource.klass.name.gsub('/', '_')
else
resource.class.name.gsub('/', '_')
end
end
def plural_class_name
class_name.underscore.pluralize.gsub('/', '_')
end
def singular_class_name
class_name.underscore.singularize.gsub('/', '_')
end
def wrapper_html_class
html_class = if collection?
plural_class_name
else
singular_class_name
end
"#{html_class}-wrapper"
end
end
module ApplicationHelper
def index_for(resources, options = {}, &block)
IndexFor.new(resources, options, self, &block).render
end
def show_for(resources, options = {}, &block)
IndexFor.new(resources, options, self, &block).render
end
def item_for(resource, &block)
content_tag_for :article, resource do
capture(resource, &block)
end
end
def homepage?
current_page?(root_path)
end
def homepage_or_inner_class
if homepage?
'page-home'
else
'page-inner'
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment