Class: Lux::Application

Inherits:
Object show all
Defined in:
lib/lux/application/application.rb

Overview

Main application router

Defined Under Namespace

Classes: MagicRoutes, Nav

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(current) ⇒ Application

Returns a new instance of Application.



44
45
46
47
48
# File 'lib/lux/application/application.rb', line 44

def initialize current
  raise 'Config is not loaded (Lux.start not called), cant render page' unless Lux.config.lux_config_loaded

  @current = current
end

Instance Attribute Details

#currentObject (readonly)

Returns the value of attribute current.



30
31
32
# File 'lib/lux/application/application.rb', line 30

def current
  @current
end

#route_targetObject (readonly)

Returns the value of attribute route_target.



30
31
32
# File 'lib/lux/application/application.rb', line 30

def route_target
  @route_target
end

Class Method Details

.namespace(name, &block) ⇒ Object



128
129
130
# File 'lib/lux/application/application.rb', line 128

def self.namespace name, &block
  @@namespaces[name] = block
end

Instance Method Details

#call(object = nil, action = nil) ⇒ Object

Calls target action in a controller, if no action is given, defaults to :index “‘ call :api_router call proc { ’string’ } call proc { [400, {}, ‘error: …’] } call [200, {}, [‘ok’]] call Main::UsersController call Main::UsersController, :index call [Main::UsersController, :index] call ‘main/orgs#show’ “‘



253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
# File 'lib/lux/application/application.rb', line 253

def call object=nil, action=nil
  # log original app caller
  root    = Lux.root.join('app/').to_s
  sources = caller.select { |it| it.include?(root) }.map { |it| 'app/' + it.sub(root, '').split(':in').first }
  action  = action.gsub('-', '_').to_sym if action && action.is_a?(String)

  Lux.log ' Routed from: %s' % sources.join(' ') if sources.first

  case object
    when Symbol
      return send(object)
    when Hash
      object = [object.keys.first, object.values.first]
    when String
      object, action = object.split('#') if object.include?('#')
    when Array
      if object[0].class == Integer && object[1].class == Hash
        # [200, {}, 'ok']
        for key, value in object[1]
          response.header key, value
        end

        response.status object[0]
        response.body object[2]
      else
        object, action = object
      end
    when Proc
      case data = object.call
        when Array
          response.status = data.first
          response.body data[2].is_a?(Array) ? data[2][0] : data[2]
        else
          response.body data
      end
  end

  throw :done if body?

  # figure our action unless defined
  unless action
    id =
    if respond_to?(:id?)
      nav.root { |root_id| id?(root_id) }
    else
      nav.root { |root_id| root_id.is_numeric? ? root_id.to_i : nil }
    end

    if id
      current.nav.id = id
      action = nav.shift || :show
    else
      action = nav.shift || :index
    end
  end

  object = ('%s_controller' % object).classify.constantize if object.is_a?(String)

  controller_name = "app/controllers/#{object.to_s.underscore}.rb"
  Lux.log ' %s' % controller_name
  current.files_in_use controller_name

  object.action action.to_sym

  unless response.body
    Lux.error 'Lux cell "%s" called via route "%s" but page body is not set' % [object, nav.root]
  end
end

#error(code = nil, message = nil) ⇒ Object

Triggers HTTP page error “‘ error.not_found error.not_found ’Doc not fount’ error(404) error(404, ‘Doc not fount’) “‘



57
58
59
60
61
62
63
64
65
# File 'lib/lux/application/application.rb', line 57

def error code=nil, message=nil
  if code
    error = Lux::Error.new code
    error.message = message if message
    raise error
  else
    Lux::Error::AutoRaise
  end
end

#map(route_object) ⇒ Object

Main routing object, maps path part to target if path part is positively matched with ‘test?` method, target is called with `call` method “` map api: ApiController map api: ’api’ map [:api, ApiController] map ‘main/root’ do map [:login, :signup] => ‘main/root’ map Main::RootController do

map :about
map '/verified-user'

end “‘



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/lux/application/application.rb', line 181

def map route_object
  klass  = nil
  route  = nil
  action = nil

  # map 'root' do
  #   ...
  if block_given?
    @lux_action_target = route_object
    yield
    @lux_action_target = nil
    return
  elsif @lux_action_target
    klass  = @lux_action_target
    route  = route_object
    action = route_object

    # map :foo => :some_action
    if route_object.is_a?(Hash)
      route  = route_object.keys.first
      action = route_object.values.first
    end

    if test?(route)
      call klass, action
    else
      return
    end
  end

  case route_object
  when String
    # map 'root#call'
    call route_object
  when Hash
    route  = route_object.keys.first
    klass  = route_object.values.first

    if route.class == Array
      # map [:foo, :bar] => 'root'
      for route_action in route
        if test?(route_action)
          call klass, route_action
        end
      end

      return
    elsif route.is_a?(String) && route[0,1] == '/'
      # map '/skils/:skill' => 'main/skills#show'
      return match route, klass
    end
  when Array
    # map [:foo, 'main/root']
    route, klass = *route_object
  else
    Lux.error 'Unsupported route type "%s"' % route_object.class
  end

  test?(route) ? call(klass) : nil
end

#match(base, target) ⇒ Object

standard route match match ‘/:city/people’, Main::PeopleController



113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/lux/application/application.rb', line 113

def match base, target
  base = base.split('/').slice(1, 100)

  base.each_with_index do |el, i|
    if el[0,1] == ':'
      params[el.sub(':','').to_sym] = nav.path[i]
    else
      return unless el == nav.path[i]
    end
  end

  call target
end

#namespace(name) ⇒ Object

Matches namespace block in a path if returns true value, match is positive and nav is shifted if given ‘Symbol`, it will call the function to do a match if given `String`, it will match the string value “` self.namespace :city do

@city = City.first slug: nav.root
!!@city

end namespace ‘dashboard’ do

map orgs: 'dashboard/orgs'

end “‘



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/lux/application/application.rb', line 145

def namespace name
  if String === name
    return unless test?(name.to_s)
  else
    if @@namespaces[name]
      return unless instance_exec &@@namespaces[name]
      nav.shift
    else
      raise ArgumentError.new('Namespace block :%s is not defined' % name)
    end
  end

  yield

  raise Lux::Error.not_found("Namespace <b>:#{name}</b> matched but nothing is called")
end

#on_error(error) ⇒ Object

Action to do if there is an application error. You want to overload this in a production.



324
325
326
# File 'lib/lux/application/application.rb', line 324

def on_error error
  raise error
end

#renderObject



328
329
330
331
332
333
334
335
336
# File 'lib/lux/application/application.rb', line 328

def render
  Lux.log "\n#{current.request.request_method.white} #{current.request.url}"

  Lux::Config.live_require_check! if Lux.config(:auto_code_reload)

  main

  response.render
end

#response(body = nil, status = nil) ⇒ Object

Quick response to page body “‘ response ’ok’ if nav.root == ‘healthcheck’ “‘



71
72
73
74
75
76
77
# File 'lib/lux/application/application.rb', line 71

def response body=nil, status=nil
  return @current.response unless body

  response.status status || 200
  response.body body
  throw :done
end

#root(target) ⇒ Object

Matches if there is not root in nav Example calls MainController.action(:index) if in root “‘ root ’main#index’ “‘



107
108
109
# File 'lib/lux/application/application.rb', line 107

def root target
  call target unless nav.root
end

#subdomain(name) ⇒ Object

Matches given subdomain name



163
164
165
166
# File 'lib/lux/application/application.rb', line 163

def subdomain name
  return unless nav.subdomain == name
  error.not_found 'Subdomain "%s" matched but nothing called' % name
end

#test?(route) ⇒ Boolean

Tests current root against the string to get a mach. Used by map function

Returns:

  • (Boolean)


81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/lux/application/application.rb', line 81

def test? route
  root = nav.root.to_s

  ok = case route
    when String
      root == route.sub(/^\//,'')
    when Symbol
      route.to_s == root
    when Regexp
      !!(route =~ root)
    when Array
      !!route.map(&:to_s).include?(root)
    else
      raise 'Route type %s is not supported' % route.class
  end

  nav.shift if ok

  ok
end