Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 441 lines (271 sloc) 8.422 kb
df800b5 Docs are started
Blake Mizerany authored
1 = Sinatra
2
3 Sinatra a DSL for quickly creating web-applications in Ruby with minimal effort.
4
5 = Sample app:
6
7 # myapp.rb
8
9 require 'rubygems'
10 require 'sinatra'
11
12 get '/' do
13 'Hello world!'
14 end
15
16 Ruby this as <tt>ruby myapp.rb</tt> and view at <tt>http://localhost:4567</tt>
17
18 = RESTful
19
20 get '/' do
21 .. show things ..
22 end
23
24 post '/' do
25 .. create something ..
26 end
27
28 put '/' do
29 .. update something ..
30 end
31
32 delete '/' do
33 .. annihilate something ..
34 end
1776a80 Added Version and Docs
Blake Mizerany authored
35
36 head '/' do
37
38 end
39
40 NOTE: <tt>put</tt> and <tt>delete</tt> are triggered when a <tt>_method</tt> param is set to PUT or DELETE and the HTTP_REQUEST_METHOD is a POST
41
42 = Routes
43
44 NOTE: Routes are looked up in order of declaration
45
46 Simple
47
48 get '/hi' do
49 ...
50 end
51
52 With params
53
54 get '/:name' do
55 # matches /sinatra and the like and sets params[:name]
56 end
57
58 Splat'n
59
9c85e99 @vic Specs, documentation and fixes for splat'n routes
vic authored
60 get '/say/*/to/*' do
61 # matches /say/hello/to/world
62 params["splat"] # => ["hello", "world"]
63 end
64
65 get '/download/*.*' do
66 # matches /download/path/to/file.xml
67 params["splat"] # => ["path/to/file", "xml"]
1776a80 Added Version and Docs
Blake Mizerany authored
68 end
69
70 Get an agent!
71
72 get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
73 "You're using Songbird version #{params[:agent][0]}"
74 end
75
76 get '/foo' do
77 # matches non-songbird browsers
78 end
df800b5 Docs are started
Blake Mizerany authored
79
047edc6 update README with Static help
Blake Mizerany authored
80 = Static files
81
82 Put all of your static content in the ./public directory
83
84 root
85 \ public
86
87 If a file exists that maps to the REQUEST_PATH then it is served and the request end; Sinatra will look for and event that matches the path otherwise
88
df800b5 Docs are started
Blake Mizerany authored
89 = Views (if you need MVC)
90
91 All views are looked up in:
92
93 root
94 | - views/
95
96
97 == Templates
98
4144ac1 @nmeans Added Sass information to documentation.
nmeans authored
99 === Haml
df800b5 Docs are started
Blake Mizerany authored
100
101 get '/' do
102 haml :index
103 end
104
105 This will render <tt>./views/index.haml</tt>
106
4144ac1 @nmeans Added Sass information to documentation.
nmeans authored
107 === Sass
108 get '/stylesheet.css' do
ccc19b0 @rtomayko content_type response helper with mime type lookup and parameter support...
rtomayko authored
109 content_type 'text/css', :charset => 'utf-8'
4144ac1 @nmeans Added Sass information to documentation.
nmeans authored
110 sass :stylesheet
111 end
112
113 This will render <tt>./views/stylesheet.sass</tt>
114
df800b5 Docs are started
Blake Mizerany authored
115 === Inline
116
117 get '/' do
118 haml '%div.title Hello World'
119 end
120
121 This will render the inlined template string
122
123 === Accessing Variables
124
125 Templates are rendered in the context the current Sinatra::EventContext. This means you get all instance/class variables and methods it has access to.
126
127 get '/:id' do
128 @foo = Foo.find(params[:id])
129 haml '%h1== @foo.name'
130 end
131
132 Send local objects like:
133
134 get '/:id' do
135 localvar = Foo.find(params[:id])
136 haml '%h1== localvar.name', :locals => { :localvar => localvar }
137 end
138
139 This is more ideal for rendering templates as partials from within templates
140
83cba9c @bmizerany updated README with helpful tidbits
bmizerany authored
141 == In file templates
142
143 This one is cool:
144
145 get '/' do
146 haml :index
147 end
148
149 use_in_file_templates!
150
151 __END__
152
153 ## layout
154 X
155 = yield
156 X
157
158 ## index
159 %div.title Hello world!!!!!
160
161 Try it!
162
163 = You can do this too but it's not as cool
164
165 template :layout do
166 "X\n=yield\nX"
167 end
168
169 template :index do
170 '%div.title Hello World!'
171 end
172
173 get '/' do
174 haml :index
175 end
176
df800b5 Docs are started
Blake Mizerany authored
177 === Erb
178
179 This works like Haml except you use <tt>erb</tt> instead of <tt>haml</tt>
180
4144ac1 @nmeans Added Sass information to documentation.
nmeans authored
181 === Sass
182
ccc19b0 @rtomayko content_type response helper with mime type lookup and parameter support...
rtomayko authored
183 This works like Haml except you use <tt>sass</tt> instead of <tt>haml</tt>. It's also a good idea to add <tt>content_type 'text/css', :charset => 'utf-8'</tt> before your call to <tt>sass</tt> so Sinatra returns the proper content type header with the file.
4144ac1 @nmeans Added Sass information to documentation.
nmeans authored
184
1f20499 getting mare advanced with to_result
Blake Mizerany authored
185 === Builder
186
187 See Sinatra::Builder
188
df800b5 Docs are started
Blake Mizerany authored
189 = Helpers
190
191 It is ill-advised to create helpers on (main). Use the handy <tt>helpers</tt> to install helper methods on Sinatra::EventContext for use inside events and templates.
192
193 Example:
194
195 helpers do
196
197 def bar(name)
198 "#{name}bar"
199 end
200
201 end
1776a80 Added Version and Docs
Blake Mizerany authored
202
203 get '/:name' do
204 bar(params[:name])
205 end
df800b5 Docs are started
Blake Mizerany authored
206
207 = Before filters
208
1776a80 Added Version and Docs
Blake Mizerany authored
209 These are run in Sinatra::EventContext
210
df800b5 Docs are started
Blake Mizerany authored
211 before do
212 .. this code will run before each event ..
213 end
214
215 = Halt!
216
217 To immediately stop a request during a before filter or event use:
218
219 throw :halt
220
221 === Variations
222
223 Set the body to the result of a helper method
224
225 throw :halt, :helper_method
226
227 Set the body to the result of a helper method after sending it parameters from the local scope
228
229 throw :halt, [:helper_method, foo, bar]
230
231 Set the body to a simple string
232
233 throw :halt, 'this will be the body'
234
235 Set status then the body
236
237 throw :halt, [401, 'go away!']
238
239 Set the status then call a helper method with params from local scope
240
241 throw :halt, [401, [:helper_method, foo, bar]]
242
243 Run a proc inside the Sinatra::EventContext instance and set the body to the result
244
245 throw :halt, lambda { puts 'In a proc!'; 'I just wrote to $stdout!' }
246
247 Create you own to_result
248
249 class MyResultObject
250 def to_result(event_context, *args)
251 event_context.body = 'This will be the body!
252 end
253 end
254
255 get '/' do
256 throw :halt, MyResultObject.new
257 end
258
259 Get the gist? If you want more fun with this then checkout <tt>to_result</tt> on Array, Symbol, Fixnum, NilClass.
260
1776a80 Added Version and Docs
Blake Mizerany authored
261 = Configuration & Re-loading
262
263 Sinatra supports multiple environments and re-loading. Re-loading happens on every request when in :development. Wrap your configurations in <tt>configure</tt> (i.e. Database connections, Constants, etc.) to protect them from re-loading and to only work in certain environments.
264
265 All environments:
266
267 configure do
268
269 end
270
271 Production
272
273 configure :production do
274
275 end
276
277 Two at a time:
278
279 configure :production, :test do
280
281 end
282
283 This is also really nifty for error handling.
284
285 = Error handling
286
287 === Not Found
288
289 Remember: These are run inside the Sinatra::EventContext which means you get all the goodies is has to offer (i.e. haml, erb, :halt, etc.)
290
291 Whenever NotFound is raised this will be called
292
293 not_found do
294 'This is nowhere to be found'
295 end
296
297 === Error
83cba9c @bmizerany updated README with helpful tidbits
bmizerany authored
298
299 By default +error+ will catch Sinatra::ServerError
300
301 Sinatra will pass you the error via the 'sinatra.error' in request.env
302
1776a80 Added Version and Docs
Blake Mizerany authored
303 error do
83cba9c @bmizerany updated README with helpful tidbits
bmizerany authored
304 'Sorry there was a nasty error - ' + request.env['sinatra.error'].name
305 end
306
307 Custom error mapping:
308
309 error MyCustomError do
e7e0e55 @rtomayko Minor docfixes in README.rdoc
rtomayko authored
310 'So what happened was...' + request.env['sinatra.error'].message
1776a80 Added Version and Docs
Blake Mizerany authored
311 end
83cba9c @bmizerany updated README with helpful tidbits
bmizerany authored
312
313 then if this happens:
314
315 get '/' do
316 raise MyCustomError, 'something bad'
317 end
318
319 you gets this:
320
321 So what happened was... something bad
322
323 one guess what this does ;)
324
325 not_found do
326 'I have no clue what you're looking for'
327 end
328
329 Try it!
330
1776a80 Added Version and Docs
Blake Mizerany authored
331
332 Because Sinatra give you a default <tt>not_found</tt> and <tt>error</tt> do :production that are secure. If you want to customize only for :production but want to keep the friendly helper screens for :development then do this:
333
334 configure :production do
335
336 not_found do
337 "We're so sorry, but we don't what this is"
338 end
339
340 error do
341 "Something really nasty happened. We're on it!"
342 end
343
344 end
83cba9c @bmizerany updated README with helpful tidbits
bmizerany authored
345
346 = Mime types
347
348 When using send_file or static files you may have mime types Sinatra doesn't understand. Use +mime+ in those cases.
349
350 mime :foo, 'text/foo'
1776a80 Added Version and Docs
Blake Mizerany authored
351
352 = Testing
353
28b1285 better docs on testing
Blake Mizerany authored
354 === Methods
355
356 get_it path, params
357 get_it path, params.merge(:env => { 'HTTP_HOST' => 'www.sinatrarb.com' }) or
358 get_it path, params.merge(:env => { :host => 'www.sinatrarb.com' })
359
360 RESTful:
361
362 post_it '/foo', '<myxml></myxml>', 'HTTP_ACCEPT' => 'application/xml'
363
364 also works with:
365
366 get_it, post_it, put_it, delete_it, head_it
367
1776a80 Added Version and Docs
Blake Mizerany authored
368 === Test/Unit
369
370 require 'my_sinatra_app'
371 require 'sinatra/test/unit'
372
373 class MyAppTest < Test::Unit::TestCase
374
375 def test_my_default
376 get_it '/'
377 assert_equal 'My Default Page!', @response.body
378 end
379
380 def test_with_agent
381 get_it '/', :agent => 'Songbird'
382 assert_equal 'You're in Songbird!', @response.body
383 end
384
385 ...
386
387 end
388
389 === Test/Spec
390
391 require 'my_sinatra_app'
392 require 'sinatra/test/spec'
393
394 context 'My app'
395
396 should "show a default page" do
397 get_it '/'
398 should.be.ok
83cba9c @bmizerany updated README with helpful tidbits
bmizerany authored
399 body.should.equal 'My Default Page!'
1776a80 Added Version and Docs
Blake Mizerany authored
400 end
401 ...
402
403 end
404
405 == Test helpers
406
407 See Sinatra::Test::Methods
408
409 = Irb
410
411 This will be back in soon
412
413 = Command line
414
415 Run your sinatra file like:
416
417 ruby myapp.rb [options]
418
419 Options are:
420
421 -h # help
422 -p # set the port (default is 4567)
423 -e # set the environment (default is development)
e7e0e55 @rtomayko Minor docfixes in README.rdoc
rtomayko authored
424 -x # turn on the mutex lock (default is off)
1776a80 Added Version and Docs
Blake Mizerany authored
425
426 = Contribute
427
428 cd where/you/keep/your/projects
429 git clone git://github.com/bmizerany/sinatra.git
430 cd your_project
431 ln -s ../sinatra/
432
433 at the top of your sinatra.rb file
434
435 $:.unshift File.dirname(__FILE__) + '/sinatra/lib'
436 require 'sinatra'
437
438 get '/about' do
439 "I'm running on Version " + Sinatra::Version.combined
440 end
Something went wrong with that request. Please try again.