Class: LayoutEngine

Inherits:
Object
  • Object
show all
Defined in:
lib/mega_bar/layout_engine.rb

Instance Method Summary collapse

Constructor Details

#initialize(app = nil, message = "Response Time") ⇒ LayoutEngine

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.



13
14
15
16
# File 'lib/mega_bar/layout_engine.rb', line 13

def initialize(app = nil, message = "Response Time")
  @app = app
  @message = message
end

Instance Method Details

#_call(env) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# 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) ⇒ Object



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# 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) ⇒ Object



18
19
20
# File 'lib/mega_bar/layout_engine.rb', line 18

def call(env)
  dup._call(env)
end

#each(&display) ⇒ Object



88
89
90
91
# 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) ⇒ Object



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# 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) ⇒ Object



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# 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) ⇒ Object



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# 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) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# 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) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
137
# 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) ⇒ Object



118
119
120
121
122
123
124
# 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