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.
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