FIX: StaticEvents should ignore directories during path recognition
[sinatra.git] / lib / sinatra / dsl.rb
blob3ae42f3892e0f2031da73fc93424b711dd818794
2 module Sinatra
4   module Dsl
6     # Define an Event that responds to a +path+ on GET method
7     # 
8     # The +path+ can be a template (i.e. '/:foo/bar/:baz').  When recognized, it will add <tt>:foo</tt> and <tt>:baz</tt> to +params+ with their values.
9     #
10     # Example:
11     #   # Going RESTful
12     #
13     #   get '/' do
14     #     .. show stuff ..
15     #   end
16     #   
17     #   post '/' do
18     #     .. add stuff ..
19     #     redirect '/'
20     #   end
21     #   
22     #   put '/:id' do
23     #     .. update params[:id] ..
24     #     redirect '/'
25     #   end
26     #   
27     #   delete '/:id' do
28     #     .. delete params[:id] ..
29     #     redirect '/'
30     #   end
31     #
32     # BIG NOTE: PUT and DELETE are trigged when POSTing to their paths with a <tt>_method</tt> param whose value is PUT or DELETE
33     #
34     def get(path, &block)
35       Sinatra::Event.new(:get, path, &block)
36     end
38     # Same as get but responds to POST
39     def post(path, &block)
40       Sinatra::Event.new(:post, path, &block)
41     end
43     # Same as get but responds to PUT
44     #
45     # BIG NOTE: PUT and DELETE are trigged when POSTing to their paths with a <tt>_method</tt> param whose value is PUT or DELETE
46     def put(path, &block)
47       Sinatra::Event.new(:put, path, &block)
48     end
50     # Same as get but responds to DELETE
51     #
52     # BIG NOTE: PUT and DELETE are trigged when POSTing to their paths with a <tt>_method</tt> param whose value is PUT or DELETE
53     def delete(path, &block)
54       Sinatra::Event.new(:delete, path, &block)
55     end
57     # Run given block after each Event's execution
58     # Usage:
59     #   before_attend do
60     #     logger.debug "After event attend!"
61     #   end
62     # or
63     #   before_attend :authorize # authorize is a helper method defined using helpers
64     #
65     # Stop execution using - throw :halt
66     #   before_attend do
67     #     throw :halt, 401 unless has_access?
68     #   end
69     # Throw a Symbol to execute a helper method
70     # Throw a String to render it as the content
71     # Throw a Fixnum to set the status
72     #
73     def before_attend(filter_name = nil, &block)
74       Sinatra::Event.before_attend(filter_name, &block)
75     end
77     # Run given block after each Event's execution
78     # Example:
79     #   after_attend do
80     #     logger.debug "After event attend!"
81     #   end
82     # or 
83     #   after_attend :clean_up  # clean_up is a helper method defined using helpers
84     #
85     def after_attend(filter_name = nil, &block)
86       Sinatra::Event.after_attend(filter_name, &block)
87     end
88   
89     # Add methods to each event for use during execution
90     #
91     # Example:
92     #   helpers do
93     #     def foo
94     #       'foo!'
95     #     end
96     #   end
97     #   
98     #   get '/bar' do
99     #     foo
100     #   end
101     #   
102     #   get_it '/bar' # => 'foo!'
103     #
104     def helpers(&block)
105       Sinatra::EventContext.class_eval(&block)
106     end
108     # Maps a path to a physical directory containing static files
109     #
110     # Example:
111     #   static '/p', 'public'
112     #
113     def static(path, root)
114       Sinatra::StaticEvent.new(path, root)
115     end
116     
117     # Execute block if in development mode (Used for configuration)
118     def development
119       yield if Sinatra::Options.environment == :development
120     end
121   
122     # Execute block if in production mode (Used for configuration)
123     def production
124       yield if Sinatra::Options.environment == :production
125     end
126   
127     # Execute block if in test mode (Used for configuration)
128     # def test
129     #   yield if Sinatra::Options.environment == :test
130     # end
131   
132     # Define named layouts (default name is <tt>:layout</tt>)
133     # 
134     # Examples:
135     #   # Default layout in Erb
136     #   layout do
137     #     '-- <%= yield %> --'
138     #   end
139     #   
140     #   # Named layout in Haml
141     #   layout :for_haml do
142     #     '== XXXX #{yield} XXXX'
143     #   end
144     #   
145     #   # Loads layout named <tt>:"foo.erb"</tt> from file (default behaviour if block is omitted)
146     #   layout 'foo.erb' # looks for foo.erb.  This is odd an is being re-thought
147     #   
148     #   def layout(name = :layout, options = {})
149     #     Layouts[name] = unless block_given?
150     #       File.read("%s/%s" % [options[:views_directory] || 'views', name])
151     #     else
152     #       yield
153     #     end
154     #   end
155     #
156     # Cool trick:
157     #   
158     #   # Send a one-time layout to renderer method
159     #   get '/cooltrick' do
160     #     erb 'wicked' do
161     #       'Cool <%= yield %> Trick'
162     #     end
163     #   end
164     #   
165     #   get_it '/cooltrick' # => 'Cool wicked Trick'
166     #
167     def layout(name = :layout, options = {})
168       Layouts[name] = unless block_given?
169         File.read("%s/%s" % [options[:views_directory] || 'views', name])
170       else
171         yield
172       end
173     end  
174   
175     # Turn sessions <tt>:on</tt> or <tt>:off</tt>
176     #  
177     # NOTE:  There is currently no way to turn it on or off per Event... patches anyone?)
178     def sessions(on_off)
179       Sinatra::Session::Cookie.use = on_off
180     end
182   end
186 include Sinatra::Dsl