Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 505 lines (312 sloc) 11.165 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
f71330e @bmizerany quick doc fix
bmizerany authored
91 All file-based views are looked up in:
df800b5 Docs are started
Blake Mizerany authored
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 supp…
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
f71330e @bmizerany quick doc fix
bmizerany authored
153 @@ layout
83cba9c @bmizerany updated README with helpful tidbits
bmizerany authored
154 X
155 = yield
156 X
157
f71330e @bmizerany quick doc fix
bmizerany authored
158 @@ index
83cba9c @bmizerany updated README with helpful tidbits
bmizerany authored
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 supp…
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
a766406 @rtomayko add doc on using Rack middleware to README
rtomayko authored
352 = Using Rack Middleware
353
354 Sinatra rides on Rack[http://rack.rubyforge.org/], a minimal standard interface for Ruby web frameworks. One of Rack's most interesting capabilities for application developers is support for "middleware" -- components that sit between the server and your application monitoring and/or manipulating the HTTP request/response to provide various types of common functionality. What's more, middleware is portable between web frameworks, so middleware components developed under, e.g., Merb, can be used with Sinatra and vice versa.
355
356 Sinatra makes building Rack middleware pipelines a cinch via a top-level +use+ method:
357
358 require 'sinatra'
359 require 'my_custom_middleware'
360
361 use Rack::Lint
362 use MyCustomMiddleware
363
364 get '/hello' do
365 'Hello World'
366 end
367
368 The semantics of +use+ are identical to those defined for the Rack::Builder[http://rack.rubyforge.org/doc/classes/Rack/Builder.html] DSL (most frequently used from rackup files). For example, the +use+ method accepts multiple/variable args as well as blocks:
369
370 use Rack::Auth::Basic do |username, password|
371 username == 'admin' && password == 'secret'
372 end
373
374 Rack is distributed with a variety of standard middleware for logging, debugging, URL routing, authentication, and session handling. Sinatra uses many of of these components automatically based on configuration so you typically don't have to +use+ them explicitly.
375
1776a80 Added Version and Docs
Blake Mizerany authored
376 = Testing
377
28b1285 better docs on testing
Blake Mizerany authored
378 === Methods
379
380 get_it path, params
381 get_it path, params.merge(:env => { 'HTTP_HOST' => 'www.sinatrarb.com' }) or
382 get_it path, params.merge(:env => { :host => 'www.sinatrarb.com' })
383
384 RESTful:
385
386 post_it '/foo', '<myxml></myxml>', 'HTTP_ACCEPT' => 'application/xml'
387
388 also works with:
389
390 get_it, post_it, put_it, delete_it, head_it
391
1776a80 Added Version and Docs
Blake Mizerany authored
392 === Test/Unit
393
394 require 'my_sinatra_app'
395 require 'sinatra/test/unit'
396
397 class MyAppTest < Test::Unit::TestCase
398
399 def test_my_default
400 get_it '/'
401 assert_equal 'My Default Page!', @response.body
402 end
403
404 def test_with_agent
405 get_it '/', :agent => 'Songbird'
406 assert_equal 'You're in Songbird!', @response.body
407 end
408
409 ...
410
411 end
412
413 === Test/Spec
414
415 require 'my_sinatra_app'
416 require 'sinatra/test/spec'
417
418 context 'My app'
419
420 should "show a default page" do
421 get_it '/'
422 should.be.ok
83cba9c @bmizerany updated README with helpful tidbits
bmizerany authored
423 body.should.equal 'My Default Page!'
1776a80 Added Version and Docs
Blake Mizerany authored
424 end
425 ...
426
427 end
428
429 == Test helpers
430
431 See Sinatra::Test::Methods
432
433 = Irb
434
435 This will be back in soon
436
437 = Command line
438
439 Run your sinatra file like:
440
441 ruby myapp.rb [options]
442
443 Options are:
444
445 -h # help
446 -p # set the port (default is 4567)
447 -e # set the environment (default is development)
e7e0e55 @rtomayko Minor docfixes in README.rdoc
rtomayko authored
448 -x # turn on the mutex lock (default is off)
1776a80 Added Version and Docs
Blake Mizerany authored
449
450 = Contribute
451
6326809 @cypher Add a subsection about tools needed for Sinatra to the Contributing s…
cypher authored
452 == Tools
453
454 Besides Ruby itself, you only need a text editor, preferably one that supports Ruby
455 syntax hilighting. VIM and Emacs are a fine choice on any platform, but feel free to
456 use whatever you're familiar with.
457
458 Sinatra uses the Git source code management system. If you're unfamiliar with Git,
459 you can find more information and tutorials on http://git.or.cz/ as well as http://git-scm.com/.
460 Scott Chacon created a great series of introductory screencasts about Git,
461 which you can find here: http://www.gitcasts.com/
462
4c02878 @cypher Update Contributing section to include initialization and updating th…
cypher authored
463 == First Time: Cloning the sinatra repo
464
1776a80 Added Version and Docs
Blake Mizerany authored
465 cd where/you/keep/your/projects
466 git clone git://github.com/bmizerany/sinatra.git
4c02878 @cypher Update Contributing section to include initialization and updating th…
cypher authored
467 cd sinatra
468 git submodule update --init
469 cd path/to/your_project
1776a80 Added Version and Docs
Blake Mizerany authored
470 ln -s ../sinatra/
4c02878 @cypher Update Contributing section to include initialization and updating th…
cypher authored
471
472 == Updating your existing Sinatra clone
473
474 cd where/you/keep/sinatra
475 git pull
476 git submodule update --init
477
478 == Using edge Sinatra in your app
1776a80 Added Version and Docs
Blake Mizerany authored
479
4c02878 @cypher Update Contributing section to include initialization and updating th…
cypher authored
480 at the top of your sinatra_app.rb file:
1776a80 Added Version and Docs
Blake Mizerany authored
481
482 $:.unshift File.dirname(__FILE__) + '/sinatra/lib'
483 require 'sinatra'
484
485 get '/about' do
486 "I'm running on Version " + Sinatra::Version.combined
487 end
e6c5471 @cypher Add a community section with info about the mailing list and irc channel
cypher authored
488
489 = Community
490
491 == Mailing List
492
493 http://groups.google.com/group/sinatrarb
494
495 If you have a problem or question, please make sure to include all the relevant
496 information in your mail, like the Sinatra version you're using, what version of Ruby
497 you have, and so on.
498
499 == IRC Channel
500
501 You can find us on the Freenode network in the channel #sinatra (irc://chat.freenode.net/#sinatra)
502
503 There's usually someone online at any given time, but since we cannot pay attention to the
504 channel all the time, so please stick around for a while after asking a question.
Something went wrong with that request. Please try again.