class Lux::Application

Main application router

Attributes

current[R]
route_target[R]

Public Class Methods

namespace(name, &block) click to toggle source
# File lib/lux/application/application.rb, line 128
def self.namespace name, &block
  @@namespaces[name] = block
end
new(current) click to toggle source
# 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

Public Instance Methods

call(object=nil, action=nil) click to toggle source

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' “`

# 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) click to toggle source

Triggers HTTP page error “` error.not_found error.not_found 'Doc not fount' error(404) error(404, 'Doc not fount') “`

# 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) { || ... } click to toggle source

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 “`

# 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) click to toggle source

standard route match match '/:city/people', Main::PeopleController

# 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) { || ... } click to toggle source

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 “`

# 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) click to toggle source

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

# File lib/lux/application/application.rb, line 324
def on_error error
  raise error
end
render() click to toggle source
# 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) click to toggle source

Quick response to page body “` response 'ok' if nav.root == 'healthcheck' “`

# 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) click to toggle source

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

# File lib/lux/application/application.rb, line 107
def root target
  call target unless nav.root
end
subdomain(name) click to toggle source

Matches given subdomain name

# 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) click to toggle source

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

# 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

Private Instance Methods

deliver_static_assets() click to toggle source

Deliver static assets if `Lux.config.serve_static_files == true`

# File lib/lux/application/application.rb, line 363
def deliver_static_assets
  return if body? || !Lux.config(:serve_static_files)

  ext = request.path.split('.').last
  return unless ext.length > 1 && ext.length < 5
  file = Lux::Response::File.new request.path.sub('/', ''), inline: true
  file.send if file.is_static_file?
end
main() click to toggle source

internall call to resolve the routes

# File lib/lux/application/application.rb, line 341
def main
  return if deliver_static_assets

  magic = MagicRoutes.new self

  catch(:done) do
    class_callback :before, magic
    class_callback :routes, magic unless body?
  end

  catch(:done) do
    class_callback :after, magic
  end
rescue => e
  response.body { nil }

  catch(:done) do
    on_error(e)
  end
end