sinatra 1.0 → 1.1.a

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sinatra might be problematic. Click here for more details.

Files changed (57) hide show
  1. data/CHANGES +108 -1
  2. data/LICENSE +1 -1
  3. data/README.de.rdoc +1024 -0
  4. data/README.es.rdoc +1047 -0
  5. data/README.fr.rdoc +1038 -0
  6. data/README.hu.rdoc +607 -0
  7. data/README.jp.rdoc +473 -15
  8. data/README.rdoc +429 -41
  9. data/Rakefile +17 -6
  10. data/lib/sinatra/base.rb +357 -158
  11. data/lib/sinatra/showexceptions.rb +9 -1
  12. data/sinatra.gemspec +52 -9
  13. data/test/builder_test.rb +25 -1
  14. data/test/coffee_test.rb +88 -0
  15. data/test/encoding_test.rb +18 -0
  16. data/test/filter_test.rb +61 -2
  17. data/test/hello.mab +1 -0
  18. data/test/helper.rb +1 -0
  19. data/test/helpers_test.rb +141 -37
  20. data/test/less_test.rb +26 -2
  21. data/test/liquid_test.rb +58 -0
  22. data/test/markaby_test.rb +58 -0
  23. data/test/markdown_test.rb +35 -0
  24. data/test/nokogiri_test.rb +69 -0
  25. data/test/radius_test.rb +59 -0
  26. data/test/rdoc_test.rb +34 -0
  27. data/test/request_test.rb +12 -0
  28. data/test/routing_test.rb +35 -1
  29. data/test/sass_test.rb +46 -16
  30. data/test/scss_test.rb +88 -0
  31. data/test/settings_test.rb +32 -0
  32. data/test/sinatra_test.rb +4 -0
  33. data/test/static_test.rb +64 -0
  34. data/test/templates_test.rb +55 -1
  35. data/test/textile_test.rb +34 -0
  36. data/test/views/ascii.haml +2 -0
  37. data/test/views/explicitly_nested.str +1 -0
  38. data/test/views/hello.coffee +1 -0
  39. data/test/views/hello.liquid +1 -0
  40. data/test/views/hello.mab +1 -0
  41. data/test/views/hello.md +1 -0
  42. data/test/views/hello.nokogiri +1 -0
  43. data/test/views/hello.radius +1 -0
  44. data/test/views/hello.rdoc +1 -0
  45. data/test/views/hello.sass +1 -1
  46. data/test/views/hello.scss +3 -0
  47. data/test/views/hello.str +1 -0
  48. data/test/views/hello.textile +1 -0
  49. data/test/views/layout2.liquid +2 -0
  50. data/test/views/layout2.mab +2 -0
  51. data/test/views/layout2.nokogiri +3 -0
  52. data/test/views/layout2.radius +2 -0
  53. data/test/views/layout2.str +2 -0
  54. data/test/views/nested.str +1 -0
  55. data/test/views/utf8.haml +2 -0
  56. metadata +240 -33
  57. data/lib/sinatra/tilt.rb +0 -746
@@ -4,16 +4,16 @@ Sinatra is a DSL for quickly creating web applications in Ruby with minimal
4
4
  effort:
5
5
 
6
6
  # myapp.rb
7
- require 'rubygems'
8
7
  require 'sinatra'
8
+
9
9
  get '/' do
10
10
  'Hello world!'
11
11
  end
12
12
 
13
13
  Install the gem and run with:
14
14
 
15
- sudo gem install sinatra
16
- ruby myapp.rb
15
+ gem install sinatra
16
+ ruby -rubygems myapp.rb
17
17
 
18
18
  View at: http://localhost:4567
19
19
 
@@ -81,6 +81,8 @@ Or with a block parameter:
81
81
  "Hello, #{c}!"
82
82
  end
83
83
 
84
+ === Conditions
85
+
84
86
  Routes may include a variety of matching conditions, such as the user agent:
85
87
 
86
88
  get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
@@ -91,6 +93,57 @@ Routes may include a variety of matching conditions, such as the user agent:
91
93
  # Matches non-songbird browsers
92
94
  end
93
95
 
96
+ Other available conditions are +host_name+ and +provides+:
97
+
98
+ get '/', :host_name => /^admin\./ do
99
+ "Admin Area, Access denied!"
100
+ end
101
+
102
+ get '/', :provides => 'html' do
103
+ haml :index
104
+ end
105
+
106
+ get '/', :provides => ['rss', 'atom', 'xml'] do
107
+ builder :feed
108
+ end
109
+
110
+ You can easily define your own conditions:
111
+
112
+ set(:probability) { |value| condition { rand <= value } }
113
+
114
+ get '/win_a_car', :probability => 0.1 do
115
+ "You won!"
116
+ end
117
+
118
+ get '/win_a_car' do
119
+ "Sorry, you lost."
120
+ end
121
+
122
+ === Return values
123
+
124
+ The return value of a route block determines at least the response body passed
125
+ on to the HTTP client, or at least the next middleware in the Rack stack.
126
+ Most commonly this is a string, as in the above examples. But other values are
127
+ also accepted.
128
+
129
+ You can return any object that would either be a valid Rack response, Rack
130
+ body object or HTTP status code:
131
+
132
+ * An Array with three elements: <tt>[status (Fixnum), headers (Hash), response body (responds to #each)]</tt>
133
+ * An Array with two elements: <tt>[status (Fixnum), response body (responds to #each)]</tt>
134
+ * An object that responds to <tt>#each</tt> and passes nothing but strings to the given block
135
+ * A Fixnum representing the status code
136
+
137
+ That way we can for instance easily implement a streaming example:
138
+
139
+ class Stream
140
+ def each
141
+ 100.times { |i| yield "#{i}\n" }
142
+ end
143
+ end
144
+
145
+ get('/') { Stream.new }
146
+
94
147
  == Static Files
95
148
 
96
149
  Static files are served from the <tt>./public</tt> directory. You can specify
@@ -111,8 +164,9 @@ directory. To use a different views directory:
111
164
 
112
165
  One important thing to remember is that you always have to reference
113
166
  templates with symbols, even if they're in a subdirectory (in this
114
- case use <tt>:'subdir/template'</tt>). Rendering methods will render
115
- any strings passed to them directly.
167
+ case use <tt>:'subdir/template'</tt>). You must use a symbol because
168
+ otherwise rendering methods will render any strings passed to them
169
+ directly.
116
170
 
117
171
  === Haml Templates
118
172
 
@@ -127,15 +181,15 @@ The haml gem/library is required to render HAML templates:
127
181
 
128
182
  Renders <tt>./views/index.haml</tt>.
129
183
 
130
- {Haml's options}[http://haml.hamptoncatlin.com/docs/rdoc/classes/Haml.html]
184
+ {Haml's options}[http://haml-lang.com/docs/yardoc/file.HAML_REFERENCE.html#options]
131
185
  can be set globally through Sinatra's configurations,
132
186
  see {Options and Configurations}[http://www.sinatrarb.com/configuration.html],
133
187
  and overridden on an individual basis.
134
188
 
135
- set :haml, {:format => :html5 } # default Haml format is :xhtml
189
+ set :haml, :format => :html5 # default Haml format is :xhtml
136
190
 
137
191
  get '/' do
138
- haml :index, :haml_options => {:format => :html4 } # overridden
192
+ haml :index, :format => :html4 # overridden
139
193
  end
140
194
 
141
195
 
@@ -152,7 +206,7 @@ Renders <tt>./views/index.erb</tt>
152
206
 
153
207
  === Erubis
154
208
 
155
- The erubis gem/library is required to render builder templates:
209
+ The erubis gem/library is required to render erubis templates:
156
210
 
157
211
  ## You'll need to require erubis in your app
158
212
  require 'erubis'
@@ -171,12 +225,24 @@ The builder gem/library is required to render builder templates:
171
225
  require 'builder'
172
226
 
173
227
  get '/' do
174
- content_type 'application/xml', :charset => 'utf-8'
175
228
  builder :index
176
229
  end
177
230
 
178
231
  Renders <tt>./views/index.builder</tt>.
179
232
 
233
+ === Nokogiri Templates
234
+
235
+ The nokogiri gem/library is required to render nokogiri templates:
236
+
237
+ ## You'll need to require nokogiri in your app
238
+ require 'nokogiri'
239
+
240
+ get '/' do
241
+ nokogiri :index
242
+ end
243
+
244
+ Renders <tt>./views/index.nokogiri</tt>.
245
+
180
246
  === Sass Templates
181
247
 
182
248
  The sass gem/library is required to render Sass templates:
@@ -185,24 +251,46 @@ The sass gem/library is required to render Sass templates:
185
251
  require 'sass'
186
252
 
187
253
  get '/stylesheet.css' do
188
- content_type 'text/css', :charset => 'utf-8'
189
254
  sass :stylesheet
190
255
  end
191
256
 
192
257
  Renders <tt>./views/stylesheet.sass</tt>.
193
258
 
194
- {Sass' options}[http://haml.hamptoncatlin.com/docs/rdoc/classes/Sass.html]
259
+ {Sass' options}[http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#options]
195
260
  can be set globally through Sinatra's configurations,
196
261
  see {Options and Configurations}[http://www.sinatrarb.com/configuration.html],
197
262
  and overridden on an individual basis.
198
263
 
199
- set :sass, {:style => :compact } # default Sass style is :nested
264
+ set :sass, :style => :compact # default Sass style is :nested
200
265
 
201
266
  get '/stylesheet.css' do
202
- content_type 'text/css', :charset => 'utf-8'
203
267
  sass :stylesheet, :style => :expanded # overridden
204
268
  end
205
269
 
270
+ === Scss Templates
271
+
272
+ The sass gem/library is required to render Scss templates:
273
+
274
+ ## You'll need to require haml or sass in your app
275
+ require 'sass'
276
+
277
+ get '/stylesheet.css' do
278
+ scss :stylesheet
279
+ end
280
+
281
+ Renders <tt>./views/stylesheet.scss</tt>.
282
+
283
+ {Scss' options}[http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#options]
284
+ can be set globally through Sinatra's configurations,
285
+ see {Options and Configurations}[http://www.sinatrarb.com/configuration.html],
286
+ and overridden on an individual basis.
287
+
288
+ set :scss, :style => :compact # default Scss style is :nested
289
+
290
+ get '/stylesheet.css' do
291
+ scss :stylesheet, :style => :expanded # overridden
292
+ end
293
+
206
294
  === Less Templates
207
295
 
208
296
  The less gem/library is required to render Less templates:
@@ -211,12 +299,141 @@ The less gem/library is required to render Less templates:
211
299
  require 'less'
212
300
 
213
301
  get '/stylesheet.css' do
214
- content_type 'text/css', :charset => 'utf-8'
215
302
  less :stylesheet
216
303
  end
217
304
 
218
305
  Renders <tt>./views/stylesheet.less</tt>.
219
306
 
307
+ === Liquid Templates
308
+
309
+ The liquid gem/library is required to render Liquid templates:
310
+
311
+ ## You'll need to require liquid in your app
312
+ require 'liquid'
313
+
314
+ get '/' do
315
+ liquid :index
316
+ end
317
+
318
+ Renders <tt>./views/index.liquid</tt>.
319
+
320
+ Since you cannot call Ruby methods (except for +yield+) from a Liquid
321
+ template, you almost always want to pass locals to it:
322
+
323
+ liquid :index, :locals => { :key => 'value' }
324
+
325
+ === Markdown Templates
326
+
327
+ The rdiscount gem/library is required to render Markdown templates:
328
+
329
+ ## You'll need to require rdiscount in your app
330
+ require "rdiscount"
331
+
332
+ get '/' do
333
+ markdown :index
334
+ end
335
+
336
+ Renders <tt>./views/index.markdown</tt> (+md+ and +mkd+ are also valid file
337
+ extensions).
338
+
339
+ It is not possible to call methods from markdown, nor to pass locals to it. You therefore will usually use it in combination with another rendering engine:
340
+
341
+ erb :overview, :locals => { :text => markdown(:introduction) }
342
+
343
+ Note that you may also call the markdown method from within other templates:
344
+
345
+ %h1 Hello From Haml!
346
+ %p= markdown(:greetings)
347
+
348
+ === Textile Templates
349
+
350
+ The RedCloth gem/library is required to render Textile templates:
351
+
352
+ ## You'll need to require redcloth in your app
353
+ require "redcloth"
354
+
355
+ get '/' do
356
+ textile :index
357
+ end
358
+
359
+ Renders <tt>./views/index.textile</tt>.
360
+
361
+ It is not possible to call methods from textile, nor to pass locals to it. You therefore will usually use it in combination with another rendering engine:
362
+
363
+ erb :overview, :locals => { :text => textile(:introduction) }
364
+
365
+ Note that you may also call the textile method from within other templates:
366
+
367
+ %h1 Hello From Haml!
368
+ %p= textile(:greetings)
369
+
370
+ === RDoc Templates
371
+
372
+ The RDoc gem/library is required to render RDoc templates:
373
+
374
+ ## You'll need to require rdoc in your app
375
+ require "rdoc"
376
+
377
+ get '/' do
378
+ rdoc :index
379
+ end
380
+
381
+ Renders <tt>./views/index.rdoc</tt>.
382
+
383
+ It is not possible to call methods from rdoc, nor to pass locals to it. You therefore will usually use it in combination with another rendering engine:
384
+
385
+ erb :overview, :locals => { :text => rdoc(:introduction) }
386
+
387
+ Note that you may also call the rdoc method from within other templates:
388
+
389
+ %h1 Hello From Haml!
390
+ %p= rdoc(:greetings)
391
+
392
+ === Radius Templates
393
+
394
+ The radius gem/library is required to render Radius templates:
395
+
396
+ ## You'll need to require radius in your app
397
+ require 'radius'
398
+
399
+ get '/' do
400
+ radius :index
401
+ end
402
+
403
+ Renders <tt>./views/index.radius</tt>.
404
+
405
+ Since you cannot call Ruby methods (except for +yield+) from a Radius
406
+ template, you almost always want to pass locals to it:
407
+
408
+ radius :index, :locals => { :key => 'value' }
409
+
410
+ === Markaby Templates
411
+
412
+ The markaby gem/library is required to render Markaby templates:
413
+
414
+ ## You'll need to require markaby in your app
415
+ require 'markaby'
416
+
417
+ get '/' do
418
+ markaby :index
419
+ end
420
+
421
+ Renders <tt>./views/index.mab</tt>.
422
+
423
+ === CoffeeScript Templates
424
+
425
+ The coffee-script gem/library and the `coffee` binary are required to render
426
+ CoffeeScript templates:
427
+
428
+ ## You'll need to require coffee-script in your app
429
+ require 'coffee-script'
430
+
431
+ get '/application.js' do
432
+ coffee :application
433
+ end
434
+
435
+ Renders <tt>./views/application.coffee</tt>.
436
+
220
437
  === Inline Templates
221
438
 
222
439
  get '/' do
@@ -249,7 +466,6 @@ other templates.
249
466
 
250
467
  Templates may be defined at the end of the source file:
251
468
 
252
- require 'rubygems'
253
469
  require 'sinatra'
254
470
 
255
471
  get '/' do
@@ -265,8 +481,8 @@ Templates may be defined at the end of the source file:
265
481
  @@ index
266
482
  %div.title Hello world!!!!!
267
483
 
268
- NOTE: Inline templates defined in the source file that requires sinatra
269
- are automatically loaded. Call `enable :inline_templates` explicitly if you
484
+ NOTE: Inline templates defined in the source file that requires sinatra are
485
+ automatically loaded. Call <tt>enable :inline_templates</tt> explicitly if you
270
486
  have inline templates in other source files.
271
487
 
272
488
  === Named Templates
@@ -309,9 +525,9 @@ route handlers and templates:
309
525
 
310
526
  == Filters
311
527
 
312
- Before filters are evaluated before each request within the context of the
313
- request and can modify the request and response. Instance variables set in
314
- filters are accessible by routes and templates:
528
+ Before filters are evaluated before each request within the same context as
529
+ the routes will be and can modify the request and response. Instance variables
530
+ set in filters are accessible by routes and templates:
315
531
 
316
532
  before do
317
533
  @note = 'Hi!'
@@ -323,33 +539,44 @@ filters are accessible by routes and templates:
323
539
  params[:splat] #=> 'bar/baz'
324
540
  end
325
541
 
326
- After filter are evaluated after each request within the context of the
327
- request and can also modify the request and response. Instance variables
328
- set in before filters and routes are accessible by after filters:
542
+ After filter are evaluated after each request within the same context and can
543
+ also modify the request and response. Instance variables set in before filters
544
+ and routes are accessible by after filters:
329
545
 
330
546
  after do
331
547
  puts response.status
332
548
  end
333
549
 
550
+ Filters optionally taking a pattern, causing them to be evaluated only if the
551
+ request path matches that pattern:
552
+
553
+ before '/protected/*' do
554
+ authenticate!
555
+ end
556
+
557
+ after '/create/:slug' do |slug|
558
+ session[:last_slug] = slug
559
+ end
560
+
334
561
  == Halting
335
562
 
336
563
  To immediately stop a request within a filter or route use:
337
564
 
338
565
  halt
339
566
 
340
- You can also specify the status when halting ...
567
+ You can also specify the status when halting:
341
568
 
342
569
  halt 410
343
570
 
344
- Or the body ...
571
+ Or the body:
345
572
 
346
573
  halt 'this will be the body'
347
574
 
348
- Or both ...
575
+ Or both:
349
576
 
350
577
  halt 401, 'go away!'
351
578
 
352
- With headers ...
579
+ With headers:
353
580
 
354
581
  halt 402, {'Content-Type' => 'text/plain'}, 'revenge'
355
582
 
@@ -369,6 +596,53 @@ A route can punt processing to the next matching route using <tt>pass</tt>:
369
596
  The route block is immediately exited and control continues with the next
370
597
  matching route. If no matching route is found, a 404 is returned.
371
598
 
599
+ == Accessing the Request Object
600
+
601
+ The incoming request object can be accessed from request level (filter, routes, error handlers) through the `request` method:
602
+
603
+ # app running on http://example.com/example
604
+ get '/foo' do
605
+ request.body # request body sent by the client (see below)
606
+ request.scheme # "http"
607
+ request.script_name # "/example"
608
+ request.path_info # "/foo"
609
+ request.port # 80
610
+ request.request_method # "GET"
611
+ request.query_string # ""
612
+ request.content_length # length of request.body
613
+ request.media_type # media type of request.body
614
+ request.host # "example.com"
615
+ request.get? # true (similar methods for other verbs)
616
+ request.form_data? # false
617
+ request["SOME_HEADER"] # value of SOME_HEADER header
618
+ request.referer # the referer of the client or '/'
619
+ request.user_agent # user agent (used by :agent condition)
620
+ request.cookies # hash of browser cookies
621
+ request.xhr? # is this an ajax request?
622
+ request.url # "http://example.com/example/foo"
623
+ request.path # "/example/foo"
624
+ request.ip # client IP address
625
+ request.secure? # false
626
+ requuest.env # raw env hash handed in by Rack
627
+ end
628
+
629
+ Some options, like <tt>script_name</tt> or <tt>path_info</tt> can also be
630
+ written:
631
+
632
+ before { request.path_info = "/" }
633
+
634
+ get "/" do
635
+ "all requests end up here"
636
+ end
637
+
638
+ The <tt>request.body</tt> is an IO or StringIO object:
639
+
640
+ post "/api" do
641
+ request.body.rewind # in case someone already read it
642
+ data = JSON.parse request.body.read
643
+ "Hello #{data['name']}!"
644
+ end
645
+
372
646
  == Configuration
373
647
 
374
648
  Run once, at startup, in any environment:
@@ -394,8 +668,8 @@ Run when the environment is set to either <tt>:production</tt> or
394
668
  == Error handling
395
669
 
396
670
  Error handlers run within the same context as routes and before filters, which
397
- means you get all the goodies it has to offer, like <tt>haml</tt>, <tt>erb</tt>,
398
- <tt>halt</tt>, etc.
671
+ means you get all the goodies it has to offer, like <tt>haml</tt>,
672
+ <tt>erb</tt>, <tt>halt</tt>, etc.
399
673
 
400
674
  === Not Found
401
675
 
@@ -403,7 +677,7 @@ When a <tt>Sinatra::NotFound</tt> exception is raised, or the response's status
403
677
  code is 404, the <tt>not_found</tt> handler is invoked:
404
678
 
405
679
  not_found do
406
- 'This is nowhere to be found'
680
+ 'This is nowhere to be found.'
407
681
  end
408
682
 
409
683
  === Error
@@ -504,6 +778,7 @@ or framework. {Rack::Test}[http://gitrdoc.com/brynary/rack-test] is
504
778
  recommended:
505
779
 
506
780
  require 'my_sinatra_app'
781
+ require 'test/unit'
507
782
  require 'rack/test'
508
783
 
509
784
  class MyAppTest < Test::Unit::TestCase
@@ -535,7 +810,7 @@ are deprecated as of the 0.9.2 release.
535
810
  == Sinatra::Base - Middleware, Libraries, and Modular Apps
536
811
 
537
812
  Defining your app at the top-level works well for micro-apps but has
538
- considerable drawbacks when building reuseable components such as Rack
813
+ considerable drawbacks when building reusable components such as Rack
539
814
  middleware, Rails metal, simple libraries with a server component, or
540
815
  even Sinatra extensions. The top-level DSL pollutes the Object namespace
541
816
  and assumes a micro-app style configuration (e.g., a single application
@@ -570,17 +845,131 @@ Sinatra::Base components with two modifications:
570
845
  * Put your app's routes, error handlers, filters, and options in a subclass
571
846
  of Sinatra::Base.
572
847
 
573
- +Sinatra::Base+ is a blank slate. Most options are disabled by default,
848
+ <tt>Sinatra::Base</tt> is a blank slate. Most options are disabled by default,
574
849
  including the built-in server. See {Options and Configuration}[http://sinatra.github.com/configuration.html]
575
850
  for details on available options and their behavior.
576
851
 
577
- SIDEBAR: Sinatra's top-level DSL is implemented using a simple delegation
578
- system. The +Sinatra::Application+ class -- a special subclass of
579
- Sinatra::Base -- receives all :get, :put, :post, :delete, :before,
580
- :error, :not_found, :configure, and :set messages sent to the
581
- top-level. Have a look at the code for yourself: here's the
852
+ === Using Sinatra as Middleware
853
+
854
+ Not only is Sinatra able to use other Rack middleware, any Sinatra application
855
+ can in turn be added in front of any Rack endpoint as middleware itself. This
856
+ endpoint could be another Sinatra application, or any other Rack-based
857
+ application (Rails/Ramaze/Camping/...).
858
+
859
+ require 'sinatra/base'
860
+
861
+ class LoginScreen < Sinatra::Base
862
+ enable :session
863
+
864
+ get('/login') { haml :login }
865
+
866
+ post('/login') do
867
+ if params[:name] = 'admin' and params[:password] = 'admin'
868
+ session['user_name'] = params[:name]
869
+ else
870
+ redirect '/login'
871
+ end
872
+ end
873
+ end
874
+
875
+ class MyApp < Sinatra::Base
876
+ # middleware will run before filters
877
+ use LoginScreen
878
+
879
+ before do
880
+ unless session['user_name']
881
+ halt "Access denied, please <a href='/login'>login</a>."
882
+ end
883
+ end
884
+
885
+ get('/') { "Hello #{session['user_name']}." }
886
+ end
887
+
888
+ == Scopes and Binding
889
+
890
+ The scope you are currently in determines what methods and variables are
891
+ available.
892
+
893
+ === Application/Class Scope
894
+
895
+ Every Sinatra application corresponds to a subclass of Sinatra::Base. If you
896
+ are using the top level DSL (<tt>require 'sinatra'</tt>), then this class is
897
+ Sinatra::Application, otherwise it is the subclass you created explicitly. At
898
+ class level you have methods like `get` or `before`, but you cannot access the
899
+ `request` object or the `session`, as there only is a single application class
900
+ for all requests.
901
+
902
+ Options created via `set` are methods at class level:
903
+
904
+ class MyApp << Sinatra::Base
905
+ # Hey, I'm in the application scope!
906
+ set :foo, 42
907
+ foo # => 42
908
+
909
+ get '/foo' do
910
+ # Hey, I'm no longer in the application scope!
911
+ end
912
+ end
913
+
914
+ You have the application scope binding inside:
915
+
916
+ * Your application class body
917
+ * Methods defined by extensions
918
+ * The block passed to `helpers`
919
+ * Procs/blocks used as value for `set`
920
+
921
+ You can reach the scope object (the class) like this:
922
+
923
+ * Via the object passed to configure blocks (<tt>configure { |c| ... }</tt>)
924
+ * `settings` from within request scope
925
+
926
+ === Request/Instance Scope
927
+
928
+ For every incoming request, a new instance of your application class is
929
+ created and all handler blocks run in that scope. From within this scope you
930
+ can access the `request` and `session` object or call rendering methods like
931
+ `erb` or `haml`. You can access the application scope from within the request
932
+ scope via the `settings` helper:
933
+
934
+ class MyApp << Sinatra::Base
935
+ # Hey, I'm in the application scope!
936
+ get '/define_route/:name' do
937
+ # Request scope for '/define_route/:name'
938
+ @value = 42
939
+
940
+ settings.get("/#{params[:name]}") do
941
+ # Request scope for "/#{params[:name]}"
942
+ @value # => nil (not the same request)
943
+ end
944
+
945
+ "Route defined!"
946
+ end
947
+ end
948
+
949
+ You have the request scope binding inside:
950
+
951
+ * get/head/post/put/delete blocks
952
+ * before/after filters
953
+ * helper methods
954
+ * templates/views
955
+
956
+ === Delegation Scope
957
+
958
+ The delegation scope just forwards methods to the class scope. However, it
959
+ does not behave 100% like the class scope, as you do not have the class'
960
+ binding: Only methods explicitly marked for delegation are available and you
961
+ do not share variables/state with the class scope (read: you have a different
962
+ `self`). You can explicitly add method delegations by calling
963
+ <tt>Sinatra::Delegator.delegate :method_name</tt>.
964
+
965
+ You have the delegate scope binding inside:
966
+
967
+ * The top level binding, if you did <tt>require "sinatra"</tt>
968
+ * An object extended with the `Sinatra::Delegator` mixin
969
+
970
+ Have a look at the code for yourself: here's the
582
971
  {Sinatra::Delegator mixin}[http://github.com/sinatra/sinatra/blob/ceac46f0bc129a6e994a06100aa854f606fe5992/lib/sinatra/base.rb#L1128]
583
- being {included into the main namespace}[http://github.com/sinatra/sinatra/blob/ceac46f0bc129a6e994a06100aa854f606fe5992/lib/sinatra/main.rb#L28]
972
+ being {included into the main namespace}[http://github.com/sinatra/sinatra/blob/ceac46f0bc129a6e994a06100aa854f606fe5992/lib/sinatra/main.rb#L28].
584
973
 
585
974
  == Command line
586
975
 
@@ -629,8 +1018,7 @@ To update the Sinatra sources in the future:
629
1018
  news, and links to other resources.
630
1019
  * {Contributing}[http://www.sinatrarb.com/contributing] - Find a bug? Need
631
1020
  help? Have a patch?
632
- * {Lighthouse}[http://sinatra.lighthouseapp.com] - Issue tracking and release
633
- planning.
1021
+ * {Issue tracker}[http://github.com/sinatra/sinatra/issues]
634
1022
  * {Twitter}[http://twitter.com/sinatra]
635
1023
  * {Mailing List}[http://groups.google.com/group/sinatrarb/topics]
636
1024
  * {IRC: #sinatra}[irc://chat.freenode.net/#sinatra] on http://freenode.net