padrino-core 0.10.2 → 0.10.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/.document +3 -3
  2. data/.yardopts +1 -0
  3. data/{LICENSE → LICENSE.txt} +0 -0
  4. data/README.rdoc +2 -2
  5. data/lib/padrino-core/application/rendering.rb +79 -26
  6. data/lib/padrino-core/application/routing.rb +215 -127
  7. data/lib/padrino-core/application/showexceptions.rb +2 -1
  8. data/lib/padrino-core/application.rb +67 -57
  9. data/lib/padrino-core/caller.rb +10 -4
  10. data/lib/padrino-core/command.rb +11 -0
  11. data/lib/padrino-core/loader.rb +52 -24
  12. data/lib/padrino-core/locale/cs.yml +4 -1
  13. data/lib/padrino-core/locale/da.yml +4 -1
  14. data/lib/padrino-core/locale/de.yml +4 -1
  15. data/lib/padrino-core/locale/en.yml +4 -1
  16. data/lib/padrino-core/locale/es.yml +4 -1
  17. data/lib/padrino-core/locale/fr.yml +4 -1
  18. data/lib/padrino-core/locale/hu.yml +4 -1
  19. data/lib/padrino-core/locale/it.yml +4 -1
  20. data/lib/padrino-core/locale/ja.yml +4 -1
  21. data/lib/padrino-core/locale/lv.yml +34 -0
  22. data/lib/padrino-core/locale/nl.yml +4 -1
  23. data/lib/padrino-core/locale/no.yml +4 -1
  24. data/lib/padrino-core/locale/pl.yml +4 -1
  25. data/lib/padrino-core/locale/pt_br.yml +4 -1
  26. data/lib/padrino-core/locale/ru.yml +4 -1
  27. data/lib/padrino-core/locale/tr.yml +4 -1
  28. data/lib/padrino-core/locale/uk.yml +4 -1
  29. data/lib/padrino-core/locale/zh_cn.yml +4 -1
  30. data/lib/padrino-core/locale/zh_tw.yml +4 -1
  31. data/lib/padrino-core/logger.rb +119 -128
  32. data/lib/padrino-core/mounter.rb +46 -14
  33. data/lib/padrino-core/reloader.rb +5 -3
  34. data/lib/padrino-core/router.rb +30 -11
  35. data/lib/padrino-core/server.rb +14 -5
  36. data/lib/padrino-core/support_lite.rb +54 -20
  37. data/lib/padrino-core/tasks.rb +1 -3
  38. data/lib/padrino-core/version.rb +8 -4
  39. data/lib/padrino-core.rb +58 -11
  40. data/padrino-core.gemspec +1 -1
  41. data/test/fixtures/apps/simple.rb +1 -1
  42. data/test/helper.rb +4 -24
  43. data/test/mini_shoulda.rb +45 -0
  44. data/test/test_application.rb +19 -18
  45. data/test/test_core.rb +2 -2
  46. data/test/test_dependencies.rb +5 -5
  47. data/test/test_filters.rb +2 -1
  48. data/test/test_locale.rb +1 -1
  49. data/test/test_logger.rb +1 -1
  50. data/test/test_mounter.rb +26 -25
  51. data/test/test_reloader_complex.rb +5 -3
  52. data/test/test_reloader_simple.rb +6 -5
  53. data/test/test_rendering.rb +8 -5
  54. data/test/test_restful_routing.rb +1 -1
  55. data/test/test_router.rb +1 -1
  56. data/test/test_routing.rb +33 -12
  57. 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
- class Sinatra::Request # @private
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
- class HttpRouter # @private
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
- old_params = @params
34
- parent_layout = @layout
35
- successful = false
42
+ original_params = @params
43
+ parent_layout = @layout
44
+ successful = false
36
45
  begin
37
46
  filter! :before
38
- (path.route.before_filters - self.class.filters[:before]).each { |filter| instance_eval(&filter)} if path.route.before_filters
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 = path.route
42
- @route.custom_conditions.each { |blk| pass if instance_eval(&blk) == false } if @route.custom_conditions
43
- @block_params = @block_params.slice(0, path.route.dest.arity) if path.route.dest.arity > 0
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 = true
47
- halt @_response_buffer
53
+ successful = true
54
+ halt halt_response
48
55
  ensure
49
- (@_pending_after_filters ||= []).concat(path.route.after_filters) if path.route.after_filters && successful
56
+ (@route.after_filters - settings.filters[:after]).each { |block| instance_eval(&block) } if successful
50
57
  @layout = parent_layout
51
- @params = old_params
58
+ @params = original_params
52
59
  end
53
60
  end
54
61
  end
55
62
 
56
- class Route # @private
57
- attr_reader :before_filters, :after_filters
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 add_before_filter(filter)
61
- @before_filters ||= []
62
- @before_filters << filter
63
- end
66
+ def before_filters(&block)
67
+ @_before_filters ||= []
68
+ @_before_filters << block if block_given?
64
69
 
65
- def add_after_filter(filter)
66
- @after_filters ||= []
67
- @after_filters << filter
70
+ @_before_filters
68
71
  end
69
72
 
70
- def before_filters=(filters)
71
- filters.each { |filter| add_before_filter(filter) } if filters
72
- end
73
+ def after_filters(&block)
74
+ @_after_filters ||= []
75
+ @_after_filters << block if block_given?
73
76
 
74
- def after_filters=(filters)
75
- filters.each { |filter| add_after_filter(filter) } if filters
77
+ @_after_filters
76
78
  end
77
79
 
78
- def custom_conditions=(custom_conditions)
79
- @custom_conditions = custom_conditions
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? { |name, val|
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 url generation much easier.
119
- # This routing system supports named route aliases and easy access to url paths.
120
- # The benefits of this is that instead of having to hard-code route urls into every area of your application,
121
- # now we can just define the urls in a single spot and then attach an alias which can be used to refer
122
- # to the url throughout the application.
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 # @private
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 like:
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
- # You can instead using named routes follow the sinatra way like:
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
- # and you can call directly these urls:
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
- # You can specify parent resources in padrino with the :parent option on the controller:
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
- # You can specify conditions to run for all routes:
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
- # You can supply default values:
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
- # ==== Examples
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 HTTPRouter, for features and configurations see: http://github.com/joshbuddy/http_router
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 like:
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 && @_controller.last
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 because now routes can be:
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
- define_method(method_name, &block)
475
- unbound_method = instance_method("#{verb} #{path}")
476
- remove_method(method_name)
559
+ unbound_method = generate_method(method_name, &block)
477
560
 
478
- block_arity = block.arity
479
- block = block_arity != 0 ?
480
- proc { @block_params = @block_params[0, block_arity]; unbound_method.bind(self).call(*@block_params) } :
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 = 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 = @filters[:before]
515
- route.after_filters = @filters[:after]
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).first.to_s
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 Padrino options)
527
- # given the raw route. Raw route passed in could be a named alias or a string and
528
- # is parsed to reflect provides formats, controllers, parents, 'with' parameters,
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{/\?$}, '(/)') # Remove index path
588
- path.gsub!(%r{//$}, '/') # Remove index path
589
- path[0,0] = "/" unless path =~ %r{^\(?/} # Paths must start with a /
590
- path.sub!(%r{/(\))?$}, '\\1') if path != "/" # Remove latest trailing delimiter
591
- path.gsub!(/\/(\(\.|$)/, '\\1') # Remove trailing slashes
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
- # ==== Examples
727
+ # @example
645
728
  # get "/a", :provides => [:html, :js]
646
- # # => GET /a => :html
647
- # # => GET /a.js => :js
648
- # # => GET /a.xml => 404
729
+ # # => GET /a => :html
730
+ # # => GET /a.js => :js
731
+ # # => GET /a.xml => 404
649
732
  #
650
733
  # get "/b", :provides => [:html]
651
- # # => GET /b; ACCEPT: html => html
652
- # # => GET /b; ACCEPT: js => 406
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
- # # => GET /c.xml => 406
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 like:
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
- self.class.url(*args)
801
+ settings.url(*args)
717
802
  end
718
803
  alias :url_for :url
719
804
 
720
805
  def recognize_path(path)
721
- self.class.recognize_path(path)
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.public).nil?
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 a given content_type like:
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
- # ==== Examples
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
- @_pending_after_filters.each { |filter| instance_eval(&filter)} if @_pending_after_filters
878
+ filter! :after unless env['sinatra.static_file']
790
879
  end
791
880
 
792
- def route!(base=self.class, pass_block=nil)
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