make URL params available in filters with pattern.
Previously this was the only way to access parameters from pattern: before /:name do |name| ... end Now it is also possible to use params: before /:name do do_something params[:name] end
This commit is contained in:
parent
2233cdbf68
commit
739b6ba012
|
@ -494,13 +494,39 @@ module Sinatra
|
||||||
# Run routes defined on the class and all superclasses.
|
# Run routes defined on the class and all superclasses.
|
||||||
def route!(base=self.class, pass_block=nil)
|
def route!(base=self.class, pass_block=nil)
|
||||||
if routes = base.routes[@request.request_method]
|
if routes = base.routes[@request.request_method]
|
||||||
original_params = @params
|
|
||||||
|
|
||||||
path = unescape(@request.path_info)
|
|
||||||
path = "/" if path.empty?
|
|
||||||
|
|
||||||
routes.each do |pattern, keys, conditions, block|
|
routes.each do |pattern, keys, conditions, block|
|
||||||
if match = pattern.match(path)
|
pass_block = process_route(pattern, keys, conditions) do
|
||||||
|
route_eval(&block)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Run routes defined in superclass.
|
||||||
|
if base.superclass.respond_to?(:routes)
|
||||||
|
return route!(base.superclass, pass_block)
|
||||||
|
end
|
||||||
|
|
||||||
|
route_eval(&pass_block) if pass_block
|
||||||
|
route_missing
|
||||||
|
end
|
||||||
|
|
||||||
|
# Run a route block and throw :halt with the result.
|
||||||
|
def route_eval(&block)
|
||||||
|
throw :halt, instance_eval(&block)
|
||||||
|
end
|
||||||
|
|
||||||
|
# If the current request matches pattern and conditions, fill params
|
||||||
|
# with keys and call the given block.
|
||||||
|
# Revert params afterwards.
|
||||||
|
#
|
||||||
|
# Returns pass block.
|
||||||
|
def process_route(pattern, keys, conditions)
|
||||||
|
@original_params ||= @params
|
||||||
|
@path ||= begin
|
||||||
|
path = unescape(@request.path_info)
|
||||||
|
path.empty? ? "/" : path
|
||||||
|
end
|
||||||
|
if match = pattern.match(@path)
|
||||||
values = match.captures.to_a
|
values = match.captures.to_a
|
||||||
params =
|
params =
|
||||||
if keys.any?
|
if keys.any?
|
||||||
|
@ -517,34 +543,16 @@ module Sinatra
|
||||||
else
|
else
|
||||||
{}
|
{}
|
||||||
end
|
end
|
||||||
@params = original_params.merge(params)
|
@params = @original_params.merge(params)
|
||||||
@block_params = values
|
@block_params = values
|
||||||
|
catch(:pass) do
|
||||||
pass_block = catch(:pass) do
|
|
||||||
conditions.each { |cond|
|
conditions.each { |cond|
|
||||||
throw :pass if instance_eval(&cond) == false }
|
throw :pass if instance_eval(&cond) == false }
|
||||||
route_eval(&block)
|
yield
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
ensure
|
||||||
|
@params = @original_params
|
||||||
@params = original_params
|
|
||||||
end
|
|
||||||
|
|
||||||
# Run routes defined in superclass.
|
|
||||||
if base.superclass.respond_to?(:routes)
|
|
||||||
route! base.superclass, pass_block
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
route_eval(&pass_block) if pass_block
|
|
||||||
|
|
||||||
route_missing
|
|
||||||
end
|
|
||||||
|
|
||||||
# Run a route block and throw :halt with the result.
|
|
||||||
def route_eval(&block)
|
|
||||||
throw :halt, instance_eval(&block)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# No matching route was found or all routes passed. The default
|
# No matching route was found or all routes passed. The default
|
||||||
|
@ -828,11 +836,9 @@ module Sinatra
|
||||||
# add a filter
|
# add a filter
|
||||||
def add_filter(type, path = nil, &block)
|
def add_filter(type, path = nil, &block)
|
||||||
return filters[type] << block unless path
|
return filters[type] << block unless path
|
||||||
block, pattern = compile!(type, path, block)
|
block, *arguments = compile!(type, path, block)
|
||||||
add_filter(type) do
|
add_filter(type) do
|
||||||
next unless match = pattern.match(request.path_info)
|
process_route(*arguments) { instance_eval(&block) }
|
||||||
@block_params = match.captures.to_a
|
|
||||||
instance_eval(&block)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -896,8 +902,7 @@ module Sinatra
|
||||||
host_name(options.delete(:host)) if options.key?(:host)
|
host_name(options.delete(:host)) if options.key?(:host)
|
||||||
options.each { |option, args| send(option, *args) }
|
options.each { |option, args| send(option, *args) }
|
||||||
|
|
||||||
block, pattern, keys = compile! verb, path, block
|
block, pattern, keys, conditions = compile! verb, path, block
|
||||||
conditions, @conditions = @conditions, []
|
|
||||||
invoke_hook(:route_added, verb, path, block)
|
invoke_hook(:route_added, verb, path, block)
|
||||||
|
|
||||||
(@routes[verb] ||= []).
|
(@routes[verb] ||= []).
|
||||||
|
@ -910,12 +915,17 @@ module Sinatra
|
||||||
|
|
||||||
def compile!(verb, path, block)
|
def compile!(verb, path, block)
|
||||||
method_name = "#{verb} #{path}"
|
method_name = "#{verb} #{path}"
|
||||||
|
|
||||||
define_method(method_name, &block)
|
define_method(method_name, &block)
|
||||||
unbound_method = instance_method method_name
|
unbound_method = instance_method method_name
|
||||||
|
pattern, keys = compile(path)
|
||||||
|
conditions, @conditions = @conditions, []
|
||||||
remove_method method_name
|
remove_method method_name
|
||||||
[block.arity != 0 ?
|
|
||||||
|
[ block.arity != 0 ?
|
||||||
proc { unbound_method.bind(self).call(*@block_params) } :
|
proc { unbound_method.bind(self).call(*@block_params) } :
|
||||||
proc { unbound_method.bind(self).call }, *compile(path)]
|
proc { unbound_method.bind(self).call },
|
||||||
|
pattern, keys, conditions ]
|
||||||
end
|
end
|
||||||
|
|
||||||
def compile(path)
|
def compile(path)
|
||||||
|
|
|
@ -264,4 +264,17 @@ class AfterFilterTest < Test::Unit::TestCase
|
||||||
get '/foo/bar'
|
get '/foo/bar'
|
||||||
assert_equal subpath, 'bar'
|
assert_equal subpath, 'bar'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'is possible to access url params from the route param' do
|
||||||
|
ran = false
|
||||||
|
mock_app do
|
||||||
|
get('/foo/*') { }
|
||||||
|
before('/foo/:sub') do
|
||||||
|
assert_equal params[:sub], 'bar'
|
||||||
|
ran = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
get '/foo/bar'
|
||||||
|
assert ran
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue