roda 2.28.0 → 2.29.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +46 -0
- data/README.rdoc +25 -7
- data/doc/release_notes/2.29.0.txt +156 -0
- data/lib/roda.rb +25 -3
- data/lib/roda/plugins/_erubis_escaping.rb +2 -0
- data/lib/roda/plugins/_symbol_regexp_matchers.rb +22 -0
- data/lib/roda/plugins/assets.rb +3 -2
- data/lib/roda/plugins/branch_locals.rb +74 -0
- data/lib/roda/plugins/caching.rb +15 -7
- data/lib/roda/plugins/chunked.rb +10 -7
- data/lib/roda/plugins/content_for.rb +4 -1
- data/lib/roda/plugins/drop_body.rb +3 -2
- data/lib/roda/plugins/error_email.rb +3 -2
- data/lib/roda/plugins/error_mail.rb +3 -2
- data/lib/roda/plugins/head.rb +2 -1
- data/lib/roda/plugins/header_matchers.rb +3 -0
- data/lib/roda/plugins/heartbeat.rb +3 -2
- data/lib/roda/plugins/json.rb +5 -3
- data/lib/roda/plugins/json_parser.rb +3 -2
- data/lib/roda/plugins/mailer.rb +3 -3
- data/lib/roda/plugins/match_affix.rb +6 -0
- data/lib/roda/plugins/multi_route.rb +3 -1
- data/lib/roda/plugins/padrino_render.rb +3 -2
- data/lib/roda/plugins/params_capturing.rb +3 -3
- data/lib/roda/plugins/partials.rb +3 -3
- data/lib/roda/plugins/path.rb +4 -2
- data/lib/roda/plugins/path_rewriter.rb +2 -2
- data/lib/roda/plugins/per_thread_caching.rb +2 -0
- data/lib/roda/plugins/placeholder_string_matchers.rb +42 -0
- data/lib/roda/plugins/precompile_templates.rb +3 -2
- data/lib/roda/plugins/render.rb +86 -37
- data/lib/roda/plugins/render_each.rb +2 -1
- data/lib/roda/plugins/render_locals.rb +102 -0
- data/lib/roda/plugins/run_append_slash.rb +2 -1
- data/lib/roda/plugins/run_handler.rb +2 -1
- data/lib/roda/plugins/sinatra_helpers.rb +4 -4
- data/lib/roda/plugins/static_path_info.rb +2 -0
- data/lib/roda/plugins/static_routing.rb +1 -1
- data/lib/roda/plugins/streaming.rb +9 -4
- data/lib/roda/plugins/symbol_matchers.rb +23 -20
- data/lib/roda/plugins/view_options.rb +63 -28
- data/lib/roda/plugins/view_subdirs.rb +1 -0
- data/lib/roda/plugins/websockets.rb +2 -0
- data/lib/roda/version.rb +1 -1
- data/spec/composition_spec.rb +2 -2
- data/spec/matchers_spec.rb +6 -5
- data/spec/plugin/_erubis_escaping_spec.rb +5 -5
- data/spec/plugin/backtracking_array_spec.rb +0 -2
- data/spec/plugin/branch_locals_spec.rb +88 -0
- data/spec/plugin/content_for_spec.rb +8 -2
- data/spec/plugin/halt_spec.rb +8 -0
- data/spec/plugin/header_matchers_spec.rb +20 -5
- data/spec/plugin/multi_route_spec.rb +1 -1
- data/spec/plugin/named_templates_spec.rb +2 -2
- data/spec/plugin/params_capturing_spec.rb +1 -1
- data/spec/plugin/per_thread_caching_spec.rb +1 -1
- data/spec/plugin/placeholder_string_matchers_spec.rb +159 -0
- data/spec/plugin/render_locals_spec.rb +114 -0
- data/spec/plugin/render_spec.rb +83 -8
- data/spec/plugin/streaming_spec.rb +104 -4
- data/spec/plugin/symbol_matchers_spec.rb +1 -1
- data/spec/plugin/view_options_spec.rb +83 -7
- data/spec/plugin/websockets_spec.rb +7 -8
- data/spec/spec_helper.rb +22 -2
- metadata +11 -2
data/lib/roda/plugins/caching.rb
CHANGED
@@ -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(
|
206
|
+
k = k.to_s.tr('_', '-')
|
199
207
|
values << (v == true ? k : "#{k}=#{v}")
|
200
208
|
end
|
201
209
|
|
202
|
-
self[
|
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[
|
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(
|
220
|
-
h.delete(
|
227
|
+
h.delete('Content-Type')
|
228
|
+
h.delete('Content-Length')
|
221
229
|
end
|
222
230
|
a
|
223
231
|
end
|
data/lib/roda/plugins/chunked.rb
CHANGED
@@ -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(
|
196
|
+
yield("%x\r\n" % chunk.bytesize)
|
194
197
|
yield(chunk)
|
195
|
-
yield(
|
198
|
+
yield("\r\n")
|
196
199
|
end
|
197
200
|
ensure
|
198
|
-
yield(
|
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,
|
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] =
|
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
|
data/lib/roda/plugins/head.rb
CHANGED
@@ -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
|
|
data/lib/roda/plugins/json.rb
CHANGED
@@ -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[
|
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]
|
data/lib/roda/plugins/mailer.rb
CHANGED
@@ -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]||
|
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
|
56
|
-
#
|
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('/')
|
data/lib/roda/plugins/path.rb
CHANGED
@@ -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
|