module BoxesHelper def insert_boxes(content) if controller.send(:boxes_editor?) && controller.send(:uses_design_blocks?) content + display_boxes_editor(controller.boxes_holder) else maybe_display_custom_element(controller.boxes_holder, :custom_header_expanded, :id => 'profile-header') + if controller.send(:uses_design_blocks?) display_boxes(controller.boxes_holder, content) else content_tag('div', content_tag('div', content_tag('div', wrap_main_content(content), :class => 'no-boxes-inner-2'), :class => 'no-boxes-inner-1' ), :class => 'no-boxes' ) end + maybe_display_custom_element(controller.boxes_holder, :custom_footer_expanded, :id => 'profile-footer') end end def box_decorator @box_decorator || DontMoveBlocks end def with_box_decorator(dec, &block) @box_decorator = dec result = block.call @box_decorator = DontMoveBlocks result end def display_boxes_editor(holder) with_box_decorator self do content_tag('div', display_boxes(holder, '<' + _('Main content') + '>'), :id => 'box-organizer') end end def boxes_limit holder controller.send(:custom_design)[:boxes_limit] || holder.boxes_limit(controller.send(:custom_design)[:layout_template]) end def display_boxes(holder, main_content) boxes = holder.boxes.with_position.first(boxes_limit(holder)) content = boxes.reverse.map { |item| display_box(item, main_content) }.join("\n") content = main_content if (content.blank?) content_tag('div', content, :class => 'boxes', :id => 'boxes' ) end def maybe_display_custom_element(holder, element, options = {}) if holder.respond_to?(element) content_tag('div', holder.send(element), options) else '' end end def display_box(box, main_content) content_tag('div', content_tag('div', display_box_content(box, main_content), :class => 'blocks'), :class => "box box-#{box.position}", :id => "box-#{box.id}" ) end def display_updated_box(box) with_box_decorator self do display_box_content(box, '<' + _('Main content') + '>') end end def display_box_content(box, main_content) context = { :article => @page, :request_path => request.path, :locale => locale, :params => request.params, :user => user, :controller => controller } box_decorator.select_blocks(box, box.blocks.includes(:box), context).map do |item| display_block item, main_content end.join("\n") + box_decorator.block_target(box) end def select_blocks box, arr, context arr end def display_block(block, main_content = nil) render :file => 'shared/block', :locals => {:block => block, :main_content => main_content, :use_cache => use_cache? } end def use_cache? box_decorator == DontMoveBlocks end def render_block_content(block) template_name = block.class.name.underscore.gsub('_block', '') template_filename = "#{template_name}.html.erb" if File.exists? Rails.root.join('app', 'views', 'blocks', template_filename) render :file => "blocks/#{template_name}", :locals => { :block => block } else nil end end def render_block_footer(block) template_name = block.class.name.underscore.gsub('_block', '') template_filename = "#{template_name}.html.erb" if File.exists? Rails.root.join('app', 'views', 'blocks', 'footers', template_filename) render :file => "blocks/footers/#{template_name}", :locals => { :block => block } else nil end end def display_block_content(block, main_content = nil) content = block.main? ? wrap_main_content(main_content) : render_block_content(block) result = extract_block_content(content) footer_content = extract_block_content(render_block_footer(block)) unless footer_content.blank? footer_content = content_tag('div', footer_content, :class => 'block-footer-content' ) end options = { :class => classes = ['block', block_css_classes(block) ].uniq.join(' '), :id => "block-#{block.id}" } if ( block.respond_to? 'help' ) options[:help] = block.help end unless block.visible? options[:title] = _("This block is invisible. Your visitors will not see it.") end result = filter_html(result, block) content_tag('div', box_decorator.block_target(block.box, block) + content_tag('div', content_tag('div', content_tag('div', result + footer_content + box_decorator.block_edit_buttons(block), :class => 'block-inner-2'), :class => 'block-inner-1'), options), :class => 'block-outer') + box_decorator.block_handle(block) end def wrap_main_content(content) content_tag('div', content, :class => 'main-content') end def extract_block_content(content) case content when Hash content_tag('iframe', '', :src => url_for(content)) when String if content.split("\n").size == 1 and content =~ /^https?:\/\// content_tag('iframe', '', :src => content) else content end when Proc self.instance_eval(&content) when NilClass '' else raise "Unsupported content for block (#{content.class})" end end module DontMoveBlocks # does nothing def self.block_target(box, block = nil) '' end # does nothing def self.block_handle(block) '' end def self.block_edit_buttons(block) '' end def self.select_blocks box, arr, context arr = arr.select{ |block| block.visible? context } custom_design = context[:controller].send(:custom_design) inserts = [custom_design[:insert]].flatten.compact inserts.each do |insert_opts| next unless box.position == insert_opts[:box] position, block = insert_opts[:position], insert_opts[:block] block = block.new box: box if block.is_a? Class if not insert_opts[:uniq] or not box.blocks.map(&:class).include? block.klass arr = arr.insert position, block end end arr end end # generates a place where you can drop a block and get the block moved to # there. # # If +block+ is not nil, then it means "place the dropped block before this # one.". Otherwise, it means "place the dropped block at the end of the # list" # # +box+ is always needed def block_target(box, block = nil) id = if block.nil? "end-of-box-#{box.id}" else "before-block-#{block.id}" end if block.nil? or movable?(block) url = url_for(:action => 'move_block', :target => id) content_tag('div', _('Drop Here'), :id => id, :class => 'block-target' ) + drop_receiving_element(id, :accept => box.acceptable_blocks, :hoverclass => 'block-target-hover', :activeClass => 'block-target-active', :tolerance => 'pointer', :onDrop => "function(ev, ui) { dropBlock('#{url}', '#{_('loading...')}', ev, ui);}") else "" end end # makes the given block draggable so it can be moved away. def block_handle(block) return "" unless movable?(block) icon = "