class Lux::Application
Main application router
Attributes
Public Class Methods
# File lib/lux/application/application.rb, line 128 def self.namespace name, &block @@namespaces[name] = block end
# 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
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
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
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
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
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
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
# 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
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
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
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
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 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
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