Module: Tanuki::ControllerBehavior
- Extended by:
- ClassMethods
- Includes:
- Enumerable
- Included in:
- I18n, Tanuki_Controller
- Defined in:
- lib/tanuki/behavior/controller_behavior.rb
Overview
Tanuki::ControllerBehavior contains basic methods for a framework controller. In is included in the base controller class.
Defined Under Namespace
Modules: ClassMethods
Class Method Summary collapse
-
.dispatch(ctx, klass, request_path) ⇒ Object
Dispathes route chain in context
ctxonrequest_path, starting with controllerklass. -
.included(mod) ⇒ Object
Extends the including module with Tanuki::ControllerBehavior::ClassMethods.
Instance Method Summary collapse
-
#[](route, *args) ⇒ Object
Initializes and retrieves child controller on
route. -
#_ctx(ctx) ⇒ Object
Returns controller context.
-
#active? ⇒ Boolean
Returns
true, if controller is active. -
#child_class(route) ⇒ Object
Retrieves child controller class on
route. -
#configure ⇒ Object
Invoked when controller needs to be configured.
-
#current? ⇒ Boolean
Returns
true, if controller is current. -
#default_route ⇒ Object
If set, controller navigates to a given child route by default.
-
#each(&block) ⇒ Object
Calls
blockonce for each visible child controller on static or dynamic routes, passing it as a parameter. -
#ensure_configured! ⇒ Object
Invoked when controller configuration needs to be ensured.
-
#forward_link ⇒ Object
Returns the link to the current controller, switching the active controller on the respective path level to
self. -
#initialize(ctx, logical_parent, route_part, model = nil) ⇒ Object
Creates new controller with context
ctx,logical_parentcontroller,route_partdefinitions and amodel. -
#initialize_route(*args) ⇒ Object
Invoked with route
argswhen current route is initialized. -
#length ⇒ Object
(also: #size)
Returns the number of visible child controllers on static and dynamic routes.
-
#process_child_context(ctx, route) ⇒ Object
Invoked when child controller context needs to be processed before initializing.
-
#to_s ⇒ Object
Returns controller string representation.
-
#visual_parent ⇒ Object
Invoked when visual parent needs to be determined.
Methods included from ClassMethods
arg_defs, escape, extended, extract_args, grow_link, has_arg
Class Method Details
.dispatch(ctx, klass, request_path) ⇒ Object
Dispathes route chain in context ctx on request_path, starting with controller klass.
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 |
# File 'lib/tanuki/behavior/controller_behavior.rb', line 273 def dispatch(ctx, klass, request_path) route_parts = parse_path(request_path) curr = root_ctrl = klass.new(ctx, nil, nil, true) route_parts.each do |route_part| curr.instance_variable_set :@_active, true nxt = curr[route_part[:route], *route_part[:args]] curr.logical_child = nxt curr = nxt end while route_part = curr.default_route if route_part[:redirect] klass = curr.child_class(route_part) return {:type => :redirect, :location => grow_link(curr, route_part, klass.arg_defs)} end curr.instance_variable_set :@_active, true nxt = curr[route_part[:route], *route_part[:args]] curr.logical_child = nxt curr = nxt end curr.instance_variable_set :@_active, true curr.instance_variable_set :@_current, true type = (curr.is_a? ctx.missing_page) ? :missing_page : :page prev = curr while curr = prev.visual_parent curr.visual_child = prev prev = curr end {:type => type, :controller => prev} end |
.included(mod) ⇒ Object
Extends the including module with Tanuki::ControllerBehavior::ClassMethods.
304 305 306 |
# File 'lib/tanuki/behavior/controller_behavior.rb', line 304 def included(mod) mod.extend ClassMethods end |
Instance Method Details
#[](route, *args) ⇒ Object
Initializes and retrieves child controller on route. Searches static, dynamic, and ghost routes (in that order).
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/tanuki/behavior/controller_behavior.rb', line 42 def [](route, *args) byname = (args.length == 1 and args[0].is_a? Hash) ensure_configured! key = [route, args.dup] if cached = @_cache[key] # Return form cache return cached elsif child_def = @_child_defs[route] # Search static routes klass = child_def[:class] args = klass.extract_args(args[0]) if byname child = klass.new(process_child_context(@_ctx, route), self, {:route => route, :args => args}, child_def[:model]) else # Search dynamic routes found = false s = route.to_s @_child_collection_defs.each do |collection_def| if md = collection_def[:parse].match(s) a_route = md['route'].to_sym child_def = collection_def[:fetcher].fetch(a_route, collection_def[:format]) if child_def klass = child_def[:class] args = klass.extract_args(args[0]) if byname = klass.extract_args(md) args.each_index {|i| [i] = args[i] if args[i] } child = klass.new(process_child_context(@_ctx, a_route), self, {:route => a_route, :args => }, child_def[:model]) found = true break child end end end # If still not found, search ghost routes child = missing_route(route, *args) unless found end @_cache[key] = child # Thread safe (possible overwrite, but within consistent state) end |
#_ctx(ctx) ⇒ Object
Returns controller context. Used internally by templates.
37 38 39 |
# File 'lib/tanuki/behavior/controller_behavior.rb', line 37 def _ctx(ctx) @_ctx end |
#active? ⇒ Boolean
Returns true, if controller is active.
81 82 83 |
# File 'lib/tanuki/behavior/controller_behavior.rb', line 81 def active? @_active end |
#child_class(route) ⇒ Object
Retrieves child controller class on route. Searches static, dynamic, and ghost routes (in that order).
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/tanuki/behavior/controller_behavior.rb', line 86 def child_class(route) ensure_configured! args = [] key = [route, args] if cached = @_cache[key] # Return from cache return cached.class elsif child_def = @_child_defs[route] # Return from static routes return child_def[:class] else # Search dynamic routes s = route.to_s @_child_collection_defs.each do |collection_def| if md = collection_def[:parse].match(s) a_route = md['route'].to_sym child_def = collection_def[:fetcher].fetch(a_route, collection_def[:format]) return child_def[:class] if child_def end end # If still not found, search ghost routes return (@_cache[key] = missing_route(route, *args)).class end end |
#configure ⇒ Object
Invoked when controller needs to be configured.
112 113 |
# File 'lib/tanuki/behavior/controller_behavior.rb', line 112 def configure end |
#current? ⇒ Boolean
Returns true, if controller is current.
116 117 118 |
# File 'lib/tanuki/behavior/controller_behavior.rb', line 116 def current? @_current end |
#default_route ⇒ Object
If set, controller navigates to a given child route by default. Returned object should be either nil (don’t navigate), or a Hash with keys:
-
:routeis theSymbolfor the route -
:argscontain route argumentsHash -
:redirectmakes a 302 redirect to this route, if true (optional)
125 126 127 |
# File 'lib/tanuki/behavior/controller_behavior.rb', line 125 def default_route nil end |
#each(&block) ⇒ Object
Calls block once for each visible child controller on static or dynamic routes, passing it as a parameter.
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/tanuki/behavior/controller_behavior.rb', line 130 def each(&block) return Enumerator.new(self) unless block_given? ensure_configured! @_child_defs.each_pair do |route, child| if route.is_a? Regexp cd = @_child_collection_defs[child] cd[:fetcher].fetch_all(cd[:format]) do |child_def| key = [child_def[:route], []] unless child = @_cache[key] child = child_def[:class].new(process_child_context(@_ctx, route), self, {:route => child_def[:route], :args => {}}, child_def[:model]) @_cache[key] = child end block.call child end else yield self[route] unless child[:hidden] end end self end |
#ensure_configured! ⇒ Object
Invoked when controller configuration needs to be ensured.
153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/tanuki/behavior/controller_behavior.rb', line 153 def ensure_configured! unless @_configured @_child_defs = {} @_child_collection_defs = [] @_cache={} @_length = 0 configure @_configured = true end nil end |
#forward_link ⇒ Object
Returns the link to the current controller, switching the active controller on the respective path level to self.
166 167 168 169 170 171 |
# File 'lib/tanuki/behavior/controller_behavior.rb', line 166 def forward_link uri_parts = @_ctx.env['PATH_INFO'].split(/(?<!\$)\//) link_parts = link.split(/(?<!\$)\//) link_parts.each_index {|i| uri_parts[i] = link_parts[i] } uri_parts.join('/') << ((qs = @_ctx.env['QUERY_STRING']).empty? ? '' : "?#{qs}") end |
#initialize(ctx, logical_parent, route_part, model = nil) ⇒ Object
Creates new controller with context ctx, logical_parent controller, route_part definitions and a model.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/tanuki/behavior/controller_behavior.rb', line 13 def initialize(ctx, logical_parent, route_part, model=nil) @_configured = false @_ctx = ctx @_model = model @_args = {} if @_logical_parent = logical_parent @_route = route_part[:route] self.class.arg_defs.each_pair do |arg_name, arg_def| route_part[:args][arg_def[:index]] = @_args[arg_name] = arg_def[:arg].to_value(route_part[:args][arg_def[:index]]) end @_link = self.class.grow_link(@_logical_parent, {:route => @_route, :args => @_args}, self.class.arg_defs) initialize_route(*route_part[:args]) else @_link = '/' @_route = nil initialize_route end end |
#initialize_route(*args) ⇒ Object
Invoked with route args when current route is initialized.
33 34 |
# File 'lib/tanuki/behavior/controller_behavior.rb', line 33 def initialize_route(*args) end |
#length ⇒ Object Also known as: size
Returns the number of visible child controllers on static and dynamic routes.
174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/tanuki/behavior/controller_behavior.rb', line 174 def length if @_child_collection_defs.length > 0 if @_length_is_valid @_length else @_child_collection_defs.each {|cd| @_length += cd[:fetcher].length } @_length_is_valid = true end else @_length end end |
#process_child_context(ctx, route) ⇒ Object
Invoked when child controller context needs to be processed before initializing.
188 189 190 |
# File 'lib/tanuki/behavior/controller_behavior.rb', line 188 def process_child_context(ctx, route) ctx end |
#to_s ⇒ Object
Returns controller string representation. Defaults to route name.
195 196 197 |
# File 'lib/tanuki/behavior/controller_behavior.rb', line 195 def to_s @_route.to_s end |
#visual_parent ⇒ Object
Invoked when visual parent needs to be determined. Defaults to logical parent.
200 201 202 |
# File 'lib/tanuki/behavior/controller_behavior.rb', line 200 def visual_parent @_logical_parent end |