roda 2.28.0 → 2.29.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +46 -0
  3. data/README.rdoc +25 -7
  4. data/doc/release_notes/2.29.0.txt +156 -0
  5. data/lib/roda.rb +25 -3
  6. data/lib/roda/plugins/_erubis_escaping.rb +2 -0
  7. data/lib/roda/plugins/_symbol_regexp_matchers.rb +22 -0
  8. data/lib/roda/plugins/assets.rb +3 -2
  9. data/lib/roda/plugins/branch_locals.rb +74 -0
  10. data/lib/roda/plugins/caching.rb +15 -7
  11. data/lib/roda/plugins/chunked.rb +10 -7
  12. data/lib/roda/plugins/content_for.rb +4 -1
  13. data/lib/roda/plugins/drop_body.rb +3 -2
  14. data/lib/roda/plugins/error_email.rb +3 -2
  15. data/lib/roda/plugins/error_mail.rb +3 -2
  16. data/lib/roda/plugins/head.rb +2 -1
  17. data/lib/roda/plugins/header_matchers.rb +3 -0
  18. data/lib/roda/plugins/heartbeat.rb +3 -2
  19. data/lib/roda/plugins/json.rb +5 -3
  20. data/lib/roda/plugins/json_parser.rb +3 -2
  21. data/lib/roda/plugins/mailer.rb +3 -3
  22. data/lib/roda/plugins/match_affix.rb +6 -0
  23. data/lib/roda/plugins/multi_route.rb +3 -1
  24. data/lib/roda/plugins/padrino_render.rb +3 -2
  25. data/lib/roda/plugins/params_capturing.rb +3 -3
  26. data/lib/roda/plugins/partials.rb +3 -3
  27. data/lib/roda/plugins/path.rb +4 -2
  28. data/lib/roda/plugins/path_rewriter.rb +2 -2
  29. data/lib/roda/plugins/per_thread_caching.rb +2 -0
  30. data/lib/roda/plugins/placeholder_string_matchers.rb +42 -0
  31. data/lib/roda/plugins/precompile_templates.rb +3 -2
  32. data/lib/roda/plugins/render.rb +86 -37
  33. data/lib/roda/plugins/render_each.rb +2 -1
  34. data/lib/roda/plugins/render_locals.rb +102 -0
  35. data/lib/roda/plugins/run_append_slash.rb +2 -1
  36. data/lib/roda/plugins/run_handler.rb +2 -1
  37. data/lib/roda/plugins/sinatra_helpers.rb +4 -4
  38. data/lib/roda/plugins/static_path_info.rb +2 -0
  39. data/lib/roda/plugins/static_routing.rb +1 -1
  40. data/lib/roda/plugins/streaming.rb +9 -4
  41. data/lib/roda/plugins/symbol_matchers.rb +23 -20
  42. data/lib/roda/plugins/view_options.rb +63 -28
  43. data/lib/roda/plugins/view_subdirs.rb +1 -0
  44. data/lib/roda/plugins/websockets.rb +2 -0
  45. data/lib/roda/version.rb +1 -1
  46. data/spec/composition_spec.rb +2 -2
  47. data/spec/matchers_spec.rb +6 -5
  48. data/spec/plugin/_erubis_escaping_spec.rb +5 -5
  49. data/spec/plugin/backtracking_array_spec.rb +0 -2
  50. data/spec/plugin/branch_locals_spec.rb +88 -0
  51. data/spec/plugin/content_for_spec.rb +8 -2
  52. data/spec/plugin/halt_spec.rb +8 -0
  53. data/spec/plugin/header_matchers_spec.rb +20 -5
  54. data/spec/plugin/multi_route_spec.rb +1 -1
  55. data/spec/plugin/named_templates_spec.rb +2 -2
  56. data/spec/plugin/params_capturing_spec.rb +1 -1
  57. data/spec/plugin/per_thread_caching_spec.rb +1 -1
  58. data/spec/plugin/placeholder_string_matchers_spec.rb +159 -0
  59. data/spec/plugin/render_locals_spec.rb +114 -0
  60. data/spec/plugin/render_spec.rb +83 -8
  61. data/spec/plugin/streaming_spec.rb +104 -4
  62. data/spec/plugin/symbol_matchers_spec.rb +1 -1
  63. data/spec/plugin/view_options_spec.rb +83 -7
  64. data/spec/plugin/websockets_spec.rb +7 -8
  65. data/spec/spec_helper.rb +22 -2
  66. metadata +11 -2
@@ -70,6 +70,7 @@ class Roda
70
70
  # OTHER DEALINGS IN THE SOFTWARE.
71
71
  module Caching
72
72
  OPTS = {}.freeze
73
+ RodaPlugins.deprecate_constant(self, :OPTS)
73
74
 
74
75
  module RequestMethods
75
76
  LAST_MODIFIED = 'Last-Modified'.freeze
@@ -130,7 +131,7 @@ class Roda
130
131
  #
131
132
  # When the current request includes an If-Match header with a
132
133
  # etag that doesn't match, immediately returns a response with a 412 status.
133
- def etag(value, opts=OPTS)
134
+ def etag(value, opts=RodaPlugins::OPTS)
134
135
  # Before touching this code, please double check RFC 2616 14.24 and 14.26.
135
136
  weak = opts[:weak]
136
137
  new_resource = opts.fetch(:new_resource){post?}
@@ -174,12 +175,19 @@ class Roda
174
175
 
175
176
  module ResponseMethods
176
177
  UNDERSCORE = '_'.freeze
178
+ RodaPlugins.deprecate_constant(self, :UNDERSCORE)
177
179
  DASH = '-'.freeze
180
+ RodaPlugins.deprecate_constant(self, :DASH)
178
181
  COMMA = ', '.freeze
182
+ RodaPlugins.deprecate_constant(self, :COMMA)
179
183
  CACHE_CONTROL = 'Cache-Control'.freeze
184
+ RodaPlugins.deprecate_constant(self, :CACHE_CONTROL)
180
185
  EXPIRES = 'Expires'.freeze
186
+ RodaPlugins.deprecate_constant(self, :EXPIRES)
181
187
  CONTENT_TYPE = 'Content-Type'.freeze
188
+ RodaPlugins.deprecate_constant(self, :CONTENT_TYPE)
182
189
  CONTENT_LENGTH = 'Content-Length'.freeze
190
+ RodaPlugins.deprecate_constant(self, :CONTENT_LENGTH)
183
191
 
184
192
  # Specify response freshness policy for using the Cache-Control header.
185
193
  # Options can can any non-value directives (:public, :private, :no_cache,
@@ -195,20 +203,20 @@ class Roda
195
203
  values = []
196
204
  opts.each do |k, v|
197
205
  next unless v
198
- k = k.to_s.tr(UNDERSCORE, DASH)
206
+ k = k.to_s.tr('_', '-')
199
207
  values << (v == true ? k : "#{k}=#{v}")
200
208
  end
201
209
 
202
- self[CACHE_CONTROL] = values.join(COMMA) unless values.empty?
210
+ self['Cache-Control'] = values.join(', ') unless values.empty?
203
211
  end
204
212
 
205
213
  # Set Cache-Control header with the max_age given. max_age should
206
214
  # be an integer number of seconds that the current request should be
207
215
  # cached for. Also sets the Expires header, useful if you have
208
216
  # HTTP 1.0 clients (Cache-Control is an HTTP 1.1 header).
209
- def expires(max_age, opts=OPTS)
217
+ def expires(max_age, opts=RodaPlugins::OPTS)
210
218
  cache_control(Hash[opts].merge!(:max_age=>max_age))
211
- self[EXPIRES] = (Time.now + max_age).httpdate
219
+ self['Expires'] = (Time.now + max_age).httpdate
212
220
  end
213
221
 
214
222
  # Remove Content-Type and Content-Length for 304 responses.
@@ -216,8 +224,8 @@ class Roda
216
224
  a = super
217
225
  if a[0] == 304
218
226
  h = a[1]
219
- h.delete(CONTENT_TYPE)
220
- h.delete(CONTENT_LENGTH)
227
+ h.delete('Content-Type')
228
+ h.delete('Content-Length')
221
229
  end
222
230
  a
223
231
  end
@@ -146,7 +146,7 @@ class Roda
146
146
  # rotated.
147
147
  module Chunked
148
148
  OPTS = {}.freeze
149
-
149
+ RodaPlugins.deprecate_constant(self, :OPTS)
150
150
  HTTP_VERSION = 'HTTP_VERSION'.freeze
151
151
  RodaPlugins.deprecate_constant(self, :HTTP_VERSION)
152
152
  HTTP11 = "HTTP/1.1".freeze
@@ -157,14 +157,14 @@ class Roda
157
157
  RodaPlugins.deprecate_constant(self, :CHUNKED)
158
158
 
159
159
  # Depend on the render plugin
160
- def self.load_dependencies(app, opts=OPTS)
160
+ def self.load_dependencies(app, opts=RodaPlugins::OPTS)
161
161
  app.plugin :render
162
162
  end
163
163
 
164
164
  # Set plugin specific options. Options:
165
165
  # :chunk_by_default :: chunk all calls to view by default
166
166
  # :headers :: Set default additional headers to use when calling view
167
- def self.configure(app, opts=OPTS)
167
+ def self.configure(app, opts=RodaPlugins::OPTS)
168
168
  app.opts[:chunk_by_default] = opts[:chunk_by_default]
169
169
  if opts[:headers]
170
170
  app.opts[:chunk_headers] = (app.opts[:chunk_headers] || {}).merge(opts[:headers]).freeze
@@ -174,8 +174,11 @@ class Roda
174
174
  # Rack response body instance for chunked responses
175
175
  class Body
176
176
  CHUNK_SIZE = "%x\r\n".freeze
177
+ RodaPlugins.deprecate_constant(self, :CHUNK_SIZE)
177
178
  CRLF = "\r\n".freeze
179
+ RodaPlugins.deprecate_constant(self, :CRLF)
178
180
  FINISH = "0\r\n\r\n".freeze
181
+ RodaPlugins.deprecate_constant(self, :FINISH)
179
182
 
180
183
  # Save the scope of the current request handling.
181
184
  def initialize(scope)
@@ -190,12 +193,12 @@ class Roda
190
193
  def each
191
194
  @scope.each_chunk do |chunk|
192
195
  next if !chunk || chunk.empty?
193
- yield(CHUNK_SIZE % chunk.bytesize)
196
+ yield("%x\r\n" % chunk.bytesize)
194
197
  yield(chunk)
195
- yield(CRLF)
198
+ yield("\r\n")
196
199
  end
197
200
  ensure
198
- yield(FINISH)
201
+ yield("0\r\n\r\n")
199
202
  end
200
203
  end
201
204
 
@@ -218,7 +221,7 @@ class Roda
218
221
 
219
222
  # Render a response to the user in chunks. See Chunked for
220
223
  # an overview. If a block is given, it is passed to #delay.
221
- def chunked(template, opts=OPTS, &block)
224
+ def chunked(template, opts=RodaPlugins::OPTS, &block)
222
225
  unless defined?(@_chunked)
223
226
  @_chunked = env['HTTP_VERSION'] == "HTTP/1.1"
224
227
  end
@@ -44,7 +44,7 @@ class Roda
44
44
  # is called multiple times to set data. Overwrite is default, use
45
45
  # the :append option to append.
46
46
  def self.configure(app, opts = {})
47
- app.opts[:append_content_for] = opts.fetch(:append, false)
47
+ app.opts[:append_content_for] = opts.fetch(:append, nil)
48
48
  end
49
49
 
50
50
  module InstanceMethods
@@ -71,6 +71,9 @@ class Roda
71
71
  if append
72
72
  (@_content_for[key] ||= []) << value
73
73
  else
74
+ if @_content_for[key] && append.nil?
75
+ RodaPlugins.warn "Attempt to set content_for with same key. This currently overwrites the existing content_for for #{key}. In Roda 3, it will start appending to the existing content_for by default. Use the :append => false option to the content_for plugin to keep the existing behavior."
76
+ end
74
77
  @_content_for[key] = value
75
78
  end
76
79
  elsif @_content_for && (value = @_content_for[key])
@@ -11,8 +11,9 @@ class Roda
11
11
  module DropBody
12
12
  module ResponseMethods
13
13
  DROP_BODY_STATUSES = [100, 101, 102, 204, 205, 304].freeze
14
- EMPTY_BODY = [].freeze
15
14
 
15
+ EMPTY_BODY = [].freeze
16
+ RodaPlugins.deprecate_constant(self, :EMPTY_BODY)
16
17
  CONTENT_LENGTH = "Content-Length".freeze
17
18
  RodaPlugins.deprecate_constant(self, :CONTENT_LENGTH)
18
19
  CONTENT_TYPE = "Content-Type".freeze
@@ -24,7 +25,7 @@ class Roda
24
25
  def finish
25
26
  r = super
26
27
  if DROP_BODY_STATUSES.include?(r[0])
27
- r[2] = EMPTY_BODY
28
+ r[2] = EMPTY_ARRAY
28
29
  h = r[1]
29
30
  h.delete("Content-Length")
30
31
  h.delete("Content-Type")
@@ -38,8 +38,9 @@ class Roda
38
38
  # use an error reporting service instead of this plugin.
39
39
  module ErrorEmail
40
40
  OPTS = {}.freeze
41
+ RodaPlugins.deprecate_constant(self, :OPTS)
41
42
  DEFAULTS = {
42
- :headers=>OPTS,
43
+ :headers=>RodaPlugins::OPTS,
43
44
  :host=>'localhost',
44
45
  # :nocov:
45
46
  :emailer=>lambda{|h| Net::SMTP.start(h[:host]){|s| s.send_message(h[:message], h[:from], h[:to])}},
@@ -97,7 +98,7 @@ END
97
98
  }#.freeze # RODA3
98
99
 
99
100
  # Set default opts for plugin. See ErrorEmail module RDoc for options.
100
- def self.configure(app, opts=OPTS)
101
+ def self.configure(app, opts=RodaPlugins::OPTS)
101
102
  email_opts = app.opts[:error_email] ||= DEFAULTS
102
103
  email_opts = email_opts.merge(opts)
103
104
  email_opts[:headers] = email_opts[:headers].dup
@@ -37,10 +37,11 @@ class Roda
37
37
  # use an error reporting service instead of this plugin.
38
38
  module ErrorMail
39
39
  OPTS = {}.freeze
40
+ RodaPlugins.deprecate_constant(self, :OPTS)
40
41
 
41
42
  # Set default opts for plugin. See ErrorEmail module RDoc for options.
42
- def self.configure(app, opts=OPTS)
43
- app.opts[:error_mail] = email_opts = (app.opts[:error_mail] || OPTS).merge(opts).freeze
43
+ def self.configure(app, opts=RodaPlugins::OPTS)
44
+ app.opts[:error_mail] = email_opts = (app.opts[:error_mail] || RodaPlugins::OPTS).merge(opts).freeze
44
45
  unless email_opts[:to] && email_opts[:from]
45
46
  raise RodaError, "must provide :to and :from options to error_mail plugin"
46
47
  end
@@ -37,6 +37,7 @@ class Roda
37
37
  # may prevent search engine's from crawling your website.
38
38
  module Head
39
39
  EMPTY_ARRAY = [].freeze
40
+ RodaPlugins.deprecate_constant(self, :EMPTY_ARRAY)
40
41
 
41
42
  module InstanceMethods
42
43
  # Always use an empty response body for head requests, with a
@@ -44,7 +45,7 @@ class Roda
44
45
  def call(*)
45
46
  res = super
46
47
  if @_request.head?
47
- res[2] = EMPTY_ARRAY
48
+ res[2] = RodaPlugins::EMPTY_ARRAY
48
49
  end
49
50
  res
50
51
  end
@@ -67,6 +67,8 @@ class Roda
67
67
 
68
68
  if roda_class.opts[:header_matcher_prefix]
69
69
  key = "HTTP_#{key}"
70
+ else
71
+ RodaPlugins.warn ":header matcher used without :header_matcher_prefix app option. Currently this looks for the #{key} header, but in Roda 3 it will look for the HTTP_#{key} header. You should set the :header_matcher_prefix app option and update your code if necessary to avoid this deprecation warning."
70
72
  end
71
73
 
72
74
  if v = @env[key]
@@ -82,6 +84,7 @@ class Roda
82
84
  @captures.concat(match.captures)
83
85
  end
84
86
  else
87
+ RodaPlugins.warn ":host matcher used with regexp value without :host_matcher_captures app option, no capturing will be done. Starting in Roda 3, the :host matcher will automatically capture if the value is a Regexp. Set :host_matcher_captures app option to enable capturing." if hostname.is_a?(Regexp)
85
88
  hostname === host
86
89
  end
87
90
  end
@@ -14,14 +14,15 @@ class Roda
14
14
  #
15
15
  # plugin :heartbeat, :path=>'/status'
16
16
  module Heartbeat
17
- OPTS = {}.freeze
18
17
  HEARTBEAT_RESPONSE = [200, {'Content-Type'=>'text/plain'}.freeze, ['OK'.freeze].freeze].freeze
19
18
 
19
+ OPTS = {}.freeze
20
+ RodaPlugins.deprecate_constant(self, :OPTS)
20
21
  PATH_INFO = 'PATH_INFO'.freeze
21
22
  RodaPlugins.deprecate_constant(self, :PATH_INFO)
22
23
 
23
24
  # Set the heartbeat path to the given path.
24
- def self.configure(app, opts=OPTS)
25
+ def self.configure(app, opts=RodaPlugins::OPTS)
25
26
  app.opts[:heartbeat_path] = (opts[:path] || app.opts[:heartbeat_path] || "/heartbeat").dup.freeze
26
27
  end
27
28
 
@@ -53,14 +53,15 @@ class Roda
53
53
  #
54
54
  # plugin :json, :content_type=>'application/xml'
55
55
  module Json
56
- OPTS = {}.freeze
57
56
  DEFAULT_SERIALIZER = :to_json.to_proc
58
57
 
58
+ OPTS = {}.freeze
59
+ RodaPlugins.deprecate_constant(self, :OPTS)
59
60
  DEFAULT_CONTENT_TYPE = 'application/json'.freeze
60
61
  RodaPlugins.deprecate_constant(self, :DEFAULT_CONTENT_TYPE)
61
62
 
62
63
  # Set the classes to automatically convert to JSON, and the serializer to use.
63
- def self.configure(app, opts=OPTS)
64
+ def self.configure(app, opts=RodaPlugins::OPTS)
64
65
  classes = opts[:classes] || [Array, Hash]
65
66
  app.opts[:json_result_classes] ||= []
66
67
  app.opts[:json_result_classes] += classes
@@ -83,6 +84,7 @@ class Roda
83
84
 
84
85
  module RequestMethods
85
86
  CONTENT_TYPE = 'Content-Type'.freeze
87
+ RodaPlugins.deprecate_constant(self, :CONTENT_TYPE)
86
88
 
87
89
  private
88
90
 
@@ -92,7 +94,7 @@ class Roda
92
94
  def block_result_body(result)
93
95
  case result
94
96
  when *roda_class.json_result_classes
95
- response[CONTENT_TYPE] ||= roda_class.opts[:json_result_content_type]
97
+ response['Content-Type'] ||= roda_class.opts[:json_result_content_type]
96
98
  convert_to_json(result)
97
99
  else
98
100
  super
@@ -11,10 +11,11 @@ class Roda
11
11
  # This only parses the request body as JSON if the Content-Type
12
12
  # header for the request includes "json".
13
13
  module JsonParser
14
- OPTS = {}.freeze
15
14
  DEFAULT_ERROR_HANDLER = proc{|r| r.halt [400, {}, []]}
16
15
  DEFAULT_PARSER = JSON.method(:parse)
17
16
 
17
+ OPTS = {}.freeze
18
+ RodaPlugins.deprecate_constant(self, :OPTS)
18
19
  JSON_PARAMS_KEY = "roda.json_params".freeze
19
20
  RodaPlugins.deprecate_constant(self, :JSON_PARAMS_KEY)
20
21
  INPUT_KEY = "rack.input".freeze
@@ -35,7 +36,7 @@ class Roda
35
36
  # :include_request :: If true, the parser will be called with the request
36
37
  # object as the second argument, so the parser needs
37
38
  # to respond to +call(str, request)+.
38
- def self.configure(app, opts=OPTS)
39
+ def self.configure(app, opts=RodaPlugins::OPTS)
39
40
  app.opts[:json_parser_error_handler] = opts[:error_handler] || app.opts[:json_parser_error_handler] || DEFAULT_ERROR_HANDLER
40
41
  app.opts[:json_parser_parser] = opts[:parser] || app.opts[:json_parser_parser] || DEFAULT_PARSER
41
42
  app.opts[:json_parser_include_request] = opts[:include_request] || app.opts[:json_parser_include_request]
@@ -111,7 +111,7 @@ class Roda
111
111
  # available in your email views.
112
112
  module Mailer
113
113
  OPTS = {}.freeze
114
-
114
+ RodaPlugins.deprecate_constant(self, :OPTS)
115
115
  REQUEST_METHOD = "REQUEST_METHOD".freeze
116
116
  RodaPlugins.deprecate_constant(self, :REQUEST_METHOD)
117
117
  PATH_INFO = "PATH_INFO".freeze
@@ -139,8 +139,8 @@ class Roda
139
139
 
140
140
  # Set the options for the mailer. Options:
141
141
  # :content_type :: The default content type for emails (default: text/plain)
142
- def self.configure(app, opts=OPTS)
143
- app.opts[:mailer] = (app.opts[:mailer]||{}).merge(opts).freeze
142
+ def self.configure(app, opts=RodaPlugins::OPTS)
143
+ app.opts[:mailer] = (app.opts[:mailer]||RodaPlugins::OPTS).merge(opts).freeze
144
144
  end
145
145
 
146
146
  module ClassMethods
@@ -25,12 +25,18 @@ class Roda
25
25
  #
26
26
  # will not modify the prefix and will change the suffix so that it consumes a trailing slash
27
27
  # at the end of the path only.
28
+ #
29
+ # This plugin automatically loads the placeholder_string_matchers plugin.
28
30
  module MatchAffix
29
31
  PREFIX = "/".freeze
30
32
  RodaPlugins.deprecate_constant(self, :PREFIX)
31
33
  SUFFIX = "(?=\/|\z)".freeze
32
34
  RodaPlugins.deprecate_constant(self, :SUFFIX)
33
35
 
36
+ def self.load_dependencies(app, _prefix, _suffix)
37
+ app.plugin :placeholder_string_matchers
38
+ end
39
+
34
40
  # Set the default prefix and suffix to use in match patterns, if a non-nil value
35
41
  # is given.
36
42
  def self.configure(app, prefix, suffix=nil)
@@ -150,7 +150,9 @@ class Roda
150
150
 
151
151
  # The names for the currently stored named routes
152
152
  def named_routes(namespace=nil)
153
- routes = opts[:namespaced_routes][namespace]
153
+ unless routes = opts[:namespaced_routes][namespace]
154
+ RodaPlugins.warn "Attempt to access multi_route namespace for which no routes have been defined: #{namespace}"
155
+ end
154
156
  routes ? routes.keys : []
155
157
  end
156
158
 
@@ -23,17 +23,18 @@ class Roda
23
23
  # Note that this plugin loads the :partials plugin.
24
24
  module PadrinoRender
25
25
  OPTS = {}.freeze
26
+ RodaPlugins.deprecate_constant(self, :OPTS)
26
27
 
27
28
  # Depend on the render plugin, since this overrides
28
29
  # some of its methods.
29
- def self.load_dependencies(app, opts=OPTS)
30
+ def self.load_dependencies(app, opts=RodaPlugins::OPTS)
30
31
  app.plugin :partials, opts
31
32
  end
32
33
 
33
34
  module InstanceMethods
34
35
  # Call view with the given arguments, so that render
35
36
  # uses a layout by default.
36
- def render(template, opts=OPTS)
37
+ def render(template, opts=RodaPlugins::OPTS)
37
38
  view(template, opts)
38
39
  end
39
40
  end
@@ -52,8 +52,8 @@ class Roda
52
52
  # strings and not symbols (<tt>r[]</tt> converts the argument
53
53
  # to a string before looking it up in +r.params+).
54
54
  #
55
- # This plugin will also handle string matchers if placeholders in
56
- # string matchers are supported.
55
+ # This plugin will also handle string matchers with placeholders if
56
+ # the placeholder_string_matchers plugin is loaded before this plugin.
57
57
  #
58
58
  # Also note that this plugin will not work correctly if you are using
59
59
  # the symbol_matchers plugin with custom symbol matching and are using
@@ -82,7 +82,7 @@ class Roda
82
82
  end
83
83
  else
84
84
  # :nocov:
85
-
85
+ # RODA3: Remove
86
86
  # Ruby 1.8 doesn't support positive lookbehind, so include the
87
87
  # colon in the scan, and strip it out later.
88
88
  STRING_PARAM_CAPTURE_RANGE = 1..-1
@@ -21,13 +21,13 @@ class Roda
21
21
  # Note that this plugin automatically loads the :render plugin.
22
22
  module Partials
23
23
  OPTS = {}.freeze
24
-
24
+ RodaPlugins.deprecate_constant(self, :OPTS)
25
25
  SLASH = '/'.freeze
26
26
  RodaPlugins.deprecate_constant(self, :SLASH)
27
27
 
28
28
  # Depend on the render plugin, since this overrides
29
29
  # some of its methods.
30
- def self.load_dependencies(app, opts=OPTS)
30
+ def self.load_dependencies(app, opts=RodaPlugins::OPTS)
31
31
  app.plugin :render, opts
32
32
  end
33
33
 
@@ -35,7 +35,7 @@ class Roda
35
35
  # Renders the given template without a layout, but
36
36
  # prefixes the template filename to use with an
37
37
  # underscore.
38
- def partial(template, opts=OPTS)
38
+ def partial(template, opts=RodaPlugins::OPTS)
39
39
  opts = parse_template_opts(template, opts)
40
40
  if opts[:template]
41
41
  template = opts[:template].split('/')
@@ -62,12 +62,14 @@ class Roda
62
62
  # a block to a block that is instance_execed.
63
63
  module Path
64
64
  DEFAULT_PORTS = {'http' => 80, 'https' => 443}.freeze
65
+
65
66
  OPTS = {}.freeze
67
+ RodaPlugins.deprecate_constant(self, :OPTS)
66
68
 
67
69
  # Initialize the path classes when loading the plugin. Options:
68
70
  # :by_name :: Register classes by name, which is friendlier when reloading code (defaults to
69
71
  # true in development mode)
70
- def self.configure(app, opts=OPTS)
72
+ def self.configure(app, opts=RodaPlugins::OPTS)
71
73
  app.instance_eval do
72
74
  self.opts[:path_class_by_name] = opts.fetch(:by_name, ENV['RACK_ENV'] == 'development')
73
75
  self.opts[:path_classes] ||= {}
@@ -90,7 +92,7 @@ class Roda
90
92
  end
91
93
 
92
94
  # Create a new instance method for the named path. See plugin module documentation for options.
93
- def path(name, path=nil, opts=OPTS, &block)
95
+ def path(name, path=nil, opts=RodaPlugins::OPTS, &block)
94
96
  if name.is_a?(Class)
95
97
  raise RodaError, "can't provide path or options when calling path with a class" unless path.nil? && opts.empty?
96
98
  raise RodaError, "must provide a block when calling path with a class" unless block