Class: Spider::Controller
- Includes:
- Annotations, App::AppClass, ControllerMixins, Dispatcher, Helpers, Logger
- Defined in:
- lib/spiderfw/controller/controller.rb,
lib/spiderfw/controller/controller_exceptions.rb
Direct Known Subclasses
HTTPController, HomeController, PageController, SpiderController
Defined Under Namespace
Classes: BadRequest, ControllerError, Forbidden, Maintenance, NotFound
Instance Attribute Summary collapse
-
#dispatch_action ⇒ String
Action used to reach this controller in the dispatch chain.
-
#executed_method ⇒ Symbol
readonly
The method currently set to be executed, if any.
-
#is_target ⇒ bool
True if the controller is the target of the current action.
- #request ⇒ Spider::Request readonly
- #response ⇒ Spider::Response readonly
- #scene ⇒ Scene readonly
Attributes included from Dispatcher
Class Method Summary collapse
-
.before(conditions, method, params = {}) ⇒ void
Defines a method that will be called before the controller’s before, if the action matches the given conditions.
-
.before_methods ⇒ Array
An array of methods defined with Controller.before.
-
.before_unless(condition, method, params = {}) ⇒ void
Like Controller.before, but calls the method unless the conditions match.
- .controller_action(method, params) ⇒ Object
-
.controller_action?(method) ⇒ bool
True if the method is a controller action.
-
.controller_actions(*methods) ⇒ Array
Registers a list of methods as controller actions, that is, methods that can be dispatched to.
- .default_action ⇒ Object
-
.find_resource(type, name, cur_path = nil) ⇒ Resource
Finds a resource in the context of the controller’s app See find_resource.
-
.find_resource_path(type, name, cur_path = nil) ⇒ Resource
Returns the path of a resource, or nil if none is found See Controller.find_resource.
-
.http_s_url(action = nil) ⇒ Object
If the site supports SSL, returns the #https_url; otherwise, the #http_url.
-
.layout_path ⇒ String
Path to this controller’s layouts.
-
.route_path(action = nil) ⇒ String
The canonical URL path for this controller.
-
.template_path ⇒ String
Path to this controller’s templates.
-
.url(action = nil) ⇒ String
(also: route_url)
Returns the full URL for the Controller The Controller’s implementation returns the route_path.
Instance Method Summary collapse
-
#action_target? ⇒ bool
Returns true if this controller is the final target for the current action, that is, if it does not dispatch to any route.
-
#after(action = '', *arguments) ⇒ Object
This method can be implemented by Controllers, and will be called on the controller chain after the execute method.
-
#before(action = '', *arguments) ⇒ Object
This method can be implemented by Controllers, and will be called on the controller chain before the execute method.
-
#call_after(action = '', *arguments) ⇒ Object
Helper method, that calls and propagates #after.
-
#call_before(action = '', *arguments) ⇒ Object
Helper method, that calls and propagates #before.
-
#check_action(action, c) ⇒ bool
Checks if an action responds to given route conditions.
- #controller_action?(method) ⇒ bool
-
#done ⇒ void
Stops the execution of the controller chain.
-
#done=(val) ⇒ void
Sets the controller chain’s “done” state.
-
#done? ⇒ bool
True if the controller is done, and should not continue dispatching.
-
#execute(action = '', *arguments) ⇒ Object
The main controller’s execution method.
-
#get_action_method(action) ⇒ Array
Returns the method to call on the controller given an action, and the arguments that should be passed to it.
-
#get_scene(scene = nil) ⇒ Scene
Returns a new Scene instance for use in the controller.
-
#init ⇒ void
Override this for controller initialization.
-
#initialize(request, response, scene = nil) ⇒ Controller
constructor
Constructor.
- #inspect ⇒ String
-
#is_target? ⇒ bool
False if the target of the call is a widget, true otherwise.
-
#prepare_scene(scene) ⇒ Scene
Sets controller information on a scene.
-
#request_path ⇒ String
(also: #call_path)
The actual action path used to reach this Controller.
Methods included from Annotations
Methods included from Logger
add, check_request_level, close, close_all, datetime_format, datetime_format=, #debug, debug, debug?, #debug?, enquire_loggers, #error, error, #error?, error?, fatal, #fatal, fatal?, #fatal?, info, #info, info?, #info?, #log, log, method_missing, open, reopen, request_level, send_to_loggers, set_request_level, unknown, #unknown, warn, #warn, warn?, #warn?
Methods included from Dispatcher
#add_chain_item, #can_dispatch?, #dispatch, #dispatch_chain, #dispatch_next, #dispatcher_get_route, #do_dispatch, included, #route, #routes, #run_chain
Methods included from App::AppClass
Constructor Details
#initialize(request, response, scene = nil) ⇒ Controller
Constructor. Note: you can use the #init method for custom initialization, instead of overrideing this method
189 190 191 192 193 194 195 196 |
# File 'lib/spiderfw/controller/controller.rb', line 189 def initialize(request, response, scene=nil) @request = request @response = response @scene = scene || get_scene @dispatch_path = '' @is_target = true init end |
Instance Attribute Details
#dispatch_action ⇒ String
Returns Action used to reach this controller in the dispatch chain.
180 181 182 |
# File 'lib/spiderfw/controller/controller.rb', line 180 def dispatch_action @dispatch_action end |
#executed_method ⇒ Symbol (readonly)
Returns The method currently set to be executed, if any.
176 177 178 |
# File 'lib/spiderfw/controller/controller.rb', line 176 def executed_method @executed_method end |
#is_target ⇒ bool
Returns True if the controller is the target of the current action.
182 183 184 |
# File 'lib/spiderfw/controller/controller.rb', line 182 def is_target @is_target end |
#request ⇒ Spider::Request (readonly)
172 173 174 |
# File 'lib/spiderfw/controller/controller.rb', line 172 def request @request end |
#response ⇒ Spider::Response (readonly)
174 175 176 |
# File 'lib/spiderfw/controller/controller.rb', line 174 def response @response end |
#scene ⇒ Scene (readonly)
178 179 180 |
# File 'lib/spiderfw/controller/controller.rb', line 178 def scene @scene end |
Class Method Details
.before(conditions, method, params = {}) ⇒ void
This method returns an undefined value.
Defines a method that will be called before the controller’s before, if the action matches the given conditions. Example:
before(/^list_/, :before_lists)
will call the method before_lists if the action starts with ‘list_’
57 58 59 60 61 |
# File 'lib/spiderfw/controller/controller.rb', line 57 def before(conditions, method, params={}) @dispatch_methods ||= {} @dispatch_methods[:before] ||= [] @dispatch_methods[:before] << [conditions, method, params] end |
.before_methods ⇒ Array
Returns An array of methods defined with before.
78 79 80 |
# File 'lib/spiderfw/controller/controller.rb', line 78 def before_methods @dispatch_methods && @dispatch_methods[:before] ? @dispatch_methods[:before] : [] end |
.before_unless(condition, method, params = {}) ⇒ void
This method returns an undefined value.
Like before, but calls the method unless the conditions match
70 71 72 73 74 75 |
# File 'lib/spiderfw/controller/controller.rb', line 70 def before_unless(condition, method, params={}) @dispatch_methods ||= {} @dispatch_methods[:before] ||= [] params[:unless] = true @dispatch_methods[:before] << [condition, method, params] end |
.controller_action(method, params) ⇒ Object
98 99 100 101 102 103 |
# File 'lib/spiderfw/controller/controller.rb', line 98 def controller_action(method, params) @controller_actions ||= [] @controller_actions << method @controller_action_params ||= {} @controller_action_params[method] = params end |
.controller_action?(method) ⇒ bool
Returns true if the method is a controller action.
106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/spiderfw/controller/controller.rb', line 106 def controller_action?(method) return false unless self.method_defined?(method) return true if default_action && method == default_action.to_sym if @controller_actions res = @controller_actions.include?(method) if (!res) Spider.logger.info("Method #{method} is not a controller action for #{self}") end return res else return true end end |
.controller_actions(*methods) ⇒ Array
Registers a list of methods as controller actions, that is, methods that can be dispatched to.
This method is not usually called directly; using the __.action annotation, or one of the format annotations (__.html, __.xml, __.json, __.text), will make a method a controller action.
90 91 92 93 94 95 96 |
# File 'lib/spiderfw/controller/controller.rb', line 90 def controller_actions(*methods) if (methods.length > 0) @controller_actions ||= [] @controller_actions += methods end @controller_actions end |
.default_action ⇒ Object
30 31 32 |
# File 'lib/spiderfw/controller/controller.rb', line 30 def default_action 'index' end |
.find_resource(type, name, cur_path = nil) ⇒ Resource
Finds a resource in the context of the controller’s app See Spider.find_resource
126 127 128 |
# File 'lib/spiderfw/controller/controller.rb', line 126 def find_resource(type, name, cur_path=nil) Spider.find_resource(type, name, cur_path, self) end |
.find_resource_path(type, name, cur_path = nil) ⇒ Resource
Returns the path of a resource, or nil if none is found See find_resource
136 137 138 139 |
# File 'lib/spiderfw/controller/controller.rb', line 136 def find_resource_path(type, name, cur_path=nil) res = Spider.find_resource(type, name, cur_path, self) return res ? res.path : nil end |
.http_s_url(action = nil) ⇒ Object
If the site supports SSL, returns the #https_url; otherwise, the #http_url
255 256 257 |
# File 'lib/spiderfw/controller/controller.rb', line 255 def self.http_s_url(action=nil) (Spider.site.blank? ? "" : Spider.site.http_s_url) + route_path(action) end |
.layout_path ⇒ String
Returns Path to this controller’s layouts.
41 42 43 44 |
# File 'lib/spiderfw/controller/controller.rb', line 41 def layout_path return nil unless self.app return File.join(self.app.path, '/views') end |
.route_path(action = nil) ⇒ String
Returns The canonical URL path for this controller.
143 144 145 146 147 148 149 150 151 152 |
# File 'lib/spiderfw/controller/controller.rb', line 143 def route_path(action=nil) u = @default_route || '' u += "/#{action}" if action if @default_dispatcher && @default_dispatcher != self u = @default_dispatcher.route_path(u) elsif self.app u = self.app.route_path(u) end u end |
.template_path ⇒ String
Returns Path to this controller’s templates.
35 36 37 38 |
# File 'lib/spiderfw/controller/controller.rb', line 35 def template_path return nil unless self.app return File.join(self.app.path, '/views') end |
.url(action = nil) ⇒ String Also known as: route_url
Returns the full URL for the Controller The Controller’s implementation returns the route_path.
However, the HTTPMixin will override this method to return a full http url; other mixins can override the method in different ways.
161 162 163 |
# File 'lib/spiderfw/controller/controller.rb', line 161 def url(action=nil) route_path(action) end |
Instance Method Details
#action_target? ⇒ bool
Returns true if this controller is the final target for the current action, that is, if it does not dispatch to any route
244 245 246 247 |
# File 'lib/spiderfw/controller/controller.rb', line 244 def action_target? !@dispatch_next[@call_path] || @dispatch_next[@call_path].dest == self \ || @dispatch_next[@call_path].dest == self.class end |
#after(action = '', *arguments) ⇒ Object
This method can be implemented by Controllers, and will be called on the controller chain after the execute method.
If the webserver supports it, this method will be called after the response has been returned to the browser; so, it’s suitable for post processing. If you aren’t using a threaded web server, though, keep in mind that the process won’t be available to service other requests.
350 351 |
# File 'lib/spiderfw/controller/controller.rb', line 350 def after(action='', *arguments) end |
#before(action = '', *arguments) ⇒ Object
This method can be implemented by Controllers, and will be called on the controller chain before the execute method.
This method is usually reserved for preprocessing that does not output to the browser, to allow other controllers in chain to set response headers.
324 325 |
# File 'lib/spiderfw/controller/controller.rb', line 324 def before(action='', *arguments) end |
#call_after(action = '', *arguments) ⇒ Object
Helper method, that calls and propagates #after
330 331 332 333 334 335 336 337 338 339 |
# File 'lib/spiderfw/controller/controller.rb', line 330 def call_after(action='', *arguments) return if respond_to?(:serving_static?) && self.serving_static? after(action, *arguments) catch(:done) do d_next = dispatch_next(action) unless d_next && d_next.obj == self do_dispatch(:call_after, action, *arguments) end end end |
#call_before(action = '', *arguments) ⇒ Object
Helper method, that calls and propagates #before
303 304 305 306 307 308 309 310 311 312 313 314 |
# File 'lib/spiderfw/controller/controller.rb', line 303 def call_before(action='', *arguments) return if respond_to?(:serving_static?) && self.serving_static? @call_path = action before(action, *arguments) catch(:done) do #debug("#{self} before") d_next = dispatch_next(action) unless d_next && d_next.obj == self do_dispatch(:call_before, action, *arguments) end end end |
#check_action(action, c) ⇒ bool
Checks if an action responds to given route conditions. Is called by Dispatcher#do_dispatch. The default implementation calls Controller.check_action, which in turn is mixed in from Dispatcher::ClassMethods#check_action
380 381 382 |
# File 'lib/spiderfw/controller/controller.rb', line 380 def check_action(action, c) self.class.check_action(action, c) end |
#controller_action?(method) ⇒ bool
413 414 415 |
# File 'lib/spiderfw/controller/controller.rb', line 413 def controller_action?(method) self.class.controller_action?(method) end |
#done ⇒ void
This method returns an undefined value.
Stops the execution of the controller chain
360 361 362 363 |
# File 'lib/spiderfw/controller/controller.rb', line 360 def done self.done = true throw :done end |
#done=(val) ⇒ void
This method returns an undefined value.
Sets the controller chain’s “done” state
368 369 370 371 |
# File 'lib/spiderfw/controller/controller.rb', line 368 def done=(val) @__done = val @dispatch_previous.done = val if @dispatch_previous end |
#done? ⇒ bool
Returns True if the controller is done, and should not continue dispatching.
354 355 356 |
# File 'lib/spiderfw/controller/controller.rb', line 354 def done? @__done end |
#execute(action = '', *arguments) ⇒ Object
The main controller’s execution method. The Controller will dispatch to another controller if a route is set; otherwise, it will call the method that should be executed according to action.
This method can be overridden in subclasses, but remember to call super, or the dispatch chain will stop!
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 |
# File 'lib/spiderfw/controller/controller.rb', line 267 def execute(action='', *arguments) return if @__done debug("Controller #{self} executing #{action} with arguments #{arguments}") catch(:done) do if can_dispatch?(:execute, action) d_next = dispatch_next(action) #run_chain(:execute, action, *arguments) # shortcut route to self return do_dispatch(:execute, action) if d_next.dest != self arguments = d_next.params end if d_next && d_next.dest == self set_executed_method(d_next.action) end if @executed_method meth = self.method(@executed_method) args = arguments + @executed_method_arguments @current_action = action arity = meth.arity unless arity == -1 arity = (-arity + 1) if arity < 0 args = arity == 0 ? [] : args[0..(arity-1)] args = [nil] if meth.arity == 1 && args.empty? end Spider.logger.info("Executing: #{self.class.name}##{@executed_method}.#{@request.format}") spider_main_controller_send = true send(@executed_method, *args) else raise NotFound.new(action) end end end |
#get_action_method(action) ⇒ Array
Returns the method to call on the controller given an action, and the arguments that should be passed to it.
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
# File 'lib/spiderfw/controller/controller.rb', line 223 def get_action_method(action) method = nil additional_arguments = nil if (action =~ /^([^:]+)(:.+)$/) method = $1 elsif (action =~ /^([^\/]+)\/(.+)$/) # methods followed by a slash method = $1 additional_arguments = [$2] else method = action end method = method[0..-2] if !method.blank? && method[-1].chr == '/' method, rest = method.split('.', 2) if method method = self.class.default_action if !method || method.empty? return nil if method.empty? return [method.to_sym, additional_arguments] end |
#get_scene(scene = nil) ⇒ Scene
Returns a new Scene instance for use in the controller.
387 388 389 390 391 |
# File 'lib/spiderfw/controller/controller.rb', line 387 def get_scene(scene=nil) scene = Scene.new(scene) if scene.class == Hash scene ||= Scene.new return scene end |
#init ⇒ void
This method returns an undefined value.
Override this for controller initialization
200 201 |
# File 'lib/spiderfw/controller/controller.rb', line 200 def init end |
#inspect ⇒ String
204 205 206 |
# File 'lib/spiderfw/controller/controller.rb', line 204 def inspect self.class.to_s end |
#is_target? ⇒ bool
Returns false if the target of the call is a widget, true otherwise.
250 251 252 |
# File 'lib/spiderfw/controller/controller.rb', line 250 def is_target? @is_target end |
#prepare_scene(scene) ⇒ Scene
Sets controller information on a scene
396 397 398 399 400 401 402 403 404 405 406 407 408 409 |
# File 'lib/spiderfw/controller/controller.rb', line 396 def prepare_scene(scene) req_path = @request.path req_path += 'index' if !req_path.blank? && req_path[-1].chr == '/' scene.request = { :path => @request.path, :page_path => req_path } scene.controller = { :request_path => request_path, :class => self.class } scene.content = {} return scene end |
#request_path ⇒ String Also known as: call_path
Returns The actual action path used to reach this Controller.
209 210 211 212 213 214 215 216 |
# File 'lib/spiderfw/controller/controller.rb', line 209 def request_path act = @dispatch_action || '' if (@dispatch_previous) prev = @dispatch_previous.call_path act = prev+'/'+act unless prev.empty? end return ('/'+act).gsub(/\/+/, '/').sub(/\/$/, '') end |