merb-core 0.9.8 → 0.9.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CONTRIBUTORS +33 -0
- data/README +7 -3
- data/Rakefile +3 -3
- data/lib/merb-core.rb +165 -94
- data/lib/merb-core/bootloader.rb +469 -100
- data/lib/merb-core/config.rb +79 -3
- data/lib/merb-core/constants.rb +24 -2
- data/lib/merb-core/controller/abstract_controller.rb +172 -67
- data/lib/merb-core/controller/exceptions.rb +50 -6
- data/lib/merb-core/controller/merb_controller.rb +215 -108
- data/lib/merb-core/controller/mime.rb +36 -12
- data/lib/merb-core/controller/mixins/authentication.rb +52 -7
- data/lib/merb-core/controller/mixins/conditional_get.rb +14 -0
- data/lib/merb-core/controller/mixins/controller.rb +90 -58
- data/lib/merb-core/controller/mixins/render.rb +34 -10
- data/lib/merb-core/controller/mixins/responder.rb +40 -16
- data/lib/merb-core/controller/template.rb +37 -16
- data/lib/merb-core/core_ext/hash.rb +9 -0
- data/lib/merb-core/core_ext/kernel.rb +92 -41
- data/lib/merb-core/dispatch/dispatcher.rb +29 -45
- data/lib/merb-core/dispatch/request.rb +186 -82
- data/lib/merb-core/dispatch/router.rb +141 -53
- data/lib/merb-core/dispatch/router/behavior.rb +296 -139
- data/lib/merb-core/dispatch/router/resources.rb +51 -19
- data/lib/merb-core/dispatch/router/route.rb +76 -23
- data/lib/merb-core/dispatch/session.rb +80 -36
- data/lib/merb-core/dispatch/session/container.rb +31 -15
- data/lib/merb-core/dispatch/session/cookie.rb +51 -22
- data/lib/merb-core/dispatch/session/memcached.rb +10 -6
- data/lib/merb-core/dispatch/session/memory.rb +17 -5
- data/lib/merb-core/dispatch/session/store_container.rb +21 -9
- data/lib/merb-core/dispatch/worker.rb +16 -2
- data/lib/merb-core/gem_ext/erubis.rb +4 -0
- data/lib/merb-core/plugins.rb +13 -0
- data/lib/merb-core/rack.rb +1 -0
- data/lib/merb-core/rack/adapter.rb +1 -0
- data/lib/merb-core/rack/adapter/abstract.rb +95 -17
- data/lib/merb-core/rack/adapter/irb.rb +50 -5
- data/lib/merb-core/rack/application.rb +27 -5
- data/lib/merb-core/rack/handler/mongrel.rb +6 -6
- data/lib/merb-core/rack/helpers.rb +33 -0
- data/lib/merb-core/rack/middleware/conditional_get.rb +1 -1
- data/lib/merb-core/rack/middleware/path_prefix.rb +3 -3
- data/lib/merb-core/rack/middleware/static.rb +11 -7
- data/lib/merb-core/server.rb +134 -69
- data/lib/merb-core/tasks/gem_management.rb +153 -80
- data/lib/merb-core/tasks/merb_rake_helper.rb +12 -4
- data/lib/merb-core/tasks/stats.rake +1 -1
- data/lib/merb-core/test/helpers/mock_request_helper.rb +29 -22
- data/lib/merb-core/test/helpers/request_helper.rb +1 -1
- data/lib/merb-core/test/helpers/route_helper.rb +50 -4
- data/lib/merb-core/test/matchers/request_matchers.rb +2 -36
- data/lib/merb-core/test/matchers/view_matchers.rb +32 -22
- data/lib/merb-core/test/run_specs.rb +6 -5
- data/lib/merb-core/test/test_ext/rspec.rb +6 -19
- data/lib/merb-core/version.rb +1 -1
- metadata +5 -4
@@ -6,19 +6,19 @@ require 'merb-core/dispatch/router/route'
|
|
6
6
|
module Merb
|
7
7
|
# Router stores route definitions and finds the first
|
8
8
|
# route that matches the incoming request URL.
|
9
|
-
#
|
9
|
+
#
|
10
10
|
# Then information from route is used by dispatcher to
|
11
11
|
# call action on the controller.
|
12
|
-
#
|
12
|
+
#
|
13
13
|
# ==== Routes compilation.
|
14
|
-
#
|
14
|
+
#
|
15
15
|
# The most interesting method of Router (and heart of
|
16
16
|
# route matching machinery) is match method generated
|
17
17
|
# on the fly from routes definitions. It is called routes
|
18
18
|
# compilation. Generated match method body contains
|
19
19
|
# one if/elsif statement that picks the first matching route
|
20
20
|
# definition and sets values to named parameters of the route.
|
21
|
-
#
|
21
|
+
#
|
22
22
|
# Compilation is synchronized by mutex.
|
23
23
|
class Router
|
24
24
|
@routes = []
|
@@ -26,14 +26,14 @@ module Merb
|
|
26
26
|
@resource_routes = {}
|
27
27
|
@compiler_mutex = Mutex.new
|
28
28
|
@root_behavior = Behavior.new.defaults(:action => "index")
|
29
|
-
|
29
|
+
|
30
30
|
# Raised when route lookup fails.
|
31
31
|
class RouteNotFound < StandardError; end;
|
32
32
|
# Raised when parameters given to generation
|
33
33
|
# method do not match route parameters.
|
34
34
|
class GenerationError < StandardError; end;
|
35
35
|
class NotCompiledError < StandardError; end;
|
36
|
-
|
36
|
+
|
37
37
|
class << self
|
38
38
|
# @private
|
39
39
|
attr_accessor :routes, :named_routes, :resource_routes, :root_behavior
|
@@ -41,19 +41,20 @@ module Merb
|
|
41
41
|
# Creates a route building context and evaluates the block in it. A
|
42
42
|
# copy of +root_behavior+ (and instance of Behavior) is copied as
|
43
43
|
# the context.
|
44
|
-
#
|
44
|
+
#
|
45
45
|
# ==== Parameters
|
46
46
|
# first<Array>::
|
47
47
|
# An array containing routes that should be prepended to the routes
|
48
48
|
# defined in the block.
|
49
|
-
#
|
50
49
|
# last<Array>::
|
51
50
|
# An array containing routes that should be appended to the routes
|
52
51
|
# defined in the block.
|
53
|
-
#
|
52
|
+
#
|
54
53
|
# ==== Returns
|
55
54
|
# Merb::Router::
|
56
55
|
# Returns self to allow chaining of methods.
|
56
|
+
#
|
57
|
+
# @api public
|
57
58
|
def prepare(first = [], last = [], &block)
|
58
59
|
@routes = []
|
59
60
|
root_behavior._with_proxy(&block)
|
@@ -63,17 +64,23 @@ module Merb
|
|
63
64
|
end
|
64
65
|
|
65
66
|
# Appends route in the block to routing table.
|
67
|
+
#
|
68
|
+
# @api public
|
66
69
|
def append(&block)
|
67
70
|
prepare(routes, [], &block)
|
68
71
|
end
|
69
|
-
|
72
|
+
|
70
73
|
# Prepends routes in the block to routing table.
|
74
|
+
#
|
75
|
+
# @api public
|
71
76
|
def prepend(&block)
|
72
77
|
prepare([], routes, &block)
|
73
78
|
end
|
74
79
|
|
75
80
|
# Clears the routing table. Route generation and request matching
|
76
81
|
# won't work anymore until a new routing table is built.
|
82
|
+
#
|
83
|
+
# @api private
|
77
84
|
def reset!
|
78
85
|
class << self
|
79
86
|
alias_method :match, :match_before_compilation
|
@@ -84,18 +91,16 @@ module Merb
|
|
84
91
|
# Finds route matching URI of the request and returns a tuple of
|
85
92
|
# [route index, route params]. This method is called by the
|
86
93
|
# dispatcher and isn't as useful in applications.
|
87
|
-
#
|
94
|
+
#
|
88
95
|
# ==== Parameters
|
89
96
|
# request<Merb::Request>:: request to match.
|
90
|
-
#
|
97
|
+
#
|
91
98
|
# ==== Returns
|
92
|
-
#
|
93
|
-
# Two-tuple: route index and route parameters. Route
|
94
|
-
#
|
95
|
-
#
|
96
|
-
#
|
97
|
-
# ---
|
98
|
-
# @private
|
99
|
+
# Array[Integer, Hash]::
|
100
|
+
# Two-tuple: route index and route parameters. Route parameters
|
101
|
+
# are :controller, :action and all the named segments of the route.
|
102
|
+
#
|
103
|
+
# @api private
|
99
104
|
def route_for(request) #:nodoc:
|
100
105
|
index, params = match(request)
|
101
106
|
route = routes[index] if index
|
@@ -105,43 +110,85 @@ module Merb
|
|
105
110
|
end
|
106
111
|
[route, params]
|
107
112
|
end
|
108
|
-
|
109
|
-
#
|
113
|
+
|
114
|
+
# A placeholder for the compiled match method.
|
115
|
+
#
|
116
|
+
# ==== Notes
|
117
|
+
# This method is aliased as +match+ but this method gets overridden with
|
118
|
+
# the actual +match+ method (generated from the routes definitions) after
|
119
|
+
# being compiled. This method is only ever called before routes are
|
120
|
+
# compiled.
|
121
|
+
#
|
122
|
+
# ==== Raises
|
123
|
+
# NotCompiledError:: routes have not been compiled yet.
|
124
|
+
#
|
125
|
+
# @api private
|
110
126
|
def match_before_compilation(request) #:nodoc:
|
111
127
|
raise NotCompiledError, "The routes have not been compiled yet"
|
112
128
|
end
|
113
|
-
|
129
|
+
|
114
130
|
alias_method :match, :match_before_compilation
|
115
131
|
|
116
|
-
#
|
132
|
+
# There are three possible ways to use this method. First, if you have a named route,
|
133
|
+
# you can specify the route as the first parameter as a symbol and any paramters in a
|
134
|
+
# hash. Second, you can generate the default route by just passing the params hash,
|
135
|
+
# just passing the params hash. Finally, you can use the anonymous parameters. This
|
136
|
+
# allows you to specify the parameters to a named route in the order they appear in the
|
137
|
+
# router.
|
117
138
|
#
|
118
|
-
# ==== Parameters
|
119
|
-
# name<Symbol>::
|
120
|
-
# The name of the route
|
139
|
+
# ==== Parameters(Named Route)
|
140
|
+
# name<Symbol>::
|
141
|
+
# The name of the route.
|
142
|
+
# args<Hash>::
|
143
|
+
# Parameters for the route generation.
|
121
144
|
#
|
122
|
-
#
|
145
|
+
# ==== Parameters(Default Route)
|
146
|
+
# args<Hash>::
|
147
|
+
# Parameters for the route generation. This route will use the default route.
|
148
|
+
#
|
149
|
+
# ==== Parameters(Anonymous Parameters)
|
150
|
+
# name<Symbol>::
|
151
|
+
# The name of the route.
|
152
|
+
# args<Array>::
|
123
153
|
# An array of anonymous parameters to generate the route
|
124
154
|
# with. These parameters are assigned to the route parameters
|
125
155
|
# in the order that they are passed.
|
126
156
|
#
|
127
|
-
# params<Hash>::
|
128
|
-
# Named parameters to generate the route with.
|
129
|
-
#
|
130
|
-
# defaults<Hash>::
|
131
|
-
# A hash of default parameters to generate the route with.
|
132
|
-
# This is usually the request parameters. If there are any
|
133
|
-
# required params that are missing to generate the route,
|
134
|
-
# they are pulled from this hash.
|
135
157
|
# ==== Returns
|
136
|
-
# String:: The generated URL
|
137
|
-
#
|
138
|
-
#
|
158
|
+
# String:: The generated URL.
|
159
|
+
#
|
160
|
+
# ==== Examples
|
161
|
+
# Named Route
|
162
|
+
#
|
163
|
+
# Merb::Router.prepare do
|
164
|
+
# match("/articles/:title").to(:controller => :articles, :action => :show).name("articles")
|
165
|
+
# end
|
166
|
+
#
|
167
|
+
# url(:articles, :title => "new_article")
|
168
|
+
#
|
169
|
+
# Default Route
|
170
|
+
#
|
171
|
+
# Merb::Router.prepare do
|
172
|
+
# default_routes
|
173
|
+
# end
|
174
|
+
#
|
175
|
+
# url(:controller => "articles", :action => "new")
|
176
|
+
#
|
177
|
+
# Anonymous Paramters
|
178
|
+
#
|
179
|
+
# Merb::Router.prepare do
|
180
|
+
# match("/articles/:year/:month/:title").to(:controller => :articles, :action => :show).name("articles")
|
181
|
+
# end
|
182
|
+
#
|
183
|
+
# url(:articles, 2008, 10, "test_article")
|
184
|
+
#
|
185
|
+
# @api private
|
139
186
|
def url(name, *args)
|
140
187
|
unless name.is_a?(Symbol)
|
141
188
|
args.unshift(name)
|
142
189
|
name = :default
|
143
190
|
end
|
144
|
-
|
191
|
+
|
145
192
|
unless route = Merb::Router.named_routes[name]
|
146
193
|
raise Merb::Router::GenerationError, "Named route not found: #{name}"
|
147
194
|
end
|
@@ -152,25 +199,26 @@ module Merb
|
|
152
199
|
end
|
153
200
|
|
154
201
|
# Generates a URL from the resource(s)
|
155
|
-
#
|
202
|
+
#
|
156
203
|
# ==== Parameters
|
157
204
|
# resources<Symbol,Object>::
|
158
205
|
# The identifiers for the resource route to generate. These
|
159
206
|
# can either be symbols or objects. Symbols denote resource
|
160
207
|
# collection routes and objects denote the members.
|
161
|
-
#
|
208
|
+
#
|
162
209
|
# params<Hash>::
|
163
210
|
# Any extra parameters needed to generate the route.
|
211
|
+
#
|
164
212
|
# ==== Returns
|
165
213
|
# String:: The generated URL
|
166
|
-
#
|
167
|
-
# @private
|
214
|
+
#
|
215
|
+
# @api private
|
168
216
|
def resource(*args)
|
169
217
|
defaults = args.pop
|
170
218
|
options = extract_options_from_args!(args) || {}
|
171
219
|
key = []
|
172
220
|
params = []
|
173
|
-
|
221
|
+
|
174
222
|
args.each do |arg|
|
175
223
|
if arg.is_a?(Symbol) || arg.is_a?(String)
|
176
224
|
key << arg.to_s
|
@@ -179,19 +227,56 @@ module Merb
|
|
179
227
|
params << arg
|
180
228
|
end
|
181
229
|
end
|
182
|
-
|
230
|
+
|
183
231
|
params << options
|
184
|
-
|
232
|
+
|
185
233
|
unless route = Merb::Router.resource_routes[key]
|
186
234
|
raise Merb::Router::GenerationError, "Resource route not found: #{args.inspect}"
|
187
235
|
end
|
188
|
-
|
236
|
+
|
189
237
|
route.generate(params, defaults)
|
190
238
|
end
|
239
|
+
|
240
|
+
# Add functionality to the router. This can be in the form of
|
241
|
+
# including a new module or directly defining new methods.
|
242
|
+
#
|
243
|
+
# ==== Parameters
|
244
|
+
# &block<Block>::
|
245
|
+
# A block of code used to extend the route builder with. This
|
246
|
+
# can be including a module or directly defining some new methods
|
247
|
+
# that should be available to building routes.
|
248
|
+
#
|
249
|
+
# ==== Returns
|
250
|
+
# nil
|
251
|
+
#
|
252
|
+
# ==== Example
|
253
|
+
# Merb::Router.extensions do
|
254
|
+
# def domain(name, domain, options={}, &block)
|
255
|
+
# match(:domain => domain).namespace(name, :path => nil, &block)
|
256
|
+
# end
|
257
|
+
# end
|
258
|
+
#
|
259
|
+
# In this case, a method 'domain' will be available to the route builder
|
260
|
+
# which will create namespaces around domains instead of path prefixes.
|
261
|
+
#
|
262
|
+
# This can then be used as follows.
|
263
|
+
#
|
264
|
+
# Merb::Router.prepare do
|
265
|
+
# domain(:admin, "my-admin.com") do
|
266
|
+
# # ... routes come here ...
|
267
|
+
# end
|
268
|
+
# end
|
269
|
+
#
|
270
|
+
# @api public
|
271
|
+
def extensions(&block)
|
272
|
+
Router::Behavior.class_eval(&block)
|
273
|
+
end
|
191
274
|
|
192
275
|
private
|
193
276
|
|
194
|
-
#
|
277
|
+
# Compiles the routes and creates the +match+ method.
|
278
|
+
#
|
279
|
+
# @api private
|
195
280
|
def compile
|
196
281
|
if routes.any?
|
197
282
|
eval(compiled_statement, binding, "Generated Code for Router", 1)
|
@@ -199,18 +284,21 @@ module Merb
|
|
199
284
|
reset!
|
200
285
|
end
|
201
286
|
end
|
202
|
-
|
203
|
-
# Generates method
|
287
|
+
|
288
|
+
# Generates the method for evaluation defining a +match+ method to match
|
289
|
+
# a request with the defined routes.
|
290
|
+
#
|
291
|
+
# @api private
|
204
292
|
def compiled_statement
|
205
293
|
@compiler_mutex.synchronize do
|
206
294
|
condition_keys, if_statements = Set.new, ""
|
207
|
-
|
295
|
+
|
208
296
|
routes.each_with_index do |route, i|
|
209
297
|
route.freeze
|
210
298
|
route.conditions.keys.each { |key| condition_keys << key }
|
211
299
|
if_statements << route.compiled_statement(i == 0)
|
212
300
|
end
|
213
|
-
|
301
|
+
|
214
302
|
statement = "def match(request)\n"
|
215
303
|
statement << condition_keys.inject("") do |cached, key|
|
216
304
|
cached << " cached_#{key} = request.#{key}.to_s\n"
|
@@ -222,7 +310,7 @@ module Merb
|
|
222
310
|
statement << "end"
|
223
311
|
end
|
224
312
|
end
|
225
|
-
|
313
|
+
|
226
314
|
end # class << self
|
227
315
|
end
|
228
316
|
end
|
@@ -3,31 +3,51 @@ module Merb
|
|
3
3
|
class Router
|
4
4
|
|
5
5
|
class Behavior
|
6
|
-
|
7
|
-
class Error < StandardError; end
|
6
|
+
|
7
|
+
class Error < StandardError; end
|
8
8
|
|
9
9
|
# Proxy catches any methods and proxies them to the current behavior.
|
10
10
|
# This allows building routes without constantly having to catching the
|
11
11
|
# yielded behavior object
|
12
|
-
#
|
13
|
-
# @private
|
14
|
-
class Proxy
|
12
|
+
#
|
13
|
+
# @api private
|
14
|
+
class Proxy
|
15
|
+
|
15
16
|
# Undefine as many methods as possible so that everything can be proxied
|
16
17
|
# along to the behavior
|
17
18
|
instance_methods.each { |m| undef_method m unless %w[ __id__ __send__ class kind_of? respond_to? assert_kind_of should should_not instance_variable_set instance_variable_get instance_eval].include?(m) }
|
18
19
|
|
20
|
+
# @api private
|
19
21
|
def initialize
|
20
22
|
@behaviors = []
|
21
23
|
end
|
22
24
|
|
25
|
+
# Puts a behavior on the bottom of the stack.
|
26
|
+
#
|
27
|
+
# ==== Notes
|
28
|
+
# The behaviors keep track of nested scopes.
|
29
|
+
#
|
30
|
+
# @api private
|
23
31
|
def push(behavior)
|
24
32
|
@behaviors.push(behavior)
|
25
33
|
end
|
26
34
|
|
35
|
+
# Removes the top-most behavior.
|
36
|
+
#
|
37
|
+
# ==== Notes
|
38
|
+
# This occurs at the end of a nested scope (namespace, etc).
|
39
|
+
#
|
40
|
+
# @api private
|
27
41
|
def pop
|
28
42
|
@behaviors.pop
|
29
43
|
end
|
30
44
|
|
45
|
+
# Tests whether the top-most behavior responds to the arguments.
|
46
|
+
#
|
47
|
+
# ==== Notes
|
48
|
+
# Behaviors contain the actual functionality of the proxy.
|
49
|
+
#
|
50
|
+
# @api private
|
31
51
|
def respond_to?(*args)
|
32
52
|
super || @behaviors.last.respond_to?(*args)
|
33
53
|
end
|
@@ -35,7 +55,7 @@ module Merb
|
|
35
55
|
# Rake does some stuff with methods in the global namespace, so if I don't
|
36
56
|
# explicitly define the Behavior methods to proxy here (specifically namespace)
|
37
57
|
# Rake's methods take precedence.
|
38
|
-
#
|
58
|
+
#
|
39
59
|
# Removing the following:
|
40
60
|
# name full_name fixatable redirect
|
41
61
|
%w(
|
@@ -49,25 +69,86 @@ module Merb
|
|
49
69
|
}
|
50
70
|
end
|
51
71
|
|
52
|
-
#
|
72
|
+
# == These methods are to be used in defer_to blocks
|
53
73
|
|
54
|
-
#
|
55
|
-
#
|
74
|
+
# There are three possible ways to use this method. First, if you have a named route,
|
75
|
+
# you can specify the route as the first parameter as a symbol and any paramters in a
|
76
|
+
# hash. Second, you can generate the default route by just passing the params hash,
|
77
|
+
# just passing the params hash. Finally, you can use the anonymous parameters. This
|
78
|
+
# allows you to specify the parameters to a named route in the order they appear in the
|
79
|
+
# router.
|
80
|
+
#
|
81
|
+
# ==== Parameters(Named Route)
|
82
|
+
# name<Symbol>::
|
83
|
+
# The name of the route.
|
84
|
+
# args<Hash>::
|
85
|
+
# Parameters for the route generation.
|
86
|
+
#
|
87
|
+
# ==== Parameters(Default Route)
|
88
|
+
# args<Hash>::
|
89
|
+
# Parameters for the route generation. This route will use the default route.
|
90
|
+
#
|
91
|
+
# ==== Parameters(Anonymous Parameters)
|
92
|
+
# name<Symbol>::
|
93
|
+
# The name of the route.
|
94
|
+
# args<Array>::
|
95
|
+
# An array of anonymous parameters to generate the route
|
96
|
+
# with. These parameters are assigned to the route parameters
|
97
|
+
# in the order that they are passed.
|
98
|
+
#
|
99
|
+
# ==== Returns
|
100
|
+
# String:: The generated URL.
|
101
|
+
#
|
102
|
+
# ==== Examples
|
103
|
+
# Named Route
|
104
|
+
#
|
105
|
+
# Merb::Router.prepare do
|
106
|
+
# match("/articles/:title").to(:controller => :articles, :action => :show).name("articles")
|
107
|
+
# end
|
108
|
+
#
|
109
|
+
# url(:articles, :title => "new_article")
|
110
|
+
#
|
111
|
+
# Default Route
|
112
|
+
#
|
113
|
+
# Merb::Router.prepare do
|
114
|
+
# default_routes
|
115
|
+
# end
|
116
|
+
#
|
117
|
+
# url(:controller => "articles", :action => "new")
|
118
|
+
#
|
119
|
+
# Anonymous Paramters
|
120
|
+
#
|
121
|
+
# Merb::Router.prepare do
|
122
|
+
# match("/articles/:year/:month/:title").to(:controller => :articles, :action => :show).name("articles")
|
123
|
+
# end
|
124
|
+
#
|
125
|
+
# url(:articles, 2008, 10, "test_article")
|
126
|
+
#
|
127
|
+
# @api public
|
56
128
|
def url(name, *args)
|
57
129
|
args << {}
|
58
130
|
Merb::Router.url(name, *args)
|
59
131
|
end
|
60
132
|
|
133
|
+
# Generates a Rack redirection response.
|
134
|
+
#
|
135
|
+
# ==== Notes
|
136
|
+
# Refer to Merb::Rack::Helpers.redirect for documentation.
|
137
|
+
#
|
138
|
+
# @api public
|
61
139
|
def redirect(url, opts = {})
|
62
|
-
|
140
|
+
Merb::Rack::Helpers.redirect(url, opts)
|
63
141
|
end
|
64
142
|
|
65
|
-
|
66
|
-
params
|
67
|
-
end
|
143
|
+
private
|
68
144
|
|
69
|
-
|
70
|
-
|
145
|
+
# Proxies the method calls to the behavior.
|
146
|
+
#
|
147
|
+
# ==== Notes
|
148
|
+
# Please refer to:
|
149
|
+
# http://ruby-doc.org/core/classes/Kernel.html#M005951
|
150
|
+
#
|
151
|
+
# @api private
|
71
152
|
def method_missing(method, *args, &block)
|
72
153
|
behavior = @behaviors.last
|
73
154
|
|
@@ -78,14 +159,14 @@ module Merb
|
|
78
159
|
end
|
79
160
|
end
|
80
161
|
end
|
81
|
-
|
162
|
+
|
82
163
|
# Behavior objects are used for the Route building DSL. Each object keeps
|
83
164
|
# track of the current definitions for the level at which it is defined.
|
84
165
|
# Each time a method is called on a Behavior object that accepts a block,
|
85
166
|
# a new instance of the Behavior class is created.
|
86
|
-
#
|
167
|
+
#
|
87
168
|
# ==== Parameters
|
88
|
-
#
|
169
|
+
#
|
89
170
|
# proxy<Proxy>::
|
90
171
|
# This is the object initialized by Merb::Router.prepare that tracks the
|
91
172
|
# current Behavior object stack so that Behavior methods can be called
|
@@ -100,11 +181,11 @@ module Merb
|
|
100
181
|
# The initial route options. See #options.
|
101
182
|
# blocks<Array>::
|
102
183
|
# The stack of deferred routing blocks for the route
|
103
|
-
#
|
184
|
+
#
|
104
185
|
# ==== Returns
|
105
186
|
# Behavior:: The initialized Behavior object
|
106
|
-
|
107
|
-
# @private
|
187
|
+
#
|
188
|
+
# @api private
|
108
189
|
def initialize(proxy = nil, conditions = {}, params = {}, defaults = {}, identifiers = {}, options = {}, blocks = []) #:nodoc:
|
109
190
|
@proxy = proxy
|
110
191
|
@conditions = conditions
|
@@ -113,130 +194,129 @@ module Merb
|
|
113
194
|
@identifiers = identifiers
|
114
195
|
@options = options
|
115
196
|
@blocks = blocks
|
116
|
-
|
197
|
+
|
117
198
|
stringify_condition_values
|
118
199
|
end
|
119
|
-
|
200
|
+
|
120
201
|
# Defines the +conditions+ that are required to match a Request. Each
|
121
202
|
# +condition+ is applied to a method of the Request object. Conditions
|
122
203
|
# can also be applied to segments of the +path+.
|
123
|
-
#
|
204
|
+
#
|
124
205
|
# If #match is passed a block, it will create a new route scope with
|
125
206
|
# the conditions passed to it and yield to the block such that all
|
126
207
|
# routes that are defined in the block have the conditions applied
|
127
208
|
# to them.
|
128
|
-
#
|
209
|
+
#
|
129
210
|
# ==== Parameters
|
130
|
-
#
|
211
|
+
#
|
131
212
|
# path<String, Regexp>::
|
132
213
|
# The pattern against which Merb::Request path is matched.
|
133
|
-
#
|
214
|
+
#
|
134
215
|
# When +path+ is a String, any substring that is wrapped in parenthesis
|
135
216
|
# is considered optional and any segment that begins with a colon, ex.:
|
136
217
|
# ":login", defines both a capture and a named param. Extra conditions
|
137
218
|
# can then be applied each named param individually.
|
138
|
-
#
|
219
|
+
#
|
139
220
|
# When +path+ is a Regexp, the pattern is left untouched and the
|
140
221
|
# Merb::Request path is matched against it as is.
|
141
222
|
#
|
142
223
|
# +path+ is optional.
|
143
|
-
#
|
224
|
+
#
|
144
225
|
# conditions<Hash>::
|
145
226
|
# Additional conditions that the request must meet in order to match.
|
146
227
|
# The keys must be the names of previously defined path segments or
|
147
228
|
# be methods that the Merb::Request instance will respond to. The
|
148
229
|
# value is the string or regexp that matched the returned value.
|
149
230
|
# Conditions are inherited by child routes.
|
150
|
-
#
|
231
|
+
#
|
151
232
|
# &block::
|
152
233
|
# All routes defined in the block will be scoped to the conditions
|
153
234
|
# defined by the #match method.
|
154
|
-
#
|
235
|
+
#
|
155
236
|
# ==== Block parameters
|
156
237
|
# r<Behavior>:: +optional+ - The match behavior object.
|
157
|
-
#
|
238
|
+
#
|
158
239
|
# ==== Returns
|
159
240
|
# Behavior::
|
160
241
|
# A new instance of Behavior with the specified path and conditions.
|
161
|
-
#
|
242
|
+
#
|
162
243
|
# +Tip+: When nesting always make sure the most inner sub-match registers
|
163
|
-
# a Route and doesn't just
|
164
|
-
#
|
244
|
+
# a Route and doesn't just return new Behaviors.
|
245
|
+
#
|
165
246
|
# ==== Examples
|
166
|
-
#
|
247
|
+
#
|
167
248
|
# # registers /foo/bar to controller => "foo", :action => "bar"
|
168
249
|
# # and /foo/baz to controller => "foo", :action => "baz"
|
169
250
|
# match("/foo") do
|
170
251
|
# match("/bar").to(:controller => "foo", :action => "bar")
|
171
252
|
# match("/baz").to(:controller => "foo", :action => "caz")
|
172
253
|
# end
|
173
|
-
#
|
254
|
+
#
|
174
255
|
# # Checks the format of the segments against the specified Regexp
|
175
256
|
# match("/:string/:number", :string => /[a-z]+/, :number => /\d+/).
|
176
257
|
# to(:controller => "string_or_numbers")
|
177
|
-
#
|
258
|
+
#
|
178
259
|
# # Equivalent to the default_route
|
179
260
|
# match("/:controller(/:action(:id))(.:format)").register
|
180
|
-
#
|
261
|
+
#
|
181
262
|
# #match only if the browser string contains MSIE or Gecko
|
182
263
|
# match("/foo", :user_agent => /(MSIE|Gecko)/ )
|
183
264
|
# .to(:controller => 'foo', :action => 'popular')
|
184
|
-
#
|
265
|
+
#
|
185
266
|
# # Route GET and POST requests to different actions (see also #resources)
|
186
267
|
# r.match('/foo', :method => :get).to(:action => 'show')
|
187
268
|
# r.match('/foo', :method => :post).to(:action => 'create')
|
188
|
-
#
|
269
|
+
#
|
189
270
|
# # match also takes regular expressions
|
190
|
-
#
|
271
|
+
#
|
191
272
|
# r.match(%r[/account/([a-z]{4,6})]).to(:controller => "account",
|
192
273
|
# :action => "show", :id => "[1]")
|
193
|
-
#
|
274
|
+
#
|
194
275
|
# r.match(%r{/?(en|es|fr|be|nl)?}).to(:language => "[1]") do
|
195
276
|
# match("/guides/:action/:id").to(:controller => "tour_guides")
|
196
277
|
# end
|
197
|
-
|
198
|
-
# @public
|
278
|
+
#
|
279
|
+
# @api public
|
199
280
|
def match(path = {}, conditions = {}, &block)
|
200
281
|
path, conditions = path[:path], path if path.is_a?(Hash)
|
201
|
-
|
202
|
-
raise Error, "The route has already been committed. Further conditions cannot be specified" if @route
|
203
282
|
|
283
|
+
raise Error, "The route has already been committed. Further conditions cannot be specified" if @route
|
204
284
|
|
205
285
|
conditions.delete_if { |k, v| v.nil? }
|
206
286
|
conditions[:path] = merge_paths(path)
|
207
|
-
|
287
|
+
|
208
288
|
behavior = Behavior.new(@proxy, @conditions.merge(conditions), @params, @defaults, @identifiers, @options, @blocks)
|
209
289
|
with_behavior_context(behavior, &block)
|
210
290
|
end
|
211
291
|
|
212
292
|
# Creates a Route from one or more Behavior objects, unless a +block+ is
|
213
293
|
# passed in.
|
214
|
-
#
|
294
|
+
#
|
215
295
|
# ==== Parameters
|
216
296
|
# params<Hash>:: The parameters the route maps to.
|
217
|
-
#
|
297
|
+
#
|
218
298
|
# &block::
|
219
299
|
# All routes defined in the block will be scoped to the params
|
220
300
|
# defined by the #to method.
|
221
|
-
#
|
301
|
+
#
|
222
302
|
# ==== Block parameters
|
223
303
|
# r<Behavior>:: +optional+ - The to behavior object.
|
224
|
-
#
|
304
|
+
#
|
225
305
|
# ==== Returns
|
226
306
|
# Route:: It registers a new route and returns it.
|
227
|
-
#
|
307
|
+
#
|
228
308
|
# ==== Examples
|
229
309
|
# match('/:controller/:id).to(:action => 'show')
|
230
|
-
#
|
310
|
+
#
|
231
311
|
# to(:controller => 'simple') do
|
232
312
|
# match('/test').to(:action => 'index')
|
233
313
|
# match('/other').to(:action => 'other')
|
234
314
|
# end
|
235
|
-
|
236
|
-
# @public
|
315
|
+
#
|
316
|
+
# @api public
|
237
317
|
def to(params = {}, &block)
|
238
318
|
raise Error, "The route has already been committed. Further params cannot be specified" if @route
|
239
|
-
|
319
|
+
|
240
320
|
behavior = Behavior.new(@proxy, @conditions, @params.merge(params), @defaults, @identifiers, @options, @blocks)
|
241
321
|
|
242
322
|
if block_given?
|
@@ -247,7 +327,8 @@ module Merb
|
|
247
327
|
end
|
248
328
|
|
249
329
|
# Equivalent of #to. Allows for some nicer syntax when scoping blocks
|
250
|
-
#
|
330
|
+
#
|
331
|
+
# ==== Examples
|
251
332
|
# Merb::Router.prepare do
|
252
333
|
# with(:controller => "users") do
|
253
334
|
# match("/signup").to(:action => "signup")
|
@@ -255,32 +336,32 @@ module Merb
|
|
255
336
|
# match("/logout").to(:action => "logout")
|
256
337
|
# end
|
257
338
|
# end
|
258
|
-
|
339
|
+
alias :with :to
|
259
340
|
|
260
341
|
# Equivalent of #to. Allows for nicer syntax when registering routes with no params
|
261
|
-
#
|
342
|
+
#
|
343
|
+
# ==== Examples
|
262
344
|
# Merb::Router.prepare do
|
263
345
|
# match("/:controller(/:action(/:id))(.:format)").register
|
264
346
|
# end
|
265
|
-
|
266
|
-
alias_method :register, :to
|
347
|
+
alias :register :to
|
267
348
|
|
268
349
|
# Sets default values for route parameters. If no value for the key
|
269
350
|
# can be extracted from the request, then the value provided here
|
270
351
|
# will be used.
|
271
|
-
#
|
352
|
+
#
|
272
353
|
# ==== Parameters
|
273
354
|
# defaults<Hash>::
|
274
355
|
# The default values for named segments.
|
275
|
-
#
|
356
|
+
#
|
276
357
|
# &block::
|
277
358
|
# All routes defined in the block will be scoped to the defaults defined
|
278
359
|
# by the #default method.
|
279
|
-
#
|
360
|
+
#
|
280
361
|
# ==== Block parameters
|
281
362
|
# r<Behavior>:: +optional+ - The defaults behavior object.
|
282
|
-
#
|
283
|
-
# @public
|
363
|
+
#
|
364
|
+
# @api public
|
284
365
|
def default(defaults = {}, &block)
|
285
366
|
behavior = Behavior.new(@proxy, @conditions, @params, @defaults.merge(defaults), @identifiers, @options, @blocks)
|
286
367
|
with_behavior_context(behavior, &block)
|
@@ -289,34 +370,34 @@ module Merb
|
|
289
370
|
alias_method :defaults, :default
|
290
371
|
|
291
372
|
# Allows the fine tuning of certain router options.
|
292
|
-
#
|
373
|
+
#
|
293
374
|
# ==== Parameters
|
294
375
|
# options<Hash>::
|
295
376
|
# The options to set for all routes defined in the scope. The currently
|
296
377
|
# supported options are:
|
297
378
|
# * :controller_prefix - The module that the controller is included in.
|
298
379
|
# * :name_prefix - The prefix added to all routes named with #name
|
299
|
-
#
|
380
|
+
#
|
300
381
|
# &block::
|
301
382
|
# All routes defined in the block will be scoped to the options defined
|
302
383
|
# by the #options method.
|
303
|
-
#
|
384
|
+
#
|
304
385
|
# ==== Block parameters
|
305
386
|
# r<Behavior>:: The options behavior object. This is optional
|
306
|
-
#
|
387
|
+
#
|
307
388
|
# ==== Examples
|
308
389
|
# # If :group is not matched in the path, it will be "registered" instead
|
309
390
|
# # of nil.
|
310
391
|
# match("/users(/:group)").default(:group => "registered")
|
311
|
-
#
|
312
|
-
# @public
|
392
|
+
#
|
393
|
+
# @api public
|
313
394
|
def options(opts = {}, &block)
|
314
395
|
options = @options.dup
|
315
|
-
|
396
|
+
|
316
397
|
opts.each_pair do |key, value|
|
317
398
|
options[key] = (options[key] || []) + [value.freeze] if value
|
318
399
|
end
|
319
|
-
|
400
|
+
|
320
401
|
behavior = Behavior.new(@proxy, @conditions, @params, @defaults, @identifiers, options, @blocks)
|
321
402
|
with_behavior_context(behavior, &block)
|
322
403
|
end
|
@@ -325,44 +406,47 @@ module Merb
|
|
325
406
|
|
326
407
|
# Creates a namespace for a route. This way you can have logical
|
327
408
|
# separation to your routes.
|
328
|
-
#
|
409
|
+
#
|
329
410
|
# ==== Parameters
|
330
411
|
# name_or_path<String, Symbol>::
|
331
412
|
# The name or path of the namespace.
|
332
|
-
#
|
413
|
+
#
|
333
414
|
# options<Hash>::
|
334
|
-
# Optional hash
|
335
|
-
#
|
415
|
+
# Optional hash (see below)
|
416
|
+
#
|
336
417
|
# &block::
|
337
418
|
# All routes defined in the block will be scoped to the namespace defined
|
338
419
|
# by the #namespace method.
|
339
|
-
#
|
420
|
+
#
|
421
|
+
# ==== Options (opts)
|
422
|
+
# :path<String>:: match against this url
|
423
|
+
#
|
340
424
|
# ==== Block parameters
|
341
425
|
# r<Behavior>:: The namespace behavior object. This is optional
|
342
|
-
#
|
426
|
+
#
|
343
427
|
# ==== Examples
|
344
428
|
# namespace :admin do
|
345
429
|
# resources :accounts
|
346
430
|
# resource :email
|
347
431
|
# end
|
348
|
-
#
|
432
|
+
#
|
349
433
|
# # /super_admin/accounts
|
350
434
|
# namespace(:admin, :path=>"super_admin") do
|
351
435
|
# resources :accounts
|
352
436
|
# end
|
353
|
-
#
|
354
|
-
# @public
|
437
|
+
#
|
438
|
+
# @api public
|
355
439
|
def namespace(name_or_path, opts = {}, &block)
|
356
440
|
name = name_or_path.to_s # We don't want this modified ever
|
357
441
|
path = opts.has_key?(:path) ? opts[:path] : name
|
358
|
-
|
442
|
+
|
359
443
|
raise Error, "The route has already been committed. Further options cannot be specified" if @route
|
360
|
-
|
444
|
+
|
361
445
|
# option keys could be nil
|
362
446
|
opts[:controller_prefix] = name unless opts.has_key?(:controller_prefix)
|
363
447
|
opts[:name_prefix] = name unless opts.has_key?(:name_prefix)
|
364
448
|
opts[:resource_prefix] = opts[:name_prefix] unless opts.has_key?(:resource_prefix)
|
365
|
-
|
449
|
+
|
366
450
|
behavior = self
|
367
451
|
behavior = behavior.match("/#{path}") unless path.nil? || path.empty?
|
368
452
|
behavior.options(opts, &block)
|
@@ -372,22 +456,22 @@ module Merb
|
|
372
456
|
# insertion into a route. This is useful when using models and want a
|
373
457
|
# specific method to be called on it (For example, for ActiveRecord::Base
|
374
458
|
# it would be #to_param).
|
375
|
-
#
|
459
|
+
#
|
376
460
|
# The default method called on objects is #to_s.
|
377
|
-
#
|
461
|
+
#
|
378
462
|
# ==== Paramters
|
379
463
|
# identifiers<Hash>::
|
380
464
|
# The keys are Classes and the values are the method that instances of the specified
|
381
465
|
# class should have called on.
|
382
|
-
#
|
466
|
+
#
|
383
467
|
# &block::
|
384
468
|
# All routes defined in the block will be call the specified methods during
|
385
469
|
# generation.
|
386
|
-
#
|
470
|
+
#
|
387
471
|
# ==== Block parameters
|
388
472
|
# r<Behavior>:: The identify behavior object. This is optional
|
389
|
-
#
|
390
|
-
# @public
|
473
|
+
#
|
474
|
+
# @api public
|
391
475
|
def identify(identifiers = {}, &block)
|
392
476
|
identifiers = if Hash === identifiers
|
393
477
|
@identifiers.merge(identifiers)
|
@@ -402,23 +486,23 @@ module Merb
|
|
402
486
|
# Creates the most common routes /:controller/:action/:id.format when
|
403
487
|
# called with no arguments. You can pass a hash or a block to add parameters
|
404
488
|
# or override the default behavior.
|
405
|
-
#
|
489
|
+
#
|
406
490
|
# ==== Parameters
|
407
491
|
# params<Hash>::
|
408
492
|
# This optional hash can be used to augment the default settings
|
409
|
-
#
|
493
|
+
#
|
410
494
|
# &block::
|
411
495
|
# When passing a block a new behavior is yielded and more refinement is
|
412
496
|
# possible.
|
413
|
-
#
|
497
|
+
#
|
414
498
|
# ==== Returns
|
415
499
|
# Route:: the default route
|
416
|
-
#
|
500
|
+
#
|
417
501
|
# ==== Examples
|
418
|
-
#
|
502
|
+
#
|
419
503
|
# # Passing an extra parameter "mode" to all matches
|
420
504
|
# r.default_routes :mode => "default"
|
421
|
-
#
|
505
|
+
#
|
422
506
|
# # specifying exceptions within a block
|
423
507
|
# r.default_routes do |nr|
|
424
508
|
# nr.defer_to do |request, params|
|
@@ -426,31 +510,31 @@ module Merb
|
|
426
510
|
# :action => "new") if request.env["REQUEST_URI"] =~ /\/private\//
|
427
511
|
# end
|
428
512
|
# end
|
429
|
-
|
430
|
-
# @public
|
513
|
+
#
|
514
|
+
# @api public
|
431
515
|
def default_routes(params = {}, &block)
|
432
516
|
match("/:controller(/:action(/:id))(.:format)").to(params, &block).name(:default)
|
433
517
|
end
|
434
518
|
|
435
519
|
# Takes a block and stores it for deferred conditional routes. The block
|
436
520
|
# takes the +request+ object and the +params+ hash as parameters.
|
437
|
-
#
|
521
|
+
#
|
438
522
|
# ==== Parameters
|
439
523
|
# params<Hash>:: Parameters and conditions associated with this behavior.
|
440
524
|
# &conditional_block::
|
441
525
|
# A block with the conditions to be met for the behavior to take
|
442
526
|
# effect.
|
443
|
-
#
|
527
|
+
#
|
444
528
|
# ==== Returns
|
445
529
|
# Route :: The default route.
|
446
|
-
#
|
530
|
+
#
|
447
531
|
# ==== Examples
|
448
532
|
# defer_to do |request, params|
|
449
533
|
# params.merge :controller => 'here',
|
450
534
|
# :action => 'there' if request.xhr?
|
451
535
|
# end
|
452
|
-
|
453
|
-
# @public
|
536
|
+
#
|
537
|
+
# @api public
|
454
538
|
def defer_to(params = {}, &block)
|
455
539
|
defer(block).to(params)
|
456
540
|
end
|
@@ -458,27 +542,39 @@ module Merb
|
|
458
542
|
# Takes a Proc as a parameter and applies it as a deferred proc for all the
|
459
543
|
# routes defined in the block. This is mostly interesting for plugin
|
460
544
|
# developers.
|
545
|
+
#
|
546
|
+
# ==== Examples
|
547
|
+
# defered_block = proc do |r, p|
|
548
|
+
# p.merge :controller => 'api/comments' if request.xhr?
|
549
|
+
# end
|
550
|
+
# defer(defered_block) do
|
551
|
+
# resources :comments
|
552
|
+
# end
|
553
|
+
#
|
554
|
+
# @api public
|
461
555
|
def defer(deferred_block, &block)
|
462
556
|
blocks = @blocks + [CachedProc.new(deferred_block)]
|
463
557
|
behavior = Behavior.new(@proxy, @conditions, @params, @defaults, @identifiers, @options, blocks)
|
464
558
|
with_behavior_context(behavior, &block)
|
465
559
|
end
|
466
560
|
|
467
|
-
#
|
468
|
-
#
|
561
|
+
# Registers the route as a named route with the name given.
|
562
|
+
#
|
469
563
|
# ==== Parameters
|
470
|
-
# symbol<Symbol>::
|
471
|
-
#
|
564
|
+
# symbol<Symbol>:: the name of the route.
|
565
|
+
#
|
472
566
|
# ==== Raises
|
473
567
|
# ArgumentError:: symbol is not a Symbol.
|
568
|
+
#
|
569
|
+
# @api public
|
474
570
|
def name(prefix, name = nil)
|
475
571
|
unless name
|
476
572
|
name, prefix = prefix, nil
|
477
573
|
end
|
478
|
-
|
574
|
+
|
479
575
|
full_name([prefix, @options[:name_prefix], name].flatten.compact.join('_'))
|
480
576
|
end
|
481
|
-
|
577
|
+
|
482
578
|
# Names this route in Router. Name must be a Symbol. The current
|
483
579
|
# name_prefix is ignored.
|
484
580
|
#
|
@@ -487,6 +583,8 @@ module Merb
|
|
487
583
|
#
|
488
584
|
# ==== Raises
|
489
585
|
# ArgumentError:: symbol is not a Symbol.
|
586
|
+
#
|
587
|
+
# @api private
|
490
588
|
def full_name(name)
|
491
589
|
if @route
|
492
590
|
@route.name = name
|
@@ -496,27 +594,34 @@ module Merb
|
|
496
594
|
end
|
497
595
|
end
|
498
596
|
|
597
|
+
# Specifies that a route can be fixatable.
|
598
|
+
#
|
499
599
|
# ==== Parameters
|
500
600
|
# enabled<Boolean>:: True enables fixation on the route.
|
601
|
+
#
|
602
|
+
# @api public
|
501
603
|
def fixatable(enable = true)
|
502
604
|
@route.fixation = enable
|
503
605
|
self
|
504
606
|
end
|
505
|
-
|
506
|
-
#
|
507
|
-
#
|
607
|
+
|
608
|
+
# Redirects the current route.
|
609
|
+
#
|
508
610
|
# ==== Parameters
|
509
|
-
# path<String
|
510
|
-
#
|
511
|
-
#
|
611
|
+
# path<String>:: The path to redirect to.
|
612
|
+
#
|
512
613
|
# options<Hash>::
|
513
|
-
# Options
|
514
|
-
#
|
515
|
-
#
|
516
|
-
#
|
614
|
+
# Options (see below)
|
615
|
+
#
|
616
|
+
# ==== Options (opts)
|
617
|
+
# :permanent<Boolean>::
|
618
|
+
# Whether or not the redirect should be permanent.
|
619
|
+
# The default value is false.
|
620
|
+
#
|
621
|
+
# @api public
|
517
622
|
def redirect(url, opts = {})
|
518
623
|
raise Error, "The route has already been committed." if @route
|
519
|
-
|
624
|
+
|
520
625
|
status = opts[:permanent] ? 301 : 302
|
521
626
|
@route = Route.new(@conditions, {:url => url.freeze, :status => status.freeze}, @blocks, :redirects => true)
|
522
627
|
@route.register
|
@@ -529,6 +634,8 @@ module Merb
|
|
529
634
|
# it doesn't affect how/which routes are added.
|
530
635
|
#
|
531
636
|
# &block:: A context in which routes are generated.
|
637
|
+
#
|
638
|
+
# @api public
|
532
639
|
def capture(&block)
|
533
640
|
captured_routes = {}
|
534
641
|
name_prefix = [@options[:name_prefix]].flatten.compact.map { |p| "#{p}_"}
|
@@ -545,27 +652,42 @@ module Merb
|
|
545
652
|
captured_routes
|
546
653
|
end
|
547
654
|
|
548
|
-
#
|
549
|
-
#
|
550
|
-
#
|
551
|
-
|
655
|
+
# Proxy routes with the default behaviors.
|
656
|
+
#
|
657
|
+
# ==== Parameters
|
658
|
+
# &block:: defines routes within the provided context.
|
659
|
+
#
|
660
|
+
# @api private
|
661
|
+
def _with_proxy(&block)
|
552
662
|
proxy = Proxy.new
|
553
663
|
proxy.push Behavior.new(proxy, @conditions, @params, @defaults, @identifiers, @options, @blocks)
|
554
664
|
proxy.instance_eval(&block)
|
555
665
|
proxy
|
556
666
|
end
|
557
667
|
|
558
|
-
|
559
|
-
|
668
|
+
protected
|
669
|
+
|
670
|
+
# Returns the current route.
|
671
|
+
#
|
672
|
+
# ==== Returns
|
673
|
+
# Route:: the route.
|
674
|
+
#
|
675
|
+
# @api private
|
560
676
|
def _route
|
561
677
|
@route
|
562
678
|
end
|
563
679
|
|
564
|
-
|
680
|
+
# Turns a route definition into a Route object.
|
681
|
+
#
|
682
|
+
# ==== Returns
|
683
|
+
# Route:: the route generated.
|
684
|
+
#
|
685
|
+
# @api private
|
686
|
+
def to_route
|
565
687
|
raise Error, "The route has already been committed." if @route
|
566
|
-
|
688
|
+
|
567
689
|
controller = @params[:controller]
|
568
|
-
|
690
|
+
|
569
691
|
if prefixes = @options[:controller_prefix]
|
570
692
|
controller ||= ":controller"
|
571
693
|
|
@@ -594,12 +716,22 @@ module Merb
|
|
594
716
|
|
595
717
|
# Allows to insert the route at a certain spot in the list of routes
|
596
718
|
# instead of appending to the list.
|
597
|
-
|
719
|
+
#
|
720
|
+
# ==== Params
|
721
|
+
# route<Route>:: the route to insert before.
|
722
|
+
# &block:: the route definition to insert.
|
723
|
+
#
|
724
|
+
# @api plugin
|
725
|
+
def before(route, &block)
|
598
726
|
options(:before => route, &block)
|
599
727
|
end
|
600
|
-
|
601
|
-
|
602
|
-
|
728
|
+
|
729
|
+
private
|
730
|
+
|
731
|
+
# Takes @conditions and turns values into strings (except for Regexp and
|
732
|
+
# Array values).
|
733
|
+
#
|
734
|
+
# @api private
|
603
735
|
def stringify_condition_values # :nodoc:
|
604
736
|
@conditions.each do |key, value|
|
605
737
|
unless value.nil? || Regexp === value || Array === value
|
@@ -607,7 +739,18 @@ module Merb
|
|
607
739
|
end
|
608
740
|
end
|
609
741
|
end
|
610
|
-
|
742
|
+
|
743
|
+
# Creates a new context with a given behavior for the route definition in
|
744
|
+
# the block.
|
745
|
+
#
|
746
|
+
# ==== Params
|
747
|
+
# behavior<Behavior>:: the behavior to proxy the calls in the block.
|
748
|
+
# &block:: the routing definitions to be nested within the behavior.
|
749
|
+
#
|
750
|
+
# ==== Returns
|
751
|
+
# Behavior:: the behavior wrapping.
|
752
|
+
#
|
753
|
+
# @api private
|
611
754
|
def with_behavior_context(behavior, &block) # :nodoc:
|
612
755
|
if block_given?
|
613
756
|
@proxy.push(behavior)
|
@@ -616,11 +759,25 @@ module Merb
|
|
616
759
|
end
|
617
760
|
behavior
|
618
761
|
end
|
619
|
-
|
762
|
+
|
763
|
+
# Merges the path elements together into an array to be joined for
|
764
|
+
# generating named routes.
|
765
|
+
#
|
766
|
+
# ==== Parameters
|
767
|
+
# path<String>:: the path to merge at the end.
|
768
|
+
#
|
769
|
+
# ==== Returns
|
770
|
+
# Array:: array of path elements.
|
771
|
+
#
|
772
|
+
# ==== Notes
|
773
|
+
# An array of ['a', 'b'] (the 'a' namespace with the 'b' action) will
|
774
|
+
# produce a name of :a_b.
|
775
|
+
#
|
776
|
+
# @api private
|
620
777
|
def merge_paths(path) # :nodoc:
|
621
778
|
[@conditions[:path], path.freeze].flatten.compact
|
622
779
|
end
|
623
|
-
|
780
|
+
|
624
781
|
end
|
625
782
|
end
|
626
783
|
end
|