lib/hermitage/rails_render_core.rb
# frozen_string_literal: true
module Hermitage
# This class performs all the rendering logic for Rails apps
class RailsRenderCore
def initialize(objects, options = {})
@objects = objects
@options = Configurator.options_for(objects, options)
@template = ActionView::Base.new
end
# Renders gallery markup
def render
# Initialize the resulting tag
tag_parts = []
# Slice objects into separate lists
lists = slice_objects
# Render each list into `tag` variable
lists.each do |list|
items = list.collect { |item| render_link_for(item) }
tag_parts << render_content_tag_for(items)
end
tag_parts.join.html_safe
end
private
# Slices objects into separate lists if it's necessary
def slice_objects
if @options[:each_slice]
@objects.each_slice(@options[:each_slice]).to_a
else
[@objects]
end
end
# Returns value of item's attribute
def value_for(item, option)
attribute = @options[option]
if attribute.is_a? Proc
attribute.call(item)
else
eval("item.#{attribute}")
end
end
# Renders link to the specific image in a gallery
def render_link_for(item)
original_path = value_for(item, :original)
thumbnail_path = value_for(item, :thumbnail)
title = @options[:title] ? value_for(item, :title) : nil
image = @template.image_tag(thumbnail_path, class: @options[:image_class])
@template.link_to(image, original_path, rel: 'hermitage',
class: @options[:link_class],
title: title)
end
# Renders items into content tag
def render_content_tag_for(items)
@template.content_tag(@options[:list_tag], class: @options[:list_class]) do
items.collect do |item|
@template.concat(@template.content_tag(@options[:item_tag], item, class: @options[:item_class]))
end
end
end
end
end