roda 2.29.0 → 3.0.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG +52 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +51 -109
- data/Rakefile +7 -14
- data/doc/conventions.rdoc +4 -4
- data/doc/release_notes/1.2.0.txt +1 -1
- data/doc/release_notes/3.0.0.txt +84 -0
- data/lib/roda.rb +25 -79
- data/lib/roda/plugins/assets.rb +25 -58
- data/lib/roda/plugins/assets_preloading.rb +0 -5
- data/lib/roda/plugins/backtracking_array.rb +0 -5
- data/lib/roda/plugins/branch_locals.rb +3 -3
- data/lib/roda/plugins/caching.rb +5 -38
- data/lib/roda/plugins/chunked.rb +7 -25
- data/lib/roda/plugins/class_level_routing.rb +2 -2
- data/lib/roda/plugins/content_for.rb +7 -10
- data/lib/roda/plugins/cookies.rb +3 -3
- data/lib/roda/plugins/csrf.rb +2 -2
- data/lib/roda/plugins/delegate.rb +3 -3
- data/lib/roda/plugins/drop_body.rb +0 -7
- data/lib/roda/plugins/empty_root.rb +0 -3
- data/lib/roda/plugins/error_email.rb +4 -6
- data/lib/roda/plugins/error_handler.rb +1 -2
- data/lib/roda/plugins/error_mail.rb +3 -6
- data/lib/roda/plugins/flash.rb +0 -4
- data/lib/roda/plugins/h.rb +5 -0
- data/lib/roda/plugins/hash_matcher.rb +4 -2
- data/lib/roda/plugins/head.rb +5 -7
- data/lib/roda/plugins/header_matchers.rb +12 -33
- data/lib/roda/plugins/heartbeat.rb +2 -7
- data/lib/roda/plugins/indifferent_params.rb +2 -2
- data/lib/roda/plugins/json.rb +6 -14
- data/lib/roda/plugins/json_parser.rb +2 -13
- data/lib/roda/plugins/mailer.rb +29 -39
- data/lib/roda/plugins/match_affix.rb +0 -5
- data/lib/roda/plugins/middleware.rb +10 -15
- data/lib/roda/plugins/multi_route.rb +8 -5
- data/lib/roda/plugins/multi_run.rb +1 -0
- data/lib/roda/plugins/named_templates.rb +2 -2
- data/lib/roda/plugins/optimized_string_matchers.rb +0 -3
- data/lib/roda/plugins/padrino_render.rb +6 -9
- data/lib/roda/plugins/param_matchers.rb +6 -6
- data/lib/roda/plugins/params_capturing.rb +15 -35
- data/lib/roda/plugins/partials.rb +3 -8
- data/lib/roda/plugins/path.rb +5 -5
- data/lib/roda/plugins/path_matchers.rb +3 -3
- data/lib/roda/plugins/path_rewriter.rb +4 -9
- data/lib/roda/plugins/placeholder_string_matchers.rb +1 -1
- data/lib/roda/plugins/precompile_templates.rb +10 -20
- data/lib/roda/plugins/public.rb +6 -9
- data/lib/roda/plugins/render.rb +50 -171
- data/lib/roda/plugins/render_each.rb +4 -7
- data/lib/roda/plugins/render_locals.rb +6 -20
- data/lib/roda/plugins/request_headers.rb +2 -4
- data/lib/roda/plugins/run_append_slash.rb +1 -4
- data/lib/roda/plugins/run_handler.rb +4 -7
- data/lib/roda/plugins/shared_vars.rb +3 -6
- data/lib/roda/plugins/sinatra_helpers.rb +11 -40
- data/lib/roda/plugins/slash_path_empty.rb +0 -3
- data/lib/roda/plugins/static.rb +2 -2
- data/lib/roda/plugins/static_routing.rb +2 -3
- data/lib/roda/plugins/streaming.rb +15 -108
- data/lib/roda/plugins/strip_path_prefix.rb +1 -1
- data/lib/roda/plugins/symbol_matchers.rb +7 -23
- data/lib/roda/plugins/type_routing.rb +4 -9
- data/lib/roda/plugins/view_options.rb +10 -66
- data/lib/roda/version.rb +2 -2
- data/spec/all.rb +0 -2
- data/spec/composition_spec.rb +1 -1
- data/spec/env_spec.rb +1 -1
- data/spec/freeze_spec.rb +1 -1
- data/spec/integration_spec.rb +1 -1
- data/spec/matchers_spec.rb +26 -70
- data/spec/opts_spec.rb +1 -1
- data/spec/plugin/all_verbs_spec.rb +1 -1
- data/spec/plugin/assets_preloading_spec.rb +1 -1
- data/spec/plugin/assets_spec.rb +43 -27
- data/spec/plugin/backtracking_array_spec.rb +1 -1
- data/spec/plugin/branch_locals_spec.rb +1 -1
- data/spec/plugin/caching_spec.rb +1 -1
- data/spec/plugin/chunked_spec.rb +1 -1
- data/spec/plugin/class_level_routing_spec.rb +1 -1
- data/spec/plugin/class_matchers_spec.rb +1 -1
- data/spec/plugin/content_for_spec.rb +2 -7
- data/spec/plugin/cookies_spec.rb +1 -1
- data/spec/plugin/csrf_spec.rb +1 -1
- data/spec/plugin/default_headers_spec.rb +1 -1
- data/spec/plugin/default_status_spec.rb +1 -1
- data/spec/plugin/delay_build_spec.rb +1 -1
- data/spec/plugin/delegate_spec.rb +1 -1
- data/spec/plugin/delete_empty_headers_spec.rb +1 -1
- data/spec/plugin/disallow_file_uploads_spec.rb +2 -2
- data/spec/plugin/drop_body_spec.rb +1 -1
- data/spec/plugin/empty_root_spec.rb +1 -1
- data/spec/plugin/environments_spec.rb +1 -1
- data/spec/plugin/error_email_spec.rb +1 -1
- data/spec/plugin/error_handler_spec.rb +1 -1
- data/spec/plugin/error_mail_spec.rb +2 -2
- data/spec/plugin/flash_spec.rb +1 -1
- data/spec/plugin/h_spec.rb +1 -1
- data/spec/plugin/halt_spec.rb +2 -2
- data/spec/plugin/hash_matcher_spec.rb +1 -1
- data/spec/plugin/head_spec.rb +1 -1
- data/spec/plugin/header_matchers_spec.rb +4 -47
- data/spec/plugin/heartbeat_spec.rb +1 -1
- data/spec/plugin/hooks_spec.rb +1 -1
- data/spec/plugin/indifferent_params_spec.rb +1 -1
- data/spec/plugin/json_parser_spec.rb +12 -1
- data/spec/plugin/json_spec.rb +8 -1
- data/spec/plugin/mailer_spec.rb +1 -1
- data/spec/plugin/match_affix_spec.rb +1 -1
- data/spec/plugin/middleware_spec.rb +15 -1
- data/spec/plugin/module_include_spec.rb +1 -1
- data/spec/plugin/multi_route_spec.rb +5 -3
- data/spec/plugin/multi_run_spec.rb +1 -1
- data/spec/plugin/multi_view_spec.rb +1 -1
- data/spec/plugin/named_templates_spec.rb +1 -1
- data/spec/plugin/not_allowed_spec.rb +1 -1
- data/spec/plugin/not_found_spec.rb +1 -1
- data/spec/plugin/optimized_string_matchers_spec.rb +1 -1
- data/spec/plugin/padrino_render_spec.rb +1 -1
- data/spec/plugin/param_matchers_spec.rb +1 -1
- data/spec/plugin/params_capturing_spec.rb +6 -22
- data/spec/plugin/partials_spec.rb +1 -1
- data/spec/plugin/pass_spec.rb +1 -1
- data/spec/plugin/path_matchers_spec.rb +1 -1
- data/spec/plugin/path_rewriter_spec.rb +1 -1
- data/spec/plugin/path_spec.rb +1 -1
- data/spec/plugin/placeholder_string_matchers_spec.rb +3 -36
- data/spec/plugin/precompile_templates_spec.rb +1 -17
- data/spec/plugin/public_spec.rb +3 -4
- data/spec/plugin/render_each_spec.rb +1 -1
- data/spec/plugin/render_locals_spec.rb +1 -1
- data/spec/plugin/render_spec.rb +28 -114
- data/spec/plugin/request_headers_spec.rb +1 -1
- data/spec/plugin/response_request_spec.rb +1 -1
- data/spec/plugin/run_append_slash_spec.rb +1 -1
- data/spec/plugin/run_handler_spec.rb +1 -1
- data/spec/plugin/shared_vars_spec.rb +1 -1
- data/spec/plugin/sinatra_helpers_spec.rb +1 -1
- data/spec/plugin/slash_path_empty_spec.rb +1 -1
- data/spec/plugin/static_routing_spec.rb +1 -1
- data/spec/plugin/static_spec.rb +1 -1
- data/spec/plugin/status_303_spec.rb +1 -1
- data/spec/plugin/status_handler_spec.rb +1 -1
- data/spec/plugin/streaming_spec.rb +1 -106
- data/spec/plugin/strip_path_prefix_spec.rb +1 -1
- data/spec/plugin/symbol_matchers_spec.rb +1 -77
- data/spec/plugin/symbol_status_spec.rb +1 -1
- data/spec/plugin/symbol_views_spec.rb +1 -1
- data/spec/plugin/type_routing_spec.rb +1 -1
- data/spec/plugin/unescape_path_spec.rb +1 -1
- data/spec/plugin/view_options_spec.rb +16 -110
- data/spec/plugin_spec.rb +1 -1
- data/spec/redirect_spec.rb +1 -1
- data/spec/request_spec.rb +1 -1
- data/spec/response_spec.rb +1 -1
- data/spec/session_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -3
- data/spec/version_spec.rb +1 -1
- metadata +6 -26
- data/lib/roda/plugins/_erubis_escaping.rb +0 -59
- data/lib/roda/plugins/per_thread_caching.rb +0 -71
- data/lib/roda/plugins/static_path_info.rb +0 -12
- data/lib/roda/plugins/view_subdirs.rb +0 -7
- data/lib/roda/plugins/websockets.rb +0 -107
- data/spec/plugin/_erubis_escaping_spec.rb +0 -97
- data/spec/plugin/per_thread_caching_spec.rb +0 -28
- data/spec/plugin/websockets_spec.rb +0 -84
|
@@ -28,11 +28,6 @@ class Roda
|
|
|
28
28
|
#
|
|
29
29
|
# This plugin automatically loads the placeholder_string_matchers plugin.
|
|
30
30
|
module MatchAffix
|
|
31
|
-
PREFIX = "/".freeze
|
|
32
|
-
RodaPlugins.deprecate_constant(self, :PREFIX)
|
|
33
|
-
SUFFIX = "(?=\/|\z)".freeze
|
|
34
|
-
RodaPlugins.deprecate_constant(self, :SUFFIX)
|
|
35
|
-
|
|
36
31
|
def self.load_dependencies(app, _prefix, _suffix)
|
|
37
32
|
app.plugin :placeholder_string_matchers
|
|
38
33
|
end
|
|
@@ -34,7 +34,8 @@ class Roda
|
|
|
34
34
|
# run App
|
|
35
35
|
#
|
|
36
36
|
# It is possible to use the Roda app as a regular app even when using
|
|
37
|
-
# the middleware plugin.
|
|
37
|
+
# the middleware plugin. Using an app as middleware automatically creates
|
|
38
|
+
# a subclass of the app for the middleware.
|
|
38
39
|
#
|
|
39
40
|
# You can support configurable middleware by passing a block when loading
|
|
40
41
|
# the plugin:
|
|
@@ -60,11 +61,6 @@ class Roda
|
|
|
60
61
|
#
|
|
61
62
|
# # Request to App for /mid returns
|
|
62
63
|
# # "foo bar baz"
|
|
63
|
-
#
|
|
64
|
-
# Note that when supporting configurable middleware via a block, the middleware
|
|
65
|
-
# used is a subclass of the class loading the plugin, instead of the class itself.
|
|
66
|
-
# This is done so the same class can be used as middleware with multiple separate
|
|
67
|
-
# configurations.
|
|
68
64
|
module Middleware
|
|
69
65
|
# Configure the middleware plugin. Options:
|
|
70
66
|
# :env_var :: Set the environment variable to use to indicate to the roda
|
|
@@ -77,17 +73,16 @@ class Roda
|
|
|
77
73
|
app.opts[:middleware_configure] = block if block
|
|
78
74
|
end
|
|
79
75
|
|
|
80
|
-
#
|
|
76
|
+
# Forwarder instances are what is actually used as middleware.
|
|
81
77
|
class Forwarder
|
|
82
|
-
#
|
|
78
|
+
# Make a subclass of +mid+ to use as the current middleware,
|
|
79
|
+
# and store +app+ as the next middleware to call.
|
|
83
80
|
def initialize(mid, app, *args, &block)
|
|
84
|
-
@mid =
|
|
85
|
-
|
|
86
|
-
configure.call(mid, *args, &block)
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
raise RodaError, "cannot provide middleware args or block unless loading middleware plugin with a block" if block || !args.empty?
|
|
90
|
-
mid
|
|
81
|
+
@mid = Class.new(mid)
|
|
82
|
+
if configure = @mid.opts[:middleware_configure]
|
|
83
|
+
configure.call(@mid, *args, &block)
|
|
84
|
+
elsif block || !args.empty?
|
|
85
|
+
raise RodaError, "cannot provide middleware args or block unless loading middleware plugin with a block"
|
|
91
86
|
end
|
|
92
87
|
@app = app
|
|
93
88
|
end
|
|
@@ -133,10 +133,13 @@ class Roda
|
|
|
133
133
|
end
|
|
134
134
|
|
|
135
135
|
module ClassMethods
|
|
136
|
-
# Freeze the namespaced routes so that there can be no thread safety issues at runtime.
|
|
136
|
+
# Freeze the namespaced routes and setup the regexp matchers so that there can be no thread safety issues at runtime.
|
|
137
137
|
def freeze
|
|
138
|
-
opts[:namespaced_routes].freeze
|
|
139
|
-
|
|
138
|
+
opts[:namespaced_routes].freeze.each do |k,v|
|
|
139
|
+
v.freeze
|
|
140
|
+
self::RodaRequest.named_route_regexp(k)
|
|
141
|
+
end
|
|
142
|
+
self::RodaRequest.instance_variable_get(:@namespaced_route_regexps).freeze
|
|
140
143
|
super
|
|
141
144
|
end
|
|
142
145
|
|
|
@@ -151,9 +154,9 @@ class Roda
|
|
|
151
154
|
# The names for the currently stored named routes
|
|
152
155
|
def named_routes(namespace=nil)
|
|
153
156
|
unless routes = opts[:namespaced_routes][namespace]
|
|
154
|
-
|
|
157
|
+
raise RodaError, "unsupported multi_route namespace used: #{namespace.inspect}"
|
|
155
158
|
end
|
|
156
|
-
routes
|
|
159
|
+
routes.keys
|
|
157
160
|
end
|
|
158
161
|
|
|
159
162
|
# Return the named route with the given name.
|
|
@@ -24,7 +24,7 @@ class Roda
|
|
|
24
24
|
# You can provide options for the template, for example to change the
|
|
25
25
|
# engine that the template uses:
|
|
26
26
|
#
|
|
27
|
-
# template :index, :
|
|
27
|
+
# template :index, engine: :str do
|
|
28
28
|
# "<p>Hello #{@user}!</p>"
|
|
29
29
|
# end
|
|
30
30
|
#
|
|
@@ -37,7 +37,7 @@ class Roda
|
|
|
37
37
|
# "<p>#{greating} <%= @user %>!</p>"
|
|
38
38
|
# end
|
|
39
39
|
#
|
|
40
|
-
# This plugin also works with the
|
|
40
|
+
# This plugin also works with the view_options plugin, as long as you
|
|
41
41
|
# prefix the template name with the view subdirectory:
|
|
42
42
|
#
|
|
43
43
|
# template "main/index" do
|
|
@@ -24,9 +24,6 @@ class Roda
|
|
|
24
24
|
# correctly in such cases, but the captures will not be yielded to the
|
|
25
25
|
# match blocks.
|
|
26
26
|
module OptimizedStringMatchers
|
|
27
|
-
EMPTY_STRING = ''.freeze
|
|
28
|
-
RodaPlugins.deprecate_constant(self, :EMPTY_STRING)
|
|
29
|
-
|
|
30
27
|
module RequestMethods
|
|
31
28
|
# Optimized version of +on+ that only supports a single string.
|
|
32
29
|
def on_branch(s)
|
|
@@ -5,36 +5,33 @@ class Roda
|
|
|
5
5
|
module RodaPlugins
|
|
6
6
|
# The padrino_render plugin adds rendering support that is
|
|
7
7
|
# similar to Padrino's. While not everything Padrino's
|
|
8
|
-
# rendering supports is supported by this plugin
|
|
8
|
+
# rendering supports is supported by this plugin, it
|
|
9
9
|
# currently handles enough to be a drop in replacement for
|
|
10
10
|
# some applications.
|
|
11
11
|
#
|
|
12
|
-
# plugin :padrino_render, :
|
|
12
|
+
# plugin :padrino_render, views: 'path/2/views'
|
|
13
13
|
#
|
|
14
14
|
# Most notably, this makes the +render+ method default to
|
|
15
15
|
# using the layout, similar to how the +view+ method works
|
|
16
16
|
# in the render plugin. If you want to call render and not
|
|
17
|
-
# use a layout, you can use the <tt
|
|
17
|
+
# use a layout, you can use the <tt>layout: false</tt>
|
|
18
18
|
# option:
|
|
19
19
|
#
|
|
20
20
|
# render('test') # layout
|
|
21
|
-
# render('test', :
|
|
21
|
+
# render('test', layout: false) # no layout
|
|
22
22
|
#
|
|
23
23
|
# Note that this plugin loads the :partials plugin.
|
|
24
24
|
module PadrinoRender
|
|
25
|
-
OPTS = {}.freeze
|
|
26
|
-
RodaPlugins.deprecate_constant(self, :OPTS)
|
|
27
|
-
|
|
28
25
|
# Depend on the render plugin, since this overrides
|
|
29
26
|
# some of its methods.
|
|
30
|
-
def self.load_dependencies(app, opts=
|
|
27
|
+
def self.load_dependencies(app, opts=OPTS)
|
|
31
28
|
app.plugin :partials, opts
|
|
32
29
|
end
|
|
33
30
|
|
|
34
31
|
module InstanceMethods
|
|
35
32
|
# Call view with the given arguments, so that render
|
|
36
33
|
# uses a layout by default.
|
|
37
|
-
def render(template, opts=
|
|
34
|
+
def render(template, opts=OPTS)
|
|
38
35
|
view(template, opts)
|
|
39
36
|
end
|
|
40
37
|
end
|
|
@@ -9,7 +9,7 @@ class Roda
|
|
|
9
9
|
# It adds a :param matcher for matching on any param with the
|
|
10
10
|
# same name, yielding the value of the param:
|
|
11
11
|
#
|
|
12
|
-
# r.on :
|
|
12
|
+
# r.on param: 'foo' do |value|
|
|
13
13
|
# # Matches '?foo=bar', '?foo='
|
|
14
14
|
# # Doesn't match '?bar=foo'
|
|
15
15
|
# end
|
|
@@ -17,7 +17,7 @@ class Roda
|
|
|
17
17
|
# It adds a :param! matcher for matching on any non-empty param
|
|
18
18
|
# with the same name, yielding the value of the param:
|
|
19
19
|
#
|
|
20
|
-
# r.on(
|
|
20
|
+
# r.on(param!: 'foo') do |value|
|
|
21
21
|
# # Matches '?foo=bar'
|
|
22
22
|
# # Doesn't match '?foo=', '?bar=foo'
|
|
23
23
|
# end
|
|
@@ -25,12 +25,12 @@ class Roda
|
|
|
25
25
|
# It also adds :params and :params! matchers, for matching multiple
|
|
26
26
|
# params at the same time:
|
|
27
27
|
#
|
|
28
|
-
# r.on :
|
|
28
|
+
# r.on params: ['foo', 'baz'] do |value|
|
|
29
29
|
# # Matches '?foo=bar&baz=quuz', '?foo=&baz='
|
|
30
30
|
# # Doesn't match '?foo=bar', '?baz='
|
|
31
31
|
# end
|
|
32
32
|
#
|
|
33
|
-
# r.on
|
|
33
|
+
# r.on params!: ['foo', 'baz'] do |value|
|
|
34
34
|
# # Matches '?foo=bar&baz=quuz'
|
|
35
35
|
# # Doesn't match '?foo=bar', '?baz=', '?foo=&baz=', '?foo=bar&baz='
|
|
36
36
|
# end
|
|
@@ -40,7 +40,7 @@ class Roda
|
|
|
40
40
|
# Match the given parameter if present, even if the parameter is empty.
|
|
41
41
|
# Adds match to the captures.
|
|
42
42
|
def match_param(key)
|
|
43
|
-
if v =
|
|
43
|
+
if v = params[key.to_s]
|
|
44
44
|
@captures << v
|
|
45
45
|
end
|
|
46
46
|
end
|
|
@@ -48,7 +48,7 @@ class Roda
|
|
|
48
48
|
# Match the given parameter if present and not empty.
|
|
49
49
|
# Adds match to the captures.
|
|
50
50
|
def match_param!(key)
|
|
51
|
-
if (v =
|
|
51
|
+
if (v = params[key.to_s]) && !v.empty?
|
|
52
52
|
@captures << v
|
|
53
53
|
end
|
|
54
54
|
end
|
|
@@ -12,9 +12,9 @@ class Roda
|
|
|
12
12
|
# route do |r|
|
|
13
13
|
# # GET /foo/123/abc/67
|
|
14
14
|
# r.on("foo", :bar, :baz, :quux) do
|
|
15
|
-
# r[
|
|
16
|
-
# r[
|
|
17
|
-
# r[
|
|
15
|
+
# r.params['bar'] #=> '123'
|
|
16
|
+
# r.params['baz'] #=> 'abc'
|
|
17
|
+
# r.params['quux'] #=> '67'
|
|
18
18
|
# end
|
|
19
19
|
# end
|
|
20
20
|
#
|
|
@@ -26,9 +26,9 @@ class Roda
|
|
|
26
26
|
# captured segments to the +captures+ key:
|
|
27
27
|
#
|
|
28
28
|
# r.on(:x, /(\d+)\/(\w+)/, :y) do
|
|
29
|
-
# r[
|
|
30
|
-
# r[
|
|
31
|
-
# r[
|
|
29
|
+
# r.params['x'] #=> nil
|
|
30
|
+
# r.params['y'] #=> nil
|
|
31
|
+
# r.params['captures'] #=> ["foo", "123", "abc", "67"]
|
|
32
32
|
# end
|
|
33
33
|
#
|
|
34
34
|
# Note that the request params +captures+ entry will be appended to with
|
|
@@ -38,7 +38,7 @@ class Roda
|
|
|
38
38
|
# r.on(:x) do
|
|
39
39
|
# r.on(:y) do
|
|
40
40
|
# r.on(:z) do
|
|
41
|
-
# r[
|
|
41
|
+
# r.params['captures'] # => ["foo", "123", "abc", "67"]
|
|
42
42
|
# end
|
|
43
43
|
# end
|
|
44
44
|
# end
|
|
@@ -48,10 +48,6 @@ class Roda
|
|
|
48
48
|
# by this plugin. You can use +r.GET+ or +r.POST+ to get the underlying
|
|
49
49
|
# entry, depending on how it was submitted.
|
|
50
50
|
#
|
|
51
|
-
# Also note that the param keys are actually stored in +r.params+ as
|
|
52
|
-
# strings and not symbols (<tt>r[]</tt> converts the argument
|
|
53
|
-
# to a string before looking it up in +r.params+).
|
|
54
|
-
#
|
|
55
51
|
# This plugin will also handle string matchers with placeholders if
|
|
56
52
|
# the placeholder_string_matchers plugin is loaded before this plugin.
|
|
57
53
|
#
|
|
@@ -67,33 +63,17 @@ class Roda
|
|
|
67
63
|
|
|
68
64
|
private
|
|
69
65
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
66
|
+
# Add the capture names from this string to list of param
|
|
67
|
+
# capture names if param capturing.
|
|
68
|
+
def _match_string(str)
|
|
69
|
+
cap_len = @captures.length
|
|
74
70
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if (pc = @_params_captures) && placeholder_string_matcher?
|
|
79
|
-
pc.concat(str.scan(STRING_PARAM_CAPTURE_REGEXP))
|
|
80
|
-
end
|
|
81
|
-
super
|
|
71
|
+
if (ret = super) && (pc = @_params_captures) && (cap_len != @captures.length)
|
|
72
|
+
# Handle use with placeholder_string_matchers plugin
|
|
73
|
+
pc.concat(str.scan(/(?<=:)\w+/))
|
|
82
74
|
end
|
|
83
|
-
else
|
|
84
|
-
# :nocov:
|
|
85
|
-
# RODA3: Remove
|
|
86
|
-
# Ruby 1.8 doesn't support positive lookbehind, so include the
|
|
87
|
-
# colon in the scan, and strip it out later.
|
|
88
|
-
STRING_PARAM_CAPTURE_RANGE = 1..-1
|
|
89
75
|
|
|
90
|
-
|
|
91
|
-
if (pc = @_params_captures) && placeholder_string_matcher?
|
|
92
|
-
pc.concat(str.scan(/:\w+/).map{|s| s[STRING_PARAM_CAPTURE_RANGE]})
|
|
93
|
-
end
|
|
94
|
-
super
|
|
95
|
-
end
|
|
96
|
-
# :nocov:
|
|
76
|
+
ret
|
|
97
77
|
end
|
|
98
78
|
|
|
99
79
|
# Add the symbol to the list of param capture names if param capturing.
|
|
@@ -6,7 +6,7 @@ class Roda
|
|
|
6
6
|
# The partials plugin adds a +partial+ method, which renders
|
|
7
7
|
# templates without the layout.
|
|
8
8
|
#
|
|
9
|
-
# plugin :partials, :
|
|
9
|
+
# plugin :partials, views: 'path/2/views'
|
|
10
10
|
#
|
|
11
11
|
# Template files are prefixed with an underscore:
|
|
12
12
|
#
|
|
@@ -20,14 +20,9 @@ class Roda
|
|
|
20
20
|
#
|
|
21
21
|
# Note that this plugin automatically loads the :render plugin.
|
|
22
22
|
module Partials
|
|
23
|
-
OPTS = {}.freeze
|
|
24
|
-
RodaPlugins.deprecate_constant(self, :OPTS)
|
|
25
|
-
SLASH = '/'.freeze
|
|
26
|
-
RodaPlugins.deprecate_constant(self, :SLASH)
|
|
27
|
-
|
|
28
23
|
# Depend on the render plugin, since this overrides
|
|
29
24
|
# some of its methods.
|
|
30
|
-
def self.load_dependencies(app, opts=
|
|
25
|
+
def self.load_dependencies(app, opts=OPTS)
|
|
31
26
|
app.plugin :render, opts
|
|
32
27
|
end
|
|
33
28
|
|
|
@@ -35,7 +30,7 @@ class Roda
|
|
|
35
30
|
# Renders the given template without a layout, but
|
|
36
31
|
# prefixes the template filename to use with an
|
|
37
32
|
# underscore.
|
|
38
|
-
def partial(template, opts=
|
|
33
|
+
def partial(template, opts=OPTS)
|
|
39
34
|
opts = parse_template_opts(template, opts)
|
|
40
35
|
if opts[:template]
|
|
41
36
|
template = opts[:template].split('/')
|
data/lib/roda/plugins/path.rb
CHANGED
|
@@ -63,13 +63,10 @@ class Roda
|
|
|
63
63
|
module Path
|
|
64
64
|
DEFAULT_PORTS = {'http' => 80, 'https' => 443}.freeze
|
|
65
65
|
|
|
66
|
-
OPTS = {}.freeze
|
|
67
|
-
RodaPlugins.deprecate_constant(self, :OPTS)
|
|
68
|
-
|
|
69
66
|
# Initialize the path classes when loading the plugin. Options:
|
|
70
67
|
# :by_name :: Register classes by name, which is friendlier when reloading code (defaults to
|
|
71
68
|
# true in development mode)
|
|
72
|
-
def self.configure(app, opts=
|
|
69
|
+
def self.configure(app, opts=OPTS)
|
|
73
70
|
app.instance_eval do
|
|
74
71
|
self.opts[:path_class_by_name] = opts.fetch(:by_name, ENV['RACK_ENV'] == 'development')
|
|
75
72
|
self.opts[:path_classes] ||= {}
|
|
@@ -92,7 +89,7 @@ class Roda
|
|
|
92
89
|
end
|
|
93
90
|
|
|
94
91
|
# Create a new instance method for the named path. See plugin module documentation for options.
|
|
95
|
-
def path(name, path=nil, opts=
|
|
92
|
+
def path(name, path=nil, opts=OPTS, &block)
|
|
96
93
|
if name.is_a?(Class)
|
|
97
94
|
raise RodaError, "can't provide path or options when calling path with a class" unless path.nil? && opts.empty?
|
|
98
95
|
raise RodaError, "must provide a block when calling path with a class" unless block
|
|
@@ -124,11 +121,13 @@ class Roda
|
|
|
124
121
|
if add_script_name || url || opts[:url_only]
|
|
125
122
|
_meth = "_#{meth}"
|
|
126
123
|
define_method(_meth, &block)
|
|
124
|
+
private _meth
|
|
127
125
|
end
|
|
128
126
|
|
|
129
127
|
unless opts[:url_only]
|
|
130
128
|
if add_script_name
|
|
131
129
|
define_method(meth) do |*a, &blk|
|
|
130
|
+
# Allow calling private _method to get path
|
|
132
131
|
request.script_name.to_s + send(_meth, *a, &blk)
|
|
133
132
|
end
|
|
134
133
|
else
|
|
@@ -149,6 +148,7 @@ class Roda
|
|
|
149
148
|
port = r.port
|
|
150
149
|
uri = ["#{scheme}://#{r.host}#{":#{port}" unless DEFAULT_PORTS[scheme] == port}"]
|
|
151
150
|
uri << request.script_name.to_s if add_script_name
|
|
151
|
+
# Allow calling private _method to get path
|
|
152
152
|
uri << send(_meth, *a, &blk)
|
|
153
153
|
File.join(uri)
|
|
154
154
|
end
|
|
@@ -9,7 +9,7 @@ class Roda
|
|
|
9
9
|
# It adds a :prefix matcher for matching on the path's prefix,
|
|
10
10
|
# yielding the rest of the matched segment:
|
|
11
11
|
#
|
|
12
|
-
# r.on :
|
|
12
|
+
# r.on prefix: 'foo' do |suffix|
|
|
13
13
|
# # Matches '/foo-bar', yielding '-bar'
|
|
14
14
|
# # Does not match bar-foo
|
|
15
15
|
# end
|
|
@@ -17,7 +17,7 @@ class Roda
|
|
|
17
17
|
# It adds a :suffix matcher for matching on the path's suffix,
|
|
18
18
|
# yielding the part of the segment before the suffix:
|
|
19
19
|
#
|
|
20
|
-
# r.on :
|
|
20
|
+
# r.on suffix: 'bar' do |prefix|
|
|
21
21
|
# # Matches '/foo-bar', yielding 'foo-'
|
|
22
22
|
# # Does not match bar-foo
|
|
23
23
|
# end
|
|
@@ -25,7 +25,7 @@ class Roda
|
|
|
25
25
|
# It adds an :extension matcher for matching on the given file extension,
|
|
26
26
|
# yielding the part of the segment before the extension:
|
|
27
27
|
#
|
|
28
|
-
# r.on :
|
|
28
|
+
# r.on extension: 'bar' do |reset|
|
|
29
29
|
# # Matches '/foo.bar', yielding 'foo'
|
|
30
30
|
# # Does not match bar.foo
|
|
31
31
|
# end
|
|
@@ -18,10 +18,10 @@ class Roda
|
|
|
18
18
|
#
|
|
19
19
|
# In some cases, you may want to override PATH_INFO for the rewritten
|
|
20
20
|
# paths, such as when you are passing the request to another Rack app.
|
|
21
|
-
# For those cases, you can use the <tt
|
|
21
|
+
# For those cases, you can use the <tt>path_info: true</tt> option to
|
|
22
22
|
# +rewrite_path+.
|
|
23
23
|
#
|
|
24
|
-
# rewrite_path '/a', '/b', :
|
|
24
|
+
# rewrite_path '/a', '/b', path_info: true
|
|
25
25
|
# # PATH_INFO '/a' => PATH_INFO '/b'
|
|
26
26
|
# # PATH_INFO '/a/c' => PATH_INFO '/b/c'
|
|
27
27
|
#
|
|
@@ -38,18 +38,13 @@ class Roda
|
|
|
38
38
|
#
|
|
39
39
|
# rewrite_path(/\A\/a\/(\w+)/){|match| "/a/#{match[1].capitalize}"}
|
|
40
40
|
# # PATH_INFO '/a/moo' => remaining_path '/a/Moo'
|
|
41
|
-
# rewrite_path(/\A\/a\/(\w+)/, :
|
|
41
|
+
# rewrite_path(/\A\/a\/(\w+)/, path_info: true){|match| "/a/#{match[1].capitalize}"}
|
|
42
42
|
# # PATH_INFO '/a/moo' => PATH_INFO '/a/Moo'
|
|
43
43
|
#
|
|
44
44
|
# All path rewrites are applied in order, so if a path is rewritten by one rewrite,
|
|
45
45
|
# it can be rewritten again by a later rewrite. Note that PATH_INFO rewrites are
|
|
46
46
|
# processed before remaining_path rewrites.
|
|
47
47
|
module PathRewriter
|
|
48
|
-
OPTS={}.freeze
|
|
49
|
-
RodaPlugins.deprecate_constant(self, :OPTS)
|
|
50
|
-
PATH_INFO = 'PATH_INFO'.freeze
|
|
51
|
-
RodaPlugins.deprecate_constant(self, :PATH_INFO)
|
|
52
|
-
|
|
53
48
|
def self.configure(app)
|
|
54
49
|
app.instance_exec do
|
|
55
50
|
app.opts[:remaining_path_rewrites] ||= []
|
|
@@ -67,7 +62,7 @@ class Roda
|
|
|
67
62
|
|
|
68
63
|
# Record a path rewrite from path +was+ to path +is+. Options:
|
|
69
64
|
# :path_info :: Modify PATH_INFO, not just remaining path.
|
|
70
|
-
def rewrite_path(was, is = nil, opts=
|
|
65
|
+
def rewrite_path(was, is = nil, opts=OPTS, &block)
|
|
71
66
|
if is.is_a? Hash
|
|
72
67
|
raise RodaError, "cannot provide two hashes to rewrite_path" unless opts.empty?
|
|
73
68
|
opts = is
|