class LayoutEngine

Public Class Methods

new(app = nil, message = "Response Time") click to toggle source

honestly, this is a hugely important file, but there shouldn’t be anything in this file that concerns regular developers or users. Here we figure out which is the current page, then collect which blocks go on a layout and which layouts go on a page. For each block, if it holds a model_display, we’ll call the controller for that model. treat your controllers and models like you would in a normal rails app. this does set some environment variables that are then used in your controllers, but inspect them there. if you’ve set up your page->layouts->blocks->model_displays->field_displays properly this should just work. if you’ve created a page using the gui and its not working.. check it’s path setting and check your routes file to see that they are looking right.

# File lib/mega_bar/layout_engine.rb, line 13
def initialize(app = nil, message = "Response Time")
  @app = app
  @message = message
end

Public Instance Methods

_call(env) click to toggle source
# File lib/mega_bar/layout_engine.rb, line 22
def _call(env)
  # so.. a lot does go on here... I'll have to write a white paper.
  if env['PATH_INFO'].end_with?('.css')  || env['PATH_INFO'].end_with?('.js') || env['PATH_INFO'].end_with?('.jpeg')
    @status, @headers, @response = @app.call(env)
    return  [@status, @headers, self]
  end
  env['REQUEST_METHOD'] = "PATCH" if  env['REQUEST_METHOD'] == "PUT"
  @redirect = false
  request = Rack::Request.new(env)
  request.params # strangely this needs to be here for best_in_place updates.
  # MegaBar::Engine.routes.routes.named_routes.values.map do |route|

  site = MegaBar::Site.where(domains: request.host).first
  site = MegaBar::Site.first unless site
  #   puts  route.instance_variable_get(:@constraints)[:request_method].to_s + "#{route.defaults[:controller]}##{route.defaults[:action]}"
  # end #vs. Rails.application.routes.routes.named_routes.values.map
  # Rails.application.routes.routes.named_routes.values.map do |route|
  #   puts  route.instance_variable_get(:@constraints)[:request_method].to_s + "#{route.defaults[:controller]}##{route.defaults[:action]}"
  # end #vs. Rails.application.routes.routes.named_routes.values.map
  ################################
  ## figure out what page it is
  # the general strategy is..
  # have rails recognize the path_info..
  # tbcontinued.
  request.session[:return_to] = env['rack.request.query_hash']['return_to'] unless env['rack.request.query_hash']['return_to'].blank?
  rout_terms = request.path_info.split('/').reject! { |c| (c.nil? || c.empty?) }
  env[:mega_rout] = rout = set_rout(request, env)
  env[:mega_page] = page_info = set_page_info(rout, rout_terms)
  pagination = set_pagination_info(env, rout_terms)
  if page_info.empty? #non megabar pages.
    gotta_be_an_array = []
    if rout[:controller].nil?
      rout[:controller] = 'flats'
      rout[:action] = 'index'
    end
    @status, @headers, @page = (rout[:controller].classify.pluralize + "Controller").constantize.action(rout[:action]).call(env)
    gotta_be_an_array << page = @page.blank? ? '' : @page.body.html_safe
    return @status, @headers, gotta_be_an_array
  end
  ################################
  orig_query_hash = Rack::Utils.parse_nested_query(env['QUERY_STRING'])
  final_layouts = []

  page_layouts = MegaBar::Layout.by_page(page_info[:page_id]).includes(:sites, :themes)

  page_layouts.each do | page_layout |
    next if mega_filtered(page_layout, site)
    env[:mega_layout] = page_layout

    final_layout_sections = process_page_layout(page_layout, page_info, rout, orig_query_hash, pagination, site, env)

    env['mega_final_layout_sections'] = final_layout_sections #used in master_layouts_controller
    @status, @headers, @layouts = MegaBar::MasterLayoutsController.action(:render_layout_with_sections).call(env)
    final_layouts <<  l = @layouts.blank? ? '' : @layouts.body.html_safe
  end


  env['mega_final_layouts'] = final_layouts
  @status, @headers, @page = MegaBar::MasterPagesController.action(:render_page).call(env)
  final_page = []
  final_page_content = @page.blank? ? '' : @page.body.html_safe
  # final_page_content = @page.instance_variable_get(:@response).nil? ? @page.instance_variable_get(:@body).instance_variable_get(:@stream).instance_variable_get(:@buf)[0] : @page.instance_variable_get(:@response).instance_variable_get(:@stream).instance_variable_get(:@buf)[0]
  final_page << final_page_content
  return @redirect ? [@redirect[0], @redirect[1], ['you are being redirected']] : [@status, @headers, final_page]
end
action_from_path(path, method, path_segments) click to toggle source
# File lib/mega_bar/layout_engine.rb, line 189
def action_from_path(path, method, path_segments)
  path_array = path.split('/')
  if method == 'GET'
    if ['edit', 'new'].include?(path_array.last)
      path_array.last
    elsif path.last.match(/^(\d)+$/)
      'show'
    elsif  path_segments.include?(path_array.last)
      'index'
    else
      path_array.last
    end
  elsif ['POST', 'PUT', 'PATCH'].include? method
    path.last.match(/^(\d)+$/) ? 'update' : 'create'
  elsif ['DELETE'].include? method
    'delete'
  end
end
call(env) click to toggle source
# File lib/mega_bar/layout_engine.rb, line 18
def call(env)
  dup._call(env)
end
each(&display) click to toggle source
# File lib/mega_bar/layout_engine.rb, line 88
def each(&display)
  display.call("<!-- #{@message}: #{@stop - @start} -->\n") if (!@headers['Content-Type'].nil? && @headers["Content-Type"].include?("text/html"))
  @response.each(&display)
end
mega_filtered(obj, site) click to toggle source
# File lib/mega_bar/layout_engine.rb, line 208
def mega_filtered(obj, site)
  if obj.sites.present?
    has_zero_site = obj.sites.pluck(:id).include?(0)
    has_site = obj.sites.pluck(:id).include?(site.id)
    return true if has_zero_site and has_site
    return  true if !has_site
  end
  if obj.themes.present?
    has_zero_theme = obj.themes.pluck(:id).include?(0)
    has_theme = obj.themes.pluck(:id).include?(site.theme_id)
    return true if has_zero_theme and has_theme
    return true if !has_theme
  end
  false
end
process_block(blck, page_info, rout, orig_query_hash, pagination, env) click to toggle source
# File lib/mega_bar/layout_engine.rb, line 161
def process_block(blck, page_info, rout, orig_query_hash, pagination, env)
  if ! blck.html.nil? && ! blck.html.empty?
    bip = '<span data-bip-type="textarea" data-bip-attribute="html" data-bip-object="block" data-bip-original-content="' +  blck.html + '" data-bip-skip-blur="false" data-bip-url="/mega-bar/blocks/' + blck.id.to_s + '" data-bip-value="' +  blck.html + '" class="best_in_place" id="best_in_place_block_' + blck.id.to_s + '_html">' + blck.html.html_safe + '</span>'
    bip.html_safe
  elsif blck.model_displays.empty?
    ''
  else
    params_hash = {} # used to set params var for controllers
    params_hash_arr = [] #used to collect 'params_hash' pieces
    mega_env = MegaEnv.new(blck, rout, page_info, pagination) # added to env for use in controllers
    params_hash_arr = mega_env.params_hash_arr
    env[:mega_env] = mega_env.to_hash
    params_hash_arr << {action: mega_env.block_action}
    params_hash_arr << {controller: mega_env.kontroller_path}
    params_hash_arr.each do |param|
      params_hash = params_hash.merge(param)
    end
    params_hash = params_hash.merge(orig_query_hash)
    params_hash = params_hash.merge(env['rack.request.form_hash']) if !env['rack.request.form_hash'].nil? # && (mega_env.block_action == 'update' || mega_env.block_action == 'create')
    env['QUERY_STRING'] = params_hash.to_param # 150221!
    env['action_dispatch.request.parameters'] = params_hash
    env['block_class'] = blck.name.downcase.parameterize.underscore
    @status, @headers, @disp_body = mega_env.kontroller_klass.constantize.action(mega_env.block_action).call(env)
    @redirect = [@status, @headers, @disp_body] if @status == 302
    block_body = @disp_body.blank? ? '' : @disp_body.body.html_safe
  end
end
process_page_layout(page_layout, page_info, rout, orig_query_hash, pagination, site, env) click to toggle source
# File lib/mega_bar/layout_engine.rb, line 139
def process_page_layout(page_layout, page_info, rout, orig_query_hash, pagination, site, env)
  final_layout_sections = {}

  page_layout.layout_sections.each do | layout_section |
    template_section = MegaBar::TemplateSection.find(layout_section.layables.where(layout_id: page_layout.id).first.template_section_id).code_name
    blocks = MegaBar::Block.by_layout_section(layout_section.id)
    blocks = blocks.by_actions(rout[:action]) unless rout.blank?
    final_blocks = []
    next unless blocks.present?
    final_layout_sections[template_section] = []
    env[:mega_layout_section] = layout_section
    blocks.each do |blck|
      next if mega_filtered(blck, site)
      final_blocks << process_block(blck, page_info, rout, orig_query_hash, pagination, env)
    end
    env['mega_final_blocks'] = final_blocks #used in master_layouts_controller
    @status, @headers, @layout_sections = MegaBar::MasterLayoutSectionsController.action(:render_layout_section_with_blocks).call(env)
    final_layout_sections[template_section] <<  ls = @layout_sections.blank? ? '' : @layout_sections.body.html_safe
  end
  final_layout_sections
end
set_page_info(rout, rout_terms) click to toggle source
# File lib/mega_bar/layout_engine.rb, line 94
def set_page_info(rout, rout_terms)

  page_info = {}
  rout_terms ||= []
  diff = 20
  prev_diff = 21
  MegaBar::Page.all.order(' id desc').pluck(:id, :path, :name).each do | page |
    page_path_terms = page[1].split('/').map{ | m | m if m[0] != ':'} - ["", nil]
    next if (rout_terms - page_path_terms).size != rout_terms.size - page_path_terms.size
    next if (page_path_terms.empty? && !rout_terms.empty? ) # home page /
    diff = (rout_terms - page_path_terms).size
    page_terms = page[1].split('/').reject! { |c| (c.nil? || c.empty?) }
    page_terms ||= []
    variable_segments = []
    page_terms.each_with_index do | v, k |
      variable_segments << rout_terms[k] if page_terms[k].starts_with?(':')
    end
    variable_segments << rout_terms[page_terms.size] if Integer(rout_terms[page_terms.size]) rescue false
    page_info = {page_id: page[0], page_path: page[1], terms: page_terms, vars: variable_segments, name: page[2]} if diff < prev_diff
    prev_diff = diff
  end
  page_info
end
set_pagination_info(env, rout_terms) click to toggle source
# File lib/mega_bar/layout_engine.rb, line 126
def set_pagination_info(env, rout_terms)
  rout_terms ||= []
  pagination_info = []
  rout_terms.map.with_index do |x, i|
   pagination_info <<  {kontrlr: x, page: rout_terms[i + 1] }  if /_page/ =~ x
  end
  q_hash = Rack::Utils.parse_nested_query(env['QUERY_STRING'])
  q_hash.keys.map do | key |
    pagination_info <<  {kontrlr: key, page: q_hash[key] }  if /_page/ =~ key
  end
  pagination_info
end
set_rout(request, env) click to toggle source
# File lib/mega_bar/layout_engine.rb, line 118
def set_rout(request, env)
  request_path_info = request.path_info.dup
  rout = (Rails.application.routes.recognize_path request_path_info, method: env['REQUEST_METHOD'] rescue {}) || {}
  rout = (MegaBar::Engine.routes.recognize_path request_path_info rescue {}) || {}  if rout.empty? && request_path_info == '/mega-bar' #yeah, a special case for this one.
  rout = (MegaBar::Engine.routes.recognize_path request_path_info.sub!('/mega-bar/', ''), method: env['REQUEST_METHOD'] rescue {}) || {}  if rout.empty?
  rout
end