1
0
Fork 0
mirror of https://github.com/sinatra/sinatra synced 2023-03-27 23:18:01 -04:00

before-filters with docs

This commit is contained in:
Blake Mizerany 2007-10-07 18:24:32 -07:00
parent ea3bc95b12
commit 143d8caa28
3 changed files with 82 additions and 11 deletions

View file

@ -54,11 +54,34 @@ module Sinatra
Sinatra::Event.new(:delete, path, &block)
end
# Run given block after each Event's execution
# Usage:
# before_attend do
# logger.debug "After event attend!"
# end
# or
# before_attend :authorize # authorize is a helper method defined using helpers
#
# Stop execution using - throw :halt
# before_attend do
# throw :halt, 401 unless has_access?
# end
# Throw a Symbol to execute a helper method
# Throw a String to render it as the content
# Throw a Fixnum to set the status
#
def before_attend(filter_name = nil, &block)
Sinatra::Event.before_attend(filter_name, &block)
end
# Run given block after each Event's execution
# Example:
# after_attend do
# logger.debug "After event attend!"
# end
# or
# after_attend :clean_up # clean_up is a helper method defined using helpers
#
def after_attend(filter_name = nil, &block)
Sinatra::Event.after_attend(filter_name, &block)
end

View file

@ -45,13 +45,28 @@ module Sinatra
cattr_accessor :logger
cattr_accessor :after_filters
cattr_accessor :before_filters
@@mutex = Mutex.new
self.before_filters = []
self.after_filters = []
def self.after_attend(filter)
after_filters << filter
def self.before_attend(method_name = nil, &block)
setup_filter(:before_filters, method_name, &block)
end
def self.after_attend(method_name = nil, &block)
setup_filter(:after_filters, method_name, &block)
end
def self.setup_filter(filter_set_name, method_name, &block)
raise "Must specify method or block" if method_name.nil? and !block_given?
send(filter_set_name) << if block_given?
block
else
method_name
end
end
after_attend :log_event
@ -69,13 +84,27 @@ module Sinatra
def attend(request)
request.params.merge!(@route.params)
context = EventContext.new(request)
begin
result = run_safely { context.instance_eval(&@block) if @block }
context.body context.body || result || ''
rescue => e
context.error e
run_safely do
caught = catch(:halt) do
call_filters(before_filters, context)
end
body = case caught
when :filter_chain_completed
begin
context.instance_eval(&@block) if @block
rescue => e
context.error e
end
when Symbol
context.send(caught)
when String
caught
when Fixnum
context.status caught
end
context.body context.body || body || ''
call_filters(after_filters, context)
end
run_safely { run_through_after_filters(context) }
context
end
alias :call :attend
@ -96,8 +125,18 @@ module Sinatra
end
end
def run_through_after_filters(context)
after_filters.each { |filter| context.send(filter) }
# Adapted from Merb
# calls a filter chain according to rules.
def call_filters(filter_set, context)
filter_set.each do |filter|
case filter
when Symbol, String
context.send(filter)
when Proc
context.instance_eval(&filter)
end
end
:filter_chain_completed
end
end

View file

@ -34,4 +34,13 @@ describe "Event" do
Sinatra::EventManager.determine_event(:get, '/asdfsasd')
end
it "should not execute event if halted" do
Sinatra::Event.before_filters << lambda { throw :halt, 'whoa!' }
event = Sinatra::Event.new(:get, '/') do
foo
end
event.expects(:foo).never
get_it('/').should.equal 'whoa!'
end
end