padrino-core 0.10.2 → 0.10.3
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/.document +3 -3
- data/.yardopts +1 -0
- data/{LICENSE → LICENSE.txt} +0 -0
- data/README.rdoc +2 -2
- data/lib/padrino-core/application/rendering.rb +79 -26
- data/lib/padrino-core/application/routing.rb +215 -127
- data/lib/padrino-core/application/showexceptions.rb +2 -1
- data/lib/padrino-core/application.rb +67 -57
- data/lib/padrino-core/caller.rb +10 -4
- data/lib/padrino-core/command.rb +11 -0
- data/lib/padrino-core/loader.rb +52 -24
- data/lib/padrino-core/locale/cs.yml +4 -1
- data/lib/padrino-core/locale/da.yml +4 -1
- data/lib/padrino-core/locale/de.yml +4 -1
- data/lib/padrino-core/locale/en.yml +4 -1
- data/lib/padrino-core/locale/es.yml +4 -1
- data/lib/padrino-core/locale/fr.yml +4 -1
- data/lib/padrino-core/locale/hu.yml +4 -1
- data/lib/padrino-core/locale/it.yml +4 -1
- data/lib/padrino-core/locale/ja.yml +4 -1
- data/lib/padrino-core/locale/lv.yml +34 -0
- data/lib/padrino-core/locale/nl.yml +4 -1
- data/lib/padrino-core/locale/no.yml +4 -1
- data/lib/padrino-core/locale/pl.yml +4 -1
- data/lib/padrino-core/locale/pt_br.yml +4 -1
- data/lib/padrino-core/locale/ru.yml +4 -1
- data/lib/padrino-core/locale/tr.yml +4 -1
- data/lib/padrino-core/locale/uk.yml +4 -1
- data/lib/padrino-core/locale/zh_cn.yml +4 -1
- data/lib/padrino-core/locale/zh_tw.yml +4 -1
- data/lib/padrino-core/logger.rb +119 -128
- data/lib/padrino-core/mounter.rb +46 -14
- data/lib/padrino-core/reloader.rb +5 -3
- data/lib/padrino-core/router.rb +30 -11
- data/lib/padrino-core/server.rb +14 -5
- data/lib/padrino-core/support_lite.rb +54 -20
- data/lib/padrino-core/tasks.rb +1 -3
- data/lib/padrino-core/version.rb +8 -4
- data/lib/padrino-core.rb +58 -11
- data/padrino-core.gemspec +1 -1
- data/test/fixtures/apps/simple.rb +1 -1
- data/test/helper.rb +4 -24
- data/test/mini_shoulda.rb +45 -0
- data/test/test_application.rb +19 -18
- data/test/test_core.rb +2 -2
- data/test/test_dependencies.rb +5 -5
- data/test/test_filters.rb +2 -1
- data/test/test_locale.rb +1 -1
- data/test/test_logger.rb +1 -1
- data/test/test_mounter.rb +26 -25
- data/test/test_reloader_complex.rb +5 -3
- data/test/test_reloader_simple.rb +6 -5
- data/test/test_rendering.rb +8 -5
- data/test/test_restful_routing.rb +1 -1
- data/test/test_router.rb +1 -1
- data/test/test_routing.rb +33 -12
- metadata +13 -9
@@ -1,7 +1,11 @@
|
|
1
1
|
require 'http_router' unless defined?(HttpRouter)
|
2
2
|
require 'padrino-core/support_lite' unless defined?(SupportLite)
|
3
3
|
|
4
|
-
|
4
|
+
##
|
5
|
+
# Adds to Sinatra +controller+ informations
|
6
|
+
#
|
7
|
+
# @private
|
8
|
+
class Sinatra::Request
|
5
9
|
attr_accessor :route_obj
|
6
10
|
|
7
11
|
def controller
|
@@ -9,7 +13,11 @@ class Sinatra::Request # @private
|
|
9
13
|
end
|
10
14
|
end
|
11
15
|
|
12
|
-
|
16
|
+
##
|
17
|
+
# HttpRouter adapter
|
18
|
+
#
|
19
|
+
# @private
|
20
|
+
class HttpRouter
|
13
21
|
def rewrite_partial_path_info(env, request); end
|
14
22
|
def rewrite_path_info(env, request); end
|
15
23
|
|
@@ -17,6 +25,7 @@ class HttpRouter # @private
|
|
17
25
|
Thread.current['padrino.instance'].instance_eval do
|
18
26
|
request.route_obj = path.route
|
19
27
|
@_response_buffer = nil
|
28
|
+
@route = path.route
|
20
29
|
@params ||= {}
|
21
30
|
@params.update(env['router.params'])
|
22
31
|
@block_params = if path.route.is_a?(HttpRouter::RegexRoute)
|
@@ -30,59 +39,55 @@ class HttpRouter # @private
|
|
30
39
|
# Provide access to the current controller to the request
|
31
40
|
# Now we can eval route, but because we have "throw halt" we need to be
|
32
41
|
# (en)sure to reset old layout and run controller after filters.
|
33
|
-
|
34
|
-
parent_layout
|
35
|
-
successful
|
42
|
+
original_params = @params
|
43
|
+
parent_layout = @layout
|
44
|
+
successful = false
|
36
45
|
begin
|
37
46
|
filter! :before
|
38
|
-
(
|
39
|
-
# If present set current controller layout
|
47
|
+
(@route.before_filters - settings.filters[:before]).each { |block| instance_eval(&block) }
|
40
48
|
@layout = path.route.use_layout if path.route.use_layout
|
41
|
-
@route
|
42
|
-
@route.
|
43
|
-
|
44
|
-
halt_response = catch(:halt) { route_eval(&path.route.dest) }
|
49
|
+
@route.custom_conditions.each { |block| pass if block.bind(self).call == false } if @route.custom_conditions
|
50
|
+
@block_params = @block_params[0, @route.dest.arity] if @route.dest.arity > 0
|
51
|
+
halt_response = catch(:halt) { route_eval { @route.dest[self, @block_params] } }
|
45
52
|
@_response_buffer = halt_response.is_a?(Array) ? halt_response.last : halt_response
|
46
|
-
successful
|
47
|
-
halt
|
53
|
+
successful = true
|
54
|
+
halt halt_response
|
48
55
|
ensure
|
49
|
-
(@
|
56
|
+
(@route.after_filters - settings.filters[:after]).each { |block| instance_eval(&block) } if successful
|
50
57
|
@layout = parent_layout
|
51
|
-
@params =
|
58
|
+
@params = original_params
|
52
59
|
end
|
53
60
|
end
|
54
61
|
end
|
55
62
|
|
56
|
-
class Route
|
57
|
-
|
58
|
-
attr_accessor :custom_conditions, :use_layout, :controller, :cache
|
63
|
+
class Route
|
64
|
+
attr_accessor :use_layout, :controller, :cache, :cache_key, :cache_expires_in
|
59
65
|
|
60
|
-
def
|
61
|
-
@
|
62
|
-
@
|
63
|
-
end
|
66
|
+
def before_filters(&block)
|
67
|
+
@_before_filters ||= []
|
68
|
+
@_before_filters << block if block_given?
|
64
69
|
|
65
|
-
|
66
|
-
@after_filters ||= []
|
67
|
-
@after_filters << filter
|
70
|
+
@_before_filters
|
68
71
|
end
|
69
72
|
|
70
|
-
def
|
71
|
-
|
72
|
-
|
73
|
+
def after_filters(&block)
|
74
|
+
@_after_filters ||= []
|
75
|
+
@_after_filters << block if block_given?
|
73
76
|
|
74
|
-
|
75
|
-
filters.each { |filter| add_after_filter(filter) } if filters
|
77
|
+
@_after_filters
|
76
78
|
end
|
77
79
|
|
78
|
-
def custom_conditions
|
79
|
-
@
|
80
|
+
def custom_conditions(&block)
|
81
|
+
@_custom_conditions ||= []
|
82
|
+
@_custom_conditions << block if block_given?
|
83
|
+
|
84
|
+
@_custom_conditions
|
80
85
|
end
|
81
86
|
end
|
82
87
|
end
|
83
88
|
|
84
89
|
module Padrino
|
85
|
-
class Filter
|
90
|
+
class Filter # @private
|
86
91
|
attr_reader :block
|
87
92
|
|
88
93
|
def initialize(mode, scoped_controller, options, args, &block)
|
@@ -95,12 +100,12 @@ module Padrino
|
|
95
100
|
when Symbol then request.route_obj && (request.route_obj.named == arg or request.route_obj.named == [@scoped_controller, arg].flatten.join("_").to_sym)
|
96
101
|
else arg === request.path_info
|
97
102
|
end
|
98
|
-
end || @options.any?
|
103
|
+
end || @options.any? do |name, val|
|
99
104
|
case name
|
100
105
|
when :agent then val === request.user_agent
|
101
106
|
else val === request.send(name)
|
102
107
|
end
|
103
|
-
|
108
|
+
end
|
104
109
|
detect ^ !@mode
|
105
110
|
end
|
106
111
|
|
@@ -115,23 +120,20 @@ module Padrino
|
|
115
120
|
end
|
116
121
|
|
117
122
|
##
|
118
|
-
# Padrino provides advanced routing definition support to make routes and
|
119
|
-
# This routing system supports named route
|
120
|
-
#
|
121
|
-
#
|
122
|
-
#
|
123
|
+
# Padrino provides advanced routing definition support to make routes and
|
124
|
+
# url generation much easier. This routing system supports named route
|
125
|
+
# aliases and easy access to url paths. The benefits of this is that instead
|
126
|
+
# of having to hard-code route urls into every area of your application, now
|
127
|
+
# we can just define the urls in a single spot and then attach an alias
|
128
|
+
# which can be used to refer to the url throughout the application.
|
123
129
|
#
|
124
130
|
module Routing
|
125
131
|
CONTENT_TYPE_ALIASES = { :htm => :html } unless defined?(CONTENT_TYPE_ALIASES)
|
126
132
|
ROUTE_PRIORITY = {:high => 0, :normal => 1, :low => 2} unless defined?(ROUTE_PRIORITY)
|
127
133
|
|
128
|
-
class UnrecognizedException < RuntimeError
|
129
|
-
end
|
134
|
+
class UnrecognizedException < RuntimeError; end
|
130
135
|
|
131
|
-
|
132
|
-
# Keeps information about parent scope.
|
133
|
-
#
|
134
|
-
class Parent < String
|
136
|
+
class Parent < String # @private
|
135
137
|
attr_reader :map
|
136
138
|
attr_reader :optional
|
137
139
|
attr_reader :options
|
@@ -146,10 +148,10 @@ module Padrino
|
|
146
148
|
end
|
147
149
|
end
|
148
150
|
|
149
|
-
##
|
150
|
-
# Main class that register this extension
|
151
|
-
#
|
152
151
|
class << self
|
152
|
+
##
|
153
|
+
# Main class that register this extension.
|
154
|
+
#
|
153
155
|
def registered(app)
|
154
156
|
app.send(:include, InstanceMethods)
|
155
157
|
app.extend(ClassMethods)
|
@@ -159,40 +161,38 @@ module Padrino
|
|
159
161
|
|
160
162
|
module ClassMethods
|
161
163
|
##
|
162
|
-
# Method for organize in a better way our routes
|
164
|
+
# Method for organize in a better way our routes.
|
165
|
+
#
|
166
|
+
# @param [Array] args
|
167
|
+
# Controller arguments.
|
168
|
+
#
|
169
|
+
# @yield []
|
170
|
+
# The given block will be used to define the routes within the
|
171
|
+
# Controller.
|
163
172
|
#
|
173
|
+
# @example
|
164
174
|
# controller :admin do
|
165
175
|
# get :index do; ...; end
|
166
176
|
# get :show, :with => :id do; ...; end
|
167
177
|
# end
|
168
178
|
#
|
169
|
-
# Now you can call your actions with:
|
170
|
-
#
|
171
179
|
# url(:admin_index) # => "/admin"
|
172
180
|
# url(:admin_show, :id => 1) # "/admin/show/1"
|
173
181
|
#
|
174
|
-
#
|
175
|
-
#
|
182
|
+
# @example Using named routes follow the sinatra way:
|
176
183
|
# controller "/admin" do
|
177
184
|
# get "/index" do; ...; end
|
178
185
|
# get "/show/:id" do; ...; end
|
179
186
|
# end
|
180
187
|
#
|
181
|
-
#
|
182
|
-
#
|
183
|
-
# # => "/admin"
|
184
|
-
# # => "/admin/show/1"
|
185
|
-
#
|
186
|
-
# You can supply provides to all controller routes:
|
187
|
-
#
|
188
|
+
# @example Supply +:provides+ to all controller routes:
|
188
189
|
# controller :provides => [:html, :xml, :json] do
|
189
190
|
# get :index do; "respond to html, xml and json"; end
|
190
191
|
# post :index do; "respond to html, xml and json"; end
|
191
192
|
# get :foo do; "respond to html, xml and json"; end
|
192
193
|
# end
|
193
194
|
#
|
194
|
-
#
|
195
|
-
#
|
195
|
+
# @example Specify parent resources in padrino with the +:parent+ option on the controller:
|
196
196
|
# controllers :product, :parent => :user do
|
197
197
|
# get :index do
|
198
198
|
# # url is generated as "/user/#{params[:user_id]}/product"
|
@@ -204,8 +204,7 @@ module Padrino
|
|
204
204
|
# end
|
205
205
|
# end
|
206
206
|
#
|
207
|
-
#
|
208
|
-
#
|
207
|
+
# @example Specify conditions to run for all routes:
|
209
208
|
# controller :conditions => {:protect => true} do
|
210
209
|
# def self.protect(protected)
|
211
210
|
# condition do
|
@@ -228,8 +227,7 @@ module Padrino
|
|
228
227
|
# end
|
229
228
|
# end
|
230
229
|
#
|
231
|
-
#
|
232
|
-
#
|
230
|
+
# @example Supply default values:
|
233
231
|
# controller :lang => :de do
|
234
232
|
# get :index, :map => "/:lang" do; "params[:lang] == :de"; end
|
235
233
|
# end
|
@@ -237,6 +235,7 @@ module Padrino
|
|
237
235
|
# In a controller before and after filters are scoped and didn't affect other controllers or main app.
|
238
236
|
# In a controller layout are scoped and didn't affect others controllers and main app.
|
239
237
|
#
|
238
|
+
# @example
|
240
239
|
# controller :posts do
|
241
240
|
# layout :post
|
242
241
|
# before { foo }
|
@@ -277,14 +276,69 @@ module Padrino
|
|
277
276
|
end
|
278
277
|
alias :controllers :controller
|
279
278
|
|
279
|
+
##
|
280
|
+
# Add a before filter hook
|
281
|
+
#
|
282
|
+
# @see #construct_filter
|
283
|
+
#
|
280
284
|
def before(*args, &block)
|
281
285
|
add_filter :before, &(args.empty? ? block : construct_filter(*args, &block))
|
282
286
|
end
|
283
287
|
|
288
|
+
##
|
289
|
+
# Add an after filter hook
|
290
|
+
#
|
291
|
+
# @see #construct_filter
|
292
|
+
#
|
284
293
|
def after(*args, &block)
|
285
294
|
add_filter :after, &(args.empty? ? block : construct_filter(*args, &block))
|
286
295
|
end
|
287
296
|
|
297
|
+
def add_filter(type, &block)
|
298
|
+
filters[type] << block
|
299
|
+
end
|
300
|
+
|
301
|
+
##
|
302
|
+
# Creates a filter to process before/after the matching route.
|
303
|
+
#
|
304
|
+
# @param [Array] args
|
305
|
+
#
|
306
|
+
# @example We are be able to filter with String path
|
307
|
+
# before('/') { 'only to :index' }
|
308
|
+
# get(:index} { 'foo' } # => filter match only before this.
|
309
|
+
# get(:main) { 'bar' }
|
310
|
+
#
|
311
|
+
# @example is the same of
|
312
|
+
# before(:index) { 'only to :index' }
|
313
|
+
# get(:index} { 'foo' } # => filter match only before this.
|
314
|
+
# get(:main) { 'bar' }
|
315
|
+
#
|
316
|
+
# @example it works only for the given controller
|
317
|
+
# controller :foo do
|
318
|
+
# before(:index) { 'only to for :foo_index' }
|
319
|
+
# get(:index} { 'foo' } # => filter match only before this.
|
320
|
+
# get(:main) { 'bar' }
|
321
|
+
# end
|
322
|
+
#
|
323
|
+
# controller :bar do
|
324
|
+
# before(:index) { 'only to for :bar_index' }
|
325
|
+
# get(:index} { 'foo' } # => filter match only before this.
|
326
|
+
# get(:main) { 'bar' }
|
327
|
+
# end
|
328
|
+
#
|
329
|
+
# @example if filters based on a symbol or regexp
|
330
|
+
# before :index, /main/ do; ... end
|
331
|
+
# # => match oly path that are +/+ or contains +main+
|
332
|
+
#
|
333
|
+
# @example filtering everything except an occurency
|
334
|
+
# before :except => :index do; ...; end
|
335
|
+
#
|
336
|
+
# @example you can also filter using a request param
|
337
|
+
# before :agent => /IE/ do; ...; end
|
338
|
+
# # => match +HTTP_USER_AGENT+ containing +IE+
|
339
|
+
#
|
340
|
+
# @see http://www.padrinorb.com/guides/controllers#route-filters
|
341
|
+
#
|
288
342
|
def construct_filter(*args, &block)
|
289
343
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
290
344
|
except = options.key?(:except) && Array(options.delete(:except))
|
@@ -296,8 +350,13 @@ module Padrino
|
|
296
350
|
##
|
297
351
|
# Provides many parents with shallowing.
|
298
352
|
#
|
299
|
-
#
|
353
|
+
# @param [Symbol] name
|
354
|
+
# The parent name.
|
355
|
+
#
|
356
|
+
# @param [Hash] options
|
357
|
+
# Additional options.
|
300
358
|
#
|
359
|
+
# @example
|
301
360
|
# controllers :product do
|
302
361
|
# parent :shop, :optional => true, :map => "/my/stand"
|
303
362
|
# parent :category, :optional => true
|
@@ -320,13 +379,14 @@ module Padrino
|
|
320
379
|
end
|
321
380
|
|
322
381
|
##
|
323
|
-
# Using
|
324
|
-
#
|
325
|
-
# ==== Examples
|
382
|
+
# Using {HttpRouter}, for features and configurations.
|
326
383
|
#
|
384
|
+
# @example
|
327
385
|
# router.add('/greedy/:greed')
|
328
386
|
# router.recognize('/simple')
|
329
387
|
#
|
388
|
+
# @see http://github.com/joshbuddy/http_router
|
389
|
+
#
|
330
390
|
def router
|
331
391
|
@router ||= HttpRouter.new
|
332
392
|
block_given? ? yield(@router) : @router
|
@@ -352,19 +412,42 @@ module Padrino
|
|
352
412
|
router.reset!
|
353
413
|
end
|
354
414
|
|
415
|
+
##
|
416
|
+
# Recognize a given path
|
417
|
+
#
|
418
|
+
# @param [String] path
|
419
|
+
# Path+Query to parse
|
420
|
+
#
|
421
|
+
# @return [Symbol, Hash]
|
422
|
+
# Returns controller and query params.
|
423
|
+
#
|
424
|
+
# @example Giving a controller like:
|
425
|
+
# controller :foo do
|
426
|
+
# get :bar, :map => 'foo-bar-:id'; ...; end
|
427
|
+
# end
|
428
|
+
#
|
429
|
+
# @example You should be able to reverse:
|
430
|
+
# MyApp.url(:foo_bar, :id => :mine)
|
431
|
+
# # => /foo-bar-mine
|
432
|
+
#
|
433
|
+
# @example Into this:
|
434
|
+
# MyApp.recognize_path('foo-bar-mine')
|
435
|
+
# # => [:foo_bar, :id => :mine]
|
436
|
+
#
|
355
437
|
def recognize_path(path)
|
356
438
|
responses = @router.recognize(Rack::MockRequest.env_for(path))
|
357
439
|
[responses[0].path.route.named, responses[0].params]
|
358
440
|
end
|
359
441
|
|
360
442
|
##
|
361
|
-
# Instance method for url generation
|
362
|
-
#
|
363
|
-
# ==== Examples
|
443
|
+
# Instance method for url generation.
|
364
444
|
#
|
445
|
+
# @example
|
365
446
|
# url(:show, :id => 1)
|
366
447
|
# url(:show, :name => 'test', :id => 24)
|
367
448
|
# url(:show, 1)
|
449
|
+
# url(:controller_name, :show, :id => 21)
|
450
|
+
# url(:controller_show, :id => 29)
|
368
451
|
#
|
369
452
|
def url(*args)
|
370
453
|
params = args.extract_options! # parameters is hash at end
|
@@ -389,7 +472,7 @@ module Padrino
|
|
389
472
|
end
|
390
473
|
alias :url_for :url
|
391
474
|
|
392
|
-
def get(path, *args, &block)
|
475
|
+
def get(path, *args, &block) # @private
|
393
476
|
conditions = @conditions.dup
|
394
477
|
route('GET', path, *args, &block)
|
395
478
|
|
@@ -397,8 +480,11 @@ module Padrino
|
|
397
480
|
route('HEAD', path, *args, &block)
|
398
481
|
end
|
399
482
|
|
483
|
+
##
|
484
|
+
# Returns the lat controller, useful inside a layout/view.
|
485
|
+
#
|
400
486
|
def current_controller
|
401
|
-
@_controller
|
487
|
+
@_controller and @_controller[-1]
|
402
488
|
end
|
403
489
|
|
404
490
|
private
|
@@ -424,10 +510,9 @@ module Padrino
|
|
424
510
|
end
|
425
511
|
|
426
512
|
##
|
427
|
-
# Rewrite default
|
428
|
-
#
|
429
|
-
# ==== Examples
|
513
|
+
# Rewrite default routes.
|
430
514
|
#
|
515
|
+
# @example
|
431
516
|
# get :index # => "/"
|
432
517
|
# get :index, "/" # => "/"
|
433
518
|
# get :index, :map => "/" # => "/"
|
@@ -471,20 +556,16 @@ module Padrino
|
|
471
556
|
|
472
557
|
# Sinatra defaults
|
473
558
|
method_name = "#{verb} #{path}"
|
474
|
-
|
475
|
-
unbound_method = instance_method("#{verb} #{path}")
|
476
|
-
remove_method(method_name)
|
559
|
+
unbound_method = generate_method(method_name, &block)
|
477
560
|
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
proc { unbound_method.bind(self).call }
|
561
|
+
block = block.arity != 0 ?
|
562
|
+
proc { |a,p| unbound_method.bind(a).call(*p) } :
|
563
|
+
proc { |a,p| unbound_method.bind(a).call }
|
482
564
|
|
483
565
|
invoke_hook(:route_added, verb, path, block)
|
484
566
|
|
485
567
|
# HTTPRouter route construction
|
486
568
|
route = router.add(path)
|
487
|
-
|
488
569
|
route.name(name) if name
|
489
570
|
priority_name = options.delete(:priority) || :normal
|
490
571
|
priority = ROUTE_PRIORITY[priority_name] or raise("Priority #{priority_name} not recognized, try #{ROUTE_PRIORITY.keys.join(', ')}")
|
@@ -506,27 +587,28 @@ module Padrino
|
|
506
587
|
# Add Sinatra conditions
|
507
588
|
options.each { |o, a| route.respond_to?(o) ? route.send(o, *a) : send(o, *a) }
|
508
589
|
conditions, @conditions = @conditions, []
|
509
|
-
route.custom_conditions
|
590
|
+
route.custom_conditions.concat(conditions)
|
510
591
|
|
511
592
|
invoke_hook(:padrino_route_added, route, verb, path, args, options, block)
|
512
593
|
|
513
594
|
# Add Application defaults
|
514
|
-
route.before_filters
|
515
|
-
route.after_filters
|
595
|
+
route.before_filters.concat(@filters[:before])
|
596
|
+
route.after_filters.concat(@filters[:after])
|
516
597
|
if @_controller
|
517
598
|
route.use_layout = @layout
|
518
|
-
route.controller = Array(@_controller).
|
599
|
+
route.controller = Array(@_controller)[0].to_s
|
519
600
|
end
|
520
601
|
|
521
602
|
deferred_routes[priority] << [route, block]
|
603
|
+
|
522
604
|
route
|
523
605
|
end
|
524
606
|
|
525
607
|
##
|
526
|
-
# Returns the final parsed route details (modified to reflect all
|
527
|
-
# given the raw route. Raw route passed in could be
|
528
|
-
# is parsed to reflect provides formats,
|
529
|
-
# and other options.
|
608
|
+
# Returns the final parsed route details (modified to reflect all
|
609
|
+
# Padrino options) given the raw route. Raw route passed in could be
|
610
|
+
# a named alias or a string and is parsed to reflect provides formats,
|
611
|
+
# controllers, parents, 'with' parameters, and other options.
|
530
612
|
#
|
531
613
|
def parse_route(path, options, verb)
|
532
614
|
# We need save our originals path/options so we can perform correctly cache.
|
@@ -584,11 +666,11 @@ module Padrino
|
|
584
666
|
path = "#{@_map}/#{path}".squeeze('/') unless absolute_map or @_map.blank?
|
585
667
|
|
586
668
|
# Small reformats
|
587
|
-
path.gsub!(%r{/\?$}, '(/)')
|
588
|
-
path.gsub!(%r{//$}, '/')
|
589
|
-
path[0,0] = "/"
|
590
|
-
path.sub!(%r{/(\))?$}, '\\1') if path != "/"
|
591
|
-
path.gsub!(/\/(\(\.|$)/, '\\1')
|
669
|
+
path.gsub!(%r{/\?$}, '(/)') # Remove index path
|
670
|
+
path.gsub!(%r{//$}, '/') # Remove index path
|
671
|
+
path[0,0] = "/" if path !~ %r{^\(?/} # Paths must start with a /
|
672
|
+
path.sub!(%r{/(\))?$}, '\\1') if path != "/" # Remove latest trailing delimiter
|
673
|
+
path.gsub!(/\/(\(\.|$)/, '\\1') # Remove trailing slashes
|
592
674
|
path.squeeze!('/')
|
593
675
|
end
|
594
676
|
|
@@ -600,7 +682,7 @@ module Padrino
|
|
600
682
|
|
601
683
|
##
|
602
684
|
# Processes the existing path and appends the 'with' parameters onto the route
|
603
|
-
# Used for calculating path in route method
|
685
|
+
# Used for calculating path in route method.
|
604
686
|
#
|
605
687
|
def process_path_for_with_params(path, with_params)
|
606
688
|
File.join(path, Array(with_params).map(&:inspect).join("/"))
|
@@ -608,7 +690,7 @@ module Padrino
|
|
608
690
|
|
609
691
|
##
|
610
692
|
# Processes the existing path and prepends the 'parent' parameters onto the route
|
611
|
-
# Used for calculating path in route method
|
693
|
+
# Used for calculating path in route method.
|
612
694
|
#
|
613
695
|
def process_path_for_parent_params(path, parent_params)
|
614
696
|
parent_prefix = parent_params.flatten.compact.uniq.map do |param|
|
@@ -617,12 +699,13 @@ module Padrino
|
|
617
699
|
part = "(#{part})" if param.respond_to?(:optional) && param.optional?
|
618
700
|
part
|
619
701
|
end
|
702
|
+
|
620
703
|
[parent_prefix, path].flatten.join("")
|
621
704
|
end
|
622
705
|
|
623
706
|
##
|
624
707
|
# Processes the existing path and appends the 'format' suffix onto the route
|
625
|
-
# Used for calculating path in route method
|
708
|
+
# Used for calculating path in route method.
|
626
709
|
#
|
627
710
|
def process_path_for_provides(path, format_params)
|
628
711
|
path << "(.:format)" unless path[-10, 10] == '(.:format)'
|
@@ -641,19 +724,19 @@ module Padrino
|
|
641
724
|
# If no type is specified, the first in the provides-list will be
|
642
725
|
# returned.
|
643
726
|
#
|
644
|
-
#
|
727
|
+
# @example
|
645
728
|
# get "/a", :provides => [:html, :js]
|
646
|
-
#
|
647
|
-
#
|
648
|
-
#
|
729
|
+
# # => GET /a => :html
|
730
|
+
# # => GET /a.js => :js
|
731
|
+
# # => GET /a.xml => 404
|
649
732
|
#
|
650
733
|
# get "/b", :provides => [:html]
|
651
|
-
#
|
652
|
-
#
|
734
|
+
# # => GET /b; ACCEPT: html => html
|
735
|
+
# # => GET /b; ACCEPT: js => 406
|
653
736
|
#
|
654
737
|
# enable :treat_format_as_accept
|
655
738
|
# get "/c", :provides => [:html, :js]
|
656
|
-
#
|
739
|
+
# # => GET /c.xml => 406
|
657
740
|
#
|
658
741
|
def provides(*types)
|
659
742
|
@_use_format = true
|
@@ -699,26 +782,28 @@ module Padrino
|
|
699
782
|
|
700
783
|
module InstanceMethods
|
701
784
|
##
|
702
|
-
# Instance method for url generation
|
703
|
-
#
|
704
|
-
# ==== Examples
|
785
|
+
# Instance method for url generation.
|
705
786
|
#
|
787
|
+
# @example
|
706
788
|
# url(:show, :id => 1)
|
707
789
|
# url(:show, :name => :test)
|
708
790
|
# url(:show, 1)
|
709
791
|
# url("/foo")
|
710
792
|
#
|
793
|
+
# @see Padrino::Routing::ClassMethods#url
|
794
|
+
#
|
711
795
|
def url(*args)
|
712
796
|
# Delegate to Sinatra 1.2 for simple url("/foo")
|
713
797
|
# http://www.sinatrarb.com/intro#Generating%20URLs
|
714
798
|
return super if args.first.is_a?(String) && !args[1].is_a?(Hash)
|
799
|
+
|
715
800
|
# Delegate to Padrino named route url generation
|
716
|
-
|
801
|
+
settings.url(*args)
|
717
802
|
end
|
718
803
|
alias :url_for :url
|
719
804
|
|
720
805
|
def recognize_path(path)
|
721
|
-
|
806
|
+
settings.recognize_path(path)
|
722
807
|
end
|
723
808
|
|
724
809
|
def current_path(*path_params)
|
@@ -732,19 +817,18 @@ module Padrino
|
|
732
817
|
|
733
818
|
##
|
734
819
|
# This is mostly just a helper so request.path_info isn't changed when
|
735
|
-
# serving files from the public directory
|
820
|
+
# serving files from the public directory.
|
736
821
|
#
|
737
822
|
def static_file?(path_info)
|
738
|
-
return if (public_dir = settings.
|
823
|
+
return if (public_dir = settings.public_folder).nil?
|
739
824
|
public_dir = File.expand_path(public_dir)
|
740
|
-
|
741
825
|
path = File.expand_path(public_dir + unescape(path_info))
|
742
826
|
return if path[0, public_dir.length] != public_dir
|
743
827
|
return unless File.file?(path)
|
744
828
|
return path
|
745
829
|
end
|
746
830
|
|
747
|
-
|
831
|
+
#
|
748
832
|
# Method for deliver static files.
|
749
833
|
#
|
750
834
|
def static!
|
@@ -755,10 +839,14 @@ module Padrino
|
|
755
839
|
end
|
756
840
|
|
757
841
|
##
|
758
|
-
# Return the request format, this is useful when we need to respond to
|
842
|
+
# Return the request format, this is useful when we need to respond to
|
843
|
+
# a given Content-Type.
|
844
|
+
#
|
845
|
+
# @param [Symbol, nil] type
|
759
846
|
#
|
760
|
-
#
|
847
|
+
# @param [Hash] params
|
761
848
|
#
|
849
|
+
# @example
|
762
850
|
# get :index, :provides => :any do
|
763
851
|
# case content_type
|
764
852
|
# when :js then ...
|
@@ -776,20 +864,21 @@ module Padrino
|
|
776
864
|
end
|
777
865
|
|
778
866
|
private
|
867
|
+
def filter!(type, base=settings)
|
868
|
+
base.filters[type].each { |block| instance_eval(&block) }
|
869
|
+
end
|
870
|
+
|
779
871
|
def dispatch!
|
780
872
|
static! if settings.static? && (request.get? || request.head?)
|
781
873
|
route!
|
782
|
-
rescue Sinatra::NotFound => boom
|
783
|
-
filter! :before
|
784
|
-
handle_not_found!(boom)
|
785
874
|
rescue ::Exception => boom
|
786
875
|
filter! :before
|
787
876
|
handle_exception!(boom)
|
788
877
|
ensure
|
789
|
-
|
878
|
+
filter! :after unless env['sinatra.static_file']
|
790
879
|
end
|
791
880
|
|
792
|
-
def route!(base=
|
881
|
+
def route!(base=settings, pass_block=nil)
|
793
882
|
Thread.current['padrino.instance'] = self
|
794
883
|
if base.compiled_router and match = base.compiled_router.call(@request.env)
|
795
884
|
if match.respond_to?(:each)
|
@@ -812,7 +901,6 @@ module Padrino
|
|
812
901
|
route_eval(&pass_block) if pass_block
|
813
902
|
|
814
903
|
route_missing
|
815
|
-
ensure
|
816
904
|
end
|
817
905
|
end # InstanceMethods
|
818
906
|
end # Routing
|