Class: Merb::AbstractController
- Includes:
- InlineTemplates, RenderMixin
- Defined in:
- lib/merb-core/controller/abstract_controller.rb
Direct Known Subclasses
Constant Summary collapse
- FILTER_OPTIONS =
[:only, :exclude, :if, :unless, :with]
Constants included from ControllerExceptions
ControllerExceptions::STATUS_CODES
Instance Attribute Summary collapse
-
#_benchmarks ⇒ Object
:api: plugin.
-
#_thrown_content ⇒ Object
:api: private.
-
#action_name ⇒ Object
:api: plugin.
-
#body ⇒ Object
:api: plugin.
-
#content_type ⇒ Object
Stub so content-type support in RenderMixin doesn’t throw errors :api: private.
Class Method Summary collapse
-
._reset_template_roots ⇒ Object
Reset the template root based on the @_template_root ivar.
-
._template_root=(root) ⇒ Object
Resets the template roots to the template root passed in.
-
._template_roots ⇒ Object
Returns roots<Array>:: Template roots as pairs of template root path and template location method.
-
._template_roots=(roots) ⇒ Object
Parameters roots<Array>:: Template roots as pairs of template root path and template location method.
-
.after(filter = nil, opts = {}, &block) ⇒ Object
- Adds a filter to the after filter chain ==== Parameters filter<Symbol, Proc>
-
The filter to add.
-
.before(filter = nil, opts = {}, &block) ⇒ Object
Adds a filter to the before filter chain.
-
.controller_name ⇒ Object
Returns String:: The controller name in path form, e.g.
-
.inherited(klass) ⇒ Object
Parameters klass<Merb::AbstractController>:: The controller that is being inherited from Merb::AbstractController.
-
.skip_after(filter) ⇒ Object
Removes a filter from the after filter chain.
-
.skip_before(filter) ⇒ Object
Removes a filter from the before filter chain.
-
.subclasses_list ⇒ Object
Returns the list of classes that have specifically subclassed AbstractController.
Instance Method Summary collapse
-
#_absolute_template_location(template, type) ⇒ Object
The location to look for a template - override this method for particular behaviour.
-
#_call_action(action) ⇒ Object
This method exists to provide an overridable hook for ActionArgs.
-
#_call_filter_for_action?(rule, action_name) ⇒ Boolean
Determine whether the filter should be called for the current action using :only and :exclude.
-
#_call_filters(filter_set) ⇒ Object
Calls a filter chain.
-
#_dispatch(action) ⇒ Object
This will dispatch the request, calling internal before/after dispatch callbacks.
-
#_evaluate_condition(condition) ⇒ Object
Evaluates a filter condition (:if or :unless).
-
#_filter_condition_met?(rule) ⇒ Boolean
Determines whether the filter should be run based on the conditions passed (:if and :unless).
-
#_template_location(context, type, controller) ⇒ Object
This is called after the controller is instantiated to figure out where to look for templates under the _template_root.
-
#absolute_url(*args) ⇒ Object
Returns the absolute url including the passed protocol and host.
-
#capture(*args, &block) ⇒ Object
Calls the capture method for the selected template engine.
-
#concat(str, binding) ⇒ Object
Calls the concatenate method for the selected template engine.
-
#controller_name ⇒ Object
Returns String:: The controller name in path form, e.g.
-
#initialize(*args) ⇒ AbstractController
constructor
- This will initialize the controller, it is designed to be overridden in subclasses (like MerbController) ==== Parameters *args
-
The args are ignored in this class, but we need this so that subclassed initializes can have parameters.
-
#resource(*args) ⇒ Object
Generates a URL for a single or nested resource.
-
#url(name, *args) ⇒ Object
(also: #relative_url)
There are three possible ways to use this method.
Methods included from RenderMixin
#_get_layout, #_handle_options!, #_template_for, #_template_method_for, #append_content, #catch_content, #clear_content, #display, included, #partial, #render, #throw_content, #thrown_content?
Constructor Details
#initialize(*args) ⇒ AbstractController
This will initialize the controller, it is designed to be overridden in subclasses (like MerbController)
Parameters
- *args
-
The args are ignored in this class, but we need this so that subclassed initializes can have parameters
:api: private
256 257 258 259 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 256 def initialize(*args) @_benchmarks = {} @_caught_content = {} end |
Instance Attribute Details
#_benchmarks ⇒ Object
:api: plugin
110 111 112 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 110 def _benchmarks @_benchmarks end |
#_thrown_content ⇒ Object
:api: private
112 113 114 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 112 def _thrown_content @_thrown_content end |
#action_name ⇒ Object
:api: plugin
110 111 112 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 110 def action_name @action_name end |
#body ⇒ Object
:api: plugin
110 111 112 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 110 def body @body end |
#content_type ⇒ Object
Stub so content-type support in RenderMixin doesn’t throw errors :api: private
116 117 118 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 116 def content_type @content_type end |
Class Method Details
._reset_template_roots ⇒ Object
Reset the template root based on the @_template_root ivar.
:api: private
203 204 205 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 203 def self._reset_template_roots self.template_roots = [[self._template_root, :_template_location]] end |
._template_root=(root) ⇒ Object
Resets the template roots to the template root passed in.
Parameters
- root<~to_s>
-
The new path to set the template root to.
:api: public
195 196 197 198 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 195 def self._template_root=(root) @_template_root = root _reset_template_roots end |
._template_roots ⇒ Object
Returns
- roots<Array>
-
Template roots as pairs of template root path and template location method.
:api: plugin
213 214 215 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 213 def self._template_roots self.template_roots || _reset_template_roots end |
._template_roots=(roots) ⇒ Object
Parameters
- roots<Array>
-
Template roots as pairs of template root path and template location method.
:api: plugin
223 224 225 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 223 def self._template_roots=(roots) self.template_roots = roots end |
.after(filter = nil, opts = {}, &block) ⇒ Object
Adds a filter to the after filter chain
Parameters
- filter<Symbol, Proc>
-
The filter to add. Defaults to nil.
- opts<Hash>
-
Filter options (see class documentation under
Filter Options
). - &block
-
A block to use as a filter if filter is nil.
Notes
If the filter already exists, its options will be replaced with opts.;
:api: public
440 441 442 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 440 def self.after(filter = nil, opts = {}, &block) add_filter(self._after_filters, filter || block, opts) end |
.before(filter = nil, opts = {}, &block) ⇒ Object
Adds a filter to the before filter chain.
Parameters
- filter<Symbol, Proc>
-
The filter to add. Defaults to nil.
- opts<Hash>
-
Filter options (see class documentation under
Filter Options
). - &block
-
A block to use as a filter if filter is nil.
Notes
If the filter already exists, its options will be replaced with opts.
:api: public
456 457 458 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 456 def self.before(filter = nil, opts = {}, &block) add_filter(self._before_filters, filter || block, opts) end |
.controller_name ⇒ Object
Returns
- String
-
The controller name in path form, e.g. “admin/items”.
:api: public
132 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 132 def self.controller_name() @controller_name ||= self.name.to_const_path end |
.inherited(klass) ⇒ Object
Parameters
- klass<Merb::AbstractController>
-
The controller that is being inherited from Merb::AbstractController
:api: private
241 242 243 244 245 246 247 248 249 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 241 def self.inherited(klass) _abstract_subclasses << klass.to_s helper_module_name = klass.to_s =~ /^(#|Merb::)/ ? "#{klass}Helper" : "Merb::#{klass}Helper" Object.make_module helper_module_name klass.class_eval <<-HERE include Object.full_const_get("#{helper_module_name}") rescue nil HERE super end |
.skip_after(filter) ⇒ Object
Removes a filter from the after filter chain. This removes the filter from the filter chain for the whole controller and does not take any options.
Parameters
- filter<Symbol, String>
-
A filter name to skip.
:api: public
468 469 470 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 468 def self.skip_after(filter) skip_filter(self._after_filters, filter) end |
.skip_before(filter) ⇒ Object
Removes a filter from the before filter chain. This removes the filter from the filter chain for the whole controller and does not take any options.
Parameters
- filter<Symbol, String>
-
A filter name to skip.
:api: public
480 481 482 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 480 def self.skip_before(filter) skip_filter(self._before_filters , filter) end |
.subclasses_list ⇒ Object
Returns the list of classes that have specifically subclassed AbstractController.
Does not include all decendents.
Returns
- Set
-
The subclasses.
:api: private
234 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 234 def self.subclasses_list() _abstract_subclasses end |
Instance Method Details
#_absolute_template_location(template, type) ⇒ Object
The location to look for a template - override this method for particular behaviour.
Parameters
- template<String>
-
The absolute path to a template - without template extension.
- type<~to_s>
-
The mime-type of the template that will be rendered. Defaults to being called with nil.
:api: public
184 185 186 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 184 def _absolute_template_location(template, type) template end |
#_call_action(action) ⇒ Object
This method exists to provide an overridable hook for ActionArgs. It uses #send to call the action method.
Parameters
- action<~to_s>
-
the action method to dispatch to
:api: plugin
314 315 316 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 314 def _call_action(action) send(action) end |
#_call_filter_for_action?(rule, action_name) ⇒ Boolean
Determine whether the filter should be called for the current action using :only and :exclude.
Parameters
- rule<Hash>
-
Rules for the filter (see below).
- action_name<~to_s>
-
The name of the action to be called.
Options (rule)
- :only<Array>
-
Optional list of actions to fire. If given, action_name must be a part of it for this function to return true.
- :exclude<Array>
-
Optional list of actions not to fire. If given, action_name must not be a part of it for this function to return true.
Returns
- Boolean
-
True if the action should be called.
:api: private
373 374 375 376 377 378 379 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 373 def _call_filter_for_action?(rule, action_name) # Both: # * no :only or the current action is in the :only list # * no :exclude or the current action is not in the :exclude list (!rule.key?(:only) || rule[:only].include?(action_name)) && (!rule.key?(:exclude) || !rule[:exclude].include?(action_name)) end |
#_call_filters(filter_set) ⇒ Object
Calls a filter chain.
Parameters
- filter_set<Array>
-
A set of filters in the form [[:filter, rule], [:filter, rule]]
Returns
- Symbol
-
:filter_chain_completed.
Notes
Filter rules can be Symbols, Strings, or Procs.
- Symbols or Strings
-
Call the method represented by the
Symbol
orString
. - Procs
-
Execute the
Proc
, in the context of the controller (self will be the controller)
:api: private
337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 337 def _call_filters(filter_set) (filter_set || []).each do |filter, rule| if _call_filter_for_action?(rule, action_name) && _filter_condition_met?(rule) case filter when Symbol, String if rule.key?(:with) args = rule[:with] send(filter, *args) else send(filter) end when Proc then self.instance_eval(&filter) end end end return :filter_chain_completed end |
#_dispatch(action) ⇒ Object
This will dispatch the request, calling internal before/after dispatch callbacks.
If the return value of _call_filters is not :filter_chain_completed the action is not called, and the return from the filters is used instead.
Parameters
- action<~to_s>
-
The action to dispatch to. This will be #send’ed in _call_action. Defaults to :to_s.
Returns
- <~to_s>
-
Returns the string that was returned from the action.
Raises
- ArgumentError
-
Invalid result caught from before filters.
:api: plugin
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 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 277 def _dispatch(action) self.action_name = action self._before_dispatch_callbacks.each { |cb| cb.call(self) } caught = catch(:halt) do start = Time.now result = _call_filters(_before_filters) @_benchmarks[:before_filters_time] = Time.now - start if _before_filters result end @body = case caught when :filter_chain_completed then _call_action(action_name) when String then caught # return *something* if you throw halt with nothing when nil then "<html><body><h1>Filter Chain Halted!</h1></body></html>" when Symbol then __send__(caught) when Proc then self.instance_eval(&caught) else raise ArgumentError, "Threw :halt, #{caught}. Expected String, nil, Symbol, Proc." end start = Time.now _call_filters(_after_filters) @_benchmarks[:after_filters_time] = Time.now - start if _after_filters self._after_dispatch_callbacks.each { |cb| cb.call(self) } @body end |
#_evaluate_condition(condition) ⇒ Object
Evaluates a filter condition (:if or :unless)
Parameters
- condition<Symbol, Proc>
-
The condition to evaluate.
Raises
- ArgumentError
-
condition not a Symbol or Proc.
Returns
- Boolean
-
True if the condition is met.
Alternatives
If condition is a symbol, it will be send’ed. If it is a Proc it will be called directly with self as an argument.
:api: private
419 420 421 422 423 424 425 426 427 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 419 def _evaluate_condition(condition) case condition when Symbol then self.send(condition) when Proc then self.instance_eval(&condition) else raise ArgumentError, 'Filter condtions need to be either a Symbol or a Proc' end end |
#_filter_condition_met?(rule) ⇒ Boolean
Determines whether the filter should be run based on the conditions passed (:if and :unless)
Parameters
- rule<Hash>
-
Rules for the filter (see below).
Options (rule)
- :if<Array>
-
Optional conditions that must be met for the filter to fire.
- :unless<Array>
-
Optional conditions that must not be met for the filter to fire.
Returns
- Boolean
-
True if the conditions are met.
:api: private
395 396 397 398 399 400 401 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 395 def _filter_condition_met?(rule) # Both: # * no :if or the if condition evaluates to true # * no :unless or the unless condition evaluates to false (!rule.key?(:if) || _evaluate_condition(rule[:if])) && (!rule.key?(:unless) || ! _evaluate_condition(rule[:unless])) end |
#_template_location(context, type, controller) ⇒ Object
This is called after the controller is instantiated to figure out where to look for templates under the _template_root. Override this to define a new structure for your app.
Parameters
- context<~to_s>
-
The controller context (the action or template name).
- type<~to_s>
-
The content type. Could be nil.
- controller<~to_s>
-
The name of the controller. Defaults to being called with the controller_name. Set t
Returns
- String
-
Indicating where to look for the template for the current controller, context, and content-type.
Notes
The type is irrelevant for controller-types that don’t support content-type negotiation, so we default to not include it in the superclass.
Examples
def _template_location
"#{params[:controller]}.#{params[:action]}.#{content_type}"
end
This would look for templates at controller.action.mime.type instead of controller/action.mime.type
:api: public
171 172 173 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 171 def _template_location(context, type, controller) controller ? "#{controller}/#{context}" : context end |
#absolute_url(*args) ⇒ Object
Returns the absolute url including the passed protocol and host.
This uses the same arguments as the url method, with added requirements of protocol and host options.
:api: public
551 552 553 554 555 556 557 558 559 560 561 562 563 564 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 551 def absolute_url(*args) # FIXME: arrgh, why request.protocol returns http://? # :// is not part of protocol name = (args) || {} protocol = .delete(:protocol) host = .delete(:host) raise ArgumentError, "The :protocol option must be specified" unless protocol raise ArgumentError, "The :host option must be specified" unless host args << protocol + "://" + host + url(*args) end |
#capture(*args, &block) ⇒ Object
Calls the capture method for the selected template engine.
Parameters
- *args
-
Arguments to pass to the block.
- &block
-
The block to call.
Returns
- String
-
The output of a template block or the return value of a non-template block converted to a string.
:api: public
610 611 612 613 614 615 616 617 618 619 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 610 def capture(*args, &block) ret = nil captured = send("capture_#{@_engine}", *args) do |*args| ret = yield *args end # return captured value only if it is not empty captured.empty? ? ret.to_s : captured end |
#concat(str, binding) ⇒ Object
Calls the concatenate method for the selected template engine.
Parameters
- str<String>
-
The string to concatenate to the buffer.
- binding<Binding>
-
The binding to use for the buffer.
:api: public
628 629 630 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 628 def concat(str, binding) send("concat_#{@_engine}", str, binding) end |
#controller_name ⇒ Object
Returns
- String
-
The controller name in path form, e.g. “admin/items”.
:api: public
138 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 138 def controller_name() self.class.controller_name end |
#resource(*args) ⇒ Object
Generates a URL for a single or nested resource.
Parameters
- resources<Symbol,Object>
-
The resources for which the URL
should be generated. These resources should be specified
in the router.rb file using #resources and #resource.
- options<Hash>
-
Any extra parameters that are needed to
generate the URL.
Returns
- String
-
The generated URL.
Examples
Merb::Router.prepare do
resources :users do
resources :comments
end
end
resource(:users) # => /users resource(@user) # => /users/10 resource(@user, :comments) # => /users/10/comments resource(@user, @comment) # => /users/10/comments/15 resource(:users, :new) # => /users/new resource(:@user, :edit) # => /users/10/edit
:api: public
595 596 597 598 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 595 def resource(*args) args << {} Merb::Router.resource(*args) end |
#url(name, *args) ⇒ Object Also known as: relative_url
There are three possible ways to use this method. First, if you have a named route, you can specify the route as the first parameter as a symbol and any paramters in a hash. Second, you can generate the default route by just passing the params hash, just passing the params hash. Finally, you can use the anonymous parameters. This allows you to specify the parameters to a named route in the order they appear in the router.
Parameters(Named Route)
- name<Symbol>
-
The name of the route.
- args<Hash>
-
Parameters for the route generation.
Parameters(Default Route)
- args<Hash>
-
Parameters for the route generation. This route will use the default route.
Parameters(Anonymous Parameters)
- name<Symbol>
-
The name of the route.
- args<Array>
-
An array of anonymous parameters to generate the route with. These parameters are assigned to the route parameters in the order that they are passed.
Returns
- String
-
The generated URL.
Examples
Named Route
Merb::Router.prepare do
match("/articles/:title").to(:controller => :articles, :action => :show).name("articles")
end
url(:articles, :title => “new_article”)
Default Route
Merb::Router.prepare do
default_routes
end
url(:controller => “articles”, :action => “new”)
Anonymous Paramters
Merb::Router.prepare do
match("/articles/:year/:month/:title").to(:controller => :articles, :action => :show).name("articles")
end
url(:articles, 2008, 10, “test_article”)
:api: public
538 539 540 541 |
# File 'lib/merb-core/controller/abstract_controller.rb', line 538 def url(name, *args) args << {} Merb::Router.url(name, *args) end |