sinatra-acd 1.4.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +5 -0
  3. data/AUTHORS +61 -0
  4. data/CHANGES +1293 -0
  5. data/Gemfile +76 -0
  6. data/LICENSE +23 -0
  7. data/README.de.md +2864 -0
  8. data/README.es.md +2786 -0
  9. data/README.fr.md +2924 -0
  10. data/README.hu.md +694 -0
  11. data/README.ja.md +2726 -0
  12. data/README.ko.md +2832 -0
  13. data/README.md +2980 -0
  14. data/README.pt-br.md +965 -0
  15. data/README.pt-pt.md +791 -0
  16. data/README.ru.md +2799 -0
  17. data/README.zh.md +2158 -0
  18. data/Rakefile +199 -0
  19. data/examples/chat.rb +61 -0
  20. data/examples/simple.rb +3 -0
  21. data/examples/stream.ru +26 -0
  22. data/lib/sinatra.rb +4 -0
  23. data/lib/sinatra/base.rb +2044 -0
  24. data/lib/sinatra/images/404.png +0 -0
  25. data/lib/sinatra/images/500.png +0 -0
  26. data/lib/sinatra/main.rb +34 -0
  27. data/lib/sinatra/show_exceptions.rb +345 -0
  28. data/lib/sinatra/version.rb +3 -0
  29. data/sinatra.gemspec +19 -0
  30. data/test/asciidoctor_test.rb +72 -0
  31. data/test/base_test.rb +171 -0
  32. data/test/builder_test.rb +91 -0
  33. data/test/coffee_test.rb +90 -0
  34. data/test/compile_test.rb +183 -0
  35. data/test/contest.rb +100 -0
  36. data/test/creole_test.rb +65 -0
  37. data/test/delegator_test.rb +160 -0
  38. data/test/encoding_test.rb +20 -0
  39. data/test/erb_test.rb +116 -0
  40. data/test/extensions_test.rb +98 -0
  41. data/test/filter_test.rb +487 -0
  42. data/test/haml_test.rb +109 -0
  43. data/test/helper.rb +131 -0
  44. data/test/helpers_test.rb +1917 -0
  45. data/test/integration/app.rb +79 -0
  46. data/test/integration_helper.rb +236 -0
  47. data/test/integration_test.rb +104 -0
  48. data/test/less_test.rb +69 -0
  49. data/test/liquid_test.rb +77 -0
  50. data/test/mapped_error_test.rb +285 -0
  51. data/test/markaby_test.rb +80 -0
  52. data/test/markdown_test.rb +82 -0
  53. data/test/mediawiki_test.rb +68 -0
  54. data/test/middleware_test.rb +68 -0
  55. data/test/nokogiri_test.rb +67 -0
  56. data/test/public/favicon.ico +0 -0
  57. data/test/rabl_test.rb +89 -0
  58. data/test/rack_test.rb +45 -0
  59. data/test/radius_test.rb +59 -0
  60. data/test/rdoc_test.rb +66 -0
  61. data/test/readme_test.rb +130 -0
  62. data/test/request_test.rb +97 -0
  63. data/test/response_test.rb +63 -0
  64. data/test/result_test.rb +76 -0
  65. data/test/route_added_hook_test.rb +59 -0
  66. data/test/routing_test.rb +1412 -0
  67. data/test/sass_test.rb +115 -0
  68. data/test/scss_test.rb +88 -0
  69. data/test/server_test.rb +48 -0
  70. data/test/settings_test.rb +582 -0
  71. data/test/sinatra_test.rb +12 -0
  72. data/test/slim_test.rb +102 -0
  73. data/test/static_test.rb +236 -0
  74. data/test/streaming_test.rb +149 -0
  75. data/test/stylus_test.rb +90 -0
  76. data/test/templates_test.rb +382 -0
  77. data/test/textile_test.rb +65 -0
  78. data/test/views/a/in_a.str +1 -0
  79. data/test/views/ascii.erb +2 -0
  80. data/test/views/b/in_b.str +1 -0
  81. data/test/views/calc.html.erb +1 -0
  82. data/test/views/error.builder +3 -0
  83. data/test/views/error.erb +3 -0
  84. data/test/views/error.haml +3 -0
  85. data/test/views/error.sass +2 -0
  86. data/test/views/explicitly_nested.str +1 -0
  87. data/test/views/foo/hello.test +1 -0
  88. data/test/views/hello.asciidoc +1 -0
  89. data/test/views/hello.builder +1 -0
  90. data/test/views/hello.coffee +1 -0
  91. data/test/views/hello.creole +1 -0
  92. data/test/views/hello.erb +1 -0
  93. data/test/views/hello.haml +1 -0
  94. data/test/views/hello.less +5 -0
  95. data/test/views/hello.liquid +1 -0
  96. data/test/views/hello.mab +1 -0
  97. data/test/views/hello.md +1 -0
  98. data/test/views/hello.mediawiki +1 -0
  99. data/test/views/hello.nokogiri +1 -0
  100. data/test/views/hello.rabl +2 -0
  101. data/test/views/hello.radius +1 -0
  102. data/test/views/hello.rdoc +1 -0
  103. data/test/views/hello.sass +2 -0
  104. data/test/views/hello.scss +3 -0
  105. data/test/views/hello.slim +1 -0
  106. data/test/views/hello.str +1 -0
  107. data/test/views/hello.styl +2 -0
  108. data/test/views/hello.test +1 -0
  109. data/test/views/hello.textile +1 -0
  110. data/test/views/hello.wlang +1 -0
  111. data/test/views/hello.yajl +1 -0
  112. data/test/views/layout2.builder +3 -0
  113. data/test/views/layout2.erb +2 -0
  114. data/test/views/layout2.haml +2 -0
  115. data/test/views/layout2.liquid +2 -0
  116. data/test/views/layout2.mab +2 -0
  117. data/test/views/layout2.nokogiri +3 -0
  118. data/test/views/layout2.rabl +3 -0
  119. data/test/views/layout2.radius +2 -0
  120. data/test/views/layout2.slim +3 -0
  121. data/test/views/layout2.str +2 -0
  122. data/test/views/layout2.test +1 -0
  123. data/test/views/layout2.wlang +2 -0
  124. data/test/views/nested.str +1 -0
  125. data/test/views/utf8.erb +2 -0
  126. data/test/wlang_test.rb +87 -0
  127. data/test/yajl_test.rb +86 -0
  128. metadata +280 -0
@@ -0,0 +1,2980 @@
1
+ # Sinatra
2
+
3
+ Sinatra is a [DSL](http://en.wikipedia.org/wiki/Domain-specific_language) for
4
+ quickly creating web applications in Ruby with minimal effort:
5
+
6
+ ``` ruby
7
+ # myapp.rb
8
+ require 'sinatra'
9
+
10
+ get '/' do
11
+ 'Hello world!'
12
+ end
13
+ ```
14
+
15
+ Install the gem:
16
+
17
+ ``` shell
18
+ gem install sinatra
19
+ ```
20
+
21
+ And run with:
22
+
23
+ ``` shell
24
+ ruby myapp.rb
25
+ ```
26
+
27
+ View at: http://localhost:4567
28
+
29
+ It is recommended to also run `gem install thin`, which Sinatra will
30
+ pick up if available.
31
+
32
+ ## Table of Contents
33
+
34
+ * [Sinatra](#sinatra)
35
+ * [Table of Contents](#table-of-contents)
36
+ * [Routes](#routes)
37
+ * [Conditions](#conditions)
38
+ * [Return Values](#return-values)
39
+ * [Custom Route Matchers](#custom-route-matchers)
40
+ * [Static Files](#static-files)
41
+ * [Views / Templates](#views--templates)
42
+ * [Literal Templates](#literal-templates)
43
+ * [Available Template Languages](#available-template-languages)
44
+ * [Haml Templates](#haml-templates)
45
+ * [Erb Templates](#erb-templates)
46
+ * [Builder Templates](#builder-templates)
47
+ * [Nokogiri Templates](#nokogiri-templates)
48
+ * [Sass Templates](#sass-templates)
49
+ * [SCSS Templates](#scss-templates)
50
+ * [Less Templates](#less-templates)
51
+ * [Liquid Templates](#liquid-templates)
52
+ * [Markdown Templates](#markdown-templates)
53
+ * [Textile Templates](#textile-templates)
54
+ * [RDoc Templates](#rdoc-templates)
55
+ * [AsciiDoc Templates](#asciidoc-templates)
56
+ * [Radius Templates](#radius-templates)
57
+ * [Markaby Templates](#markaby-templates)
58
+ * [RABL Templates](#rabl-templates)
59
+ * [Slim Templates](#slim-templates)
60
+ * [Creole Templates](#creole-templates)
61
+ * [MediaWiki Templates](#mediawiki-templates)
62
+ * [CoffeeScript Templates](#coffeescript-templates)
63
+ * [Stylus Templates](#stylus-templates)
64
+ * [Yajl Templates](#yajl-templates)
65
+ * [WLang Templates](#wlang-templates)
66
+ * [Accessing Variables in Templates](#accessing-variables-in-templates)
67
+ * [Templates with `yield` and nested layouts](#templates-with-yield-and-nested-layouts)
68
+ * [Inline Templates](#inline-templates)
69
+ * [Named Templates](#named-templates)
70
+ * [Associating File Extensions](#associating-file-extensions)
71
+ * [Adding Your Own Template Engine](#adding-your-own-template-engine)
72
+ * [Filters](#filters)
73
+ * [Helpers](#helpers)
74
+ * [Using Sessions](#using-sessions)
75
+ * [Halting](#halting)
76
+ * [Passing](#passing)
77
+ * [Triggering Another Route](#triggering-another-route)
78
+ * [Setting Body, Status Code and Headers](#setting-body-status-code-and-headers)
79
+ * [Streaming Responses](#streaming-responses)
80
+ * [Logging](#logging)
81
+ * [Mime Types](#mime-types)
82
+ * [Generating URLs](#generating-urls)
83
+ * [Browser Redirect](#browser-redirect)
84
+ * [Cache Control](#cache-control)
85
+ * [Sending Files](#sending-files)
86
+ * [Accessing the Request Object](#accessing-the-request-object)
87
+ * [Attachments](#attachments)
88
+ * [Dealing with Date and Time](#dealing-with-date-and-time)
89
+ * [Looking Up Template Files](#looking-up-template-files)
90
+ * [Configuration](#configuration)
91
+ * [Configuring attack protection](#configuring-attack-protection)
92
+ * [Available Settings](#available-settings)
93
+ * [Environments](#environments)
94
+ * [Error Handling](#error-handling)
95
+ * [Not Found](#not-found)
96
+ * [Error](#error)
97
+ * [Rack Middleware](#rack-middleware)
98
+ * [Testing](#testing)
99
+ * [Sinatra::Base - Middleware, Libraries, and Modular Apps](#sinatrabase---middleware-libraries-and-modular-apps)
100
+ * [Modular vs. Classic Style](#modular-vs-classic-style)
101
+ * [Serving a Modular Application](#serving-a-modular-application)
102
+ * [Using a Classic Style Application with a config.ru](#using-a-classic-style-application-with-a-configru)
103
+ * [When to use a config.ru?](#when-to-use-a-configru)
104
+ * [Using Sinatra as Middleware](#using-sinatra-as-middleware)
105
+ * [Dynamic Application Creation](#dynamic-application-creation)
106
+ * [Scopes and Binding](#scopes-and-binding)
107
+ * [Application/Class Scope](#applicationclass-scope)
108
+ * [Request/Instance Scope](#requestinstance-scope)
109
+ * [Delegation Scope](#delegation-scope)
110
+ * [Command Line](#command-line)
111
+ * [Requirement](#requirement)
112
+ * [The Bleeding Edge](#the-bleeding-edge)
113
+ * [With Bundler](#with-bundler)
114
+ * [Roll Your Own](#roll-your-own)
115
+ * [Install Globally](#install-globally)
116
+ * [Versioning](#versioning)
117
+ * [Further Reading](#further-reading)
118
+
119
+ ## Routes
120
+
121
+ In Sinatra, a route is an HTTP method paired with a URL-matching pattern.
122
+ Each route is associated with a block:
123
+
124
+ ``` ruby
125
+ get '/' do
126
+ .. show something ..
127
+ end
128
+
129
+ post '/' do
130
+ .. create something ..
131
+ end
132
+
133
+ put '/' do
134
+ .. replace something ..
135
+ end
136
+
137
+ patch '/' do
138
+ .. modify something ..
139
+ end
140
+
141
+ delete '/' do
142
+ .. annihilate something ..
143
+ end
144
+
145
+ options '/' do
146
+ .. appease something ..
147
+ end
148
+
149
+ link '/' do
150
+ .. affiliate something ..
151
+ end
152
+
153
+ unlink '/' do
154
+ .. separate something ..
155
+ end
156
+ ```
157
+
158
+ Routes are matched in the order they are defined. The first route that
159
+ matches the request is invoked.
160
+
161
+ Route patterns may include named parameters, accessible via the
162
+ `params` hash:
163
+
164
+ ``` ruby
165
+ get '/hello/:name' do
166
+ # matches "GET /hello/foo" and "GET /hello/bar"
167
+ # params[:name] is 'foo' or 'bar'
168
+ "Hello #{params[:name]}!"
169
+ end
170
+ ```
171
+
172
+ You can also access named parameters via block parameters:
173
+
174
+ ``` ruby
175
+ get '/hello/:name' do |n|
176
+ # matches "GET /hello/foo" and "GET /hello/bar"
177
+ # params[:name] is 'foo' or 'bar'
178
+ # n stores params[:name]
179
+ "Hello #{n}!"
180
+ end
181
+ ```
182
+
183
+ Route patterns may also include splat (or wildcard) parameters, accessible
184
+ via the `params[:splat]` array:
185
+
186
+ ``` ruby
187
+ get '/say/*/to/*' do
188
+ # matches /say/hello/to/world
189
+ params[:splat] # => ["hello", "world"]
190
+ end
191
+
192
+ get '/download/*.*' do
193
+ # matches /download/path/to/file.xml
194
+ params[:splat] # => ["path/to/file", "xml"]
195
+ end
196
+ ```
197
+
198
+ Or with block parameters:
199
+
200
+ ``` ruby
201
+ get '/download/*.*' do |path, ext|
202
+ [path, ext] # => ["path/to/file", "xml"]
203
+ end
204
+ ```
205
+
206
+ Route matching with Regular Expressions:
207
+
208
+ ``` ruby
209
+ get %r{/hello/([\w]+)} do
210
+ "Hello, #{params[:captures].first}!"
211
+ end
212
+ ```
213
+
214
+ Or with a block parameter:
215
+
216
+ ``` ruby
217
+ get %r{/hello/([\w]+)} do |c|
218
+ "Hello, #{c}!"
219
+ end
220
+ ```
221
+
222
+ Route patterns may have optional parameters:
223
+
224
+ ``` ruby
225
+ get '/posts.?:format?' do
226
+ # matches "GET /posts" and any extension "GET /posts.json", "GET /posts.xml" etc.
227
+ end
228
+ ```
229
+
230
+ Routes may also utilize query parameters:
231
+
232
+ ``` ruby
233
+ get '/posts' do
234
+ # matches "GET /posts?title=foo&author=bar"
235
+ title = params[:title]
236
+ author = params[:author]
237
+ # uses title and author variables; query is optional to the /posts route
238
+ end
239
+ ```
240
+
241
+ By the way, unless you disable the path traversal attack protection (see below),
242
+ the request path might be modified before matching against your routes.
243
+
244
+ ## Conditions
245
+
246
+ Routes may include a variety of matching conditions, such as the user agent:
247
+
248
+ ``` ruby
249
+ get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
250
+ "You're using Songbird version #{params[:agent][0]}"
251
+ end
252
+
253
+ get '/foo' do
254
+ # Matches non-songbird browsers
255
+ end
256
+ ```
257
+
258
+ Other available conditions are `host_name` and `provides`:
259
+
260
+ ``` ruby
261
+ get '/', :host_name => /^admin\./ do
262
+ "Admin Area, Access denied!"
263
+ end
264
+
265
+ get '/', :provides => 'html' do
266
+ haml :index
267
+ end
268
+
269
+ get '/', :provides => ['rss', 'atom', 'xml'] do
270
+ builder :feed
271
+ end
272
+ ```
273
+
274
+ You can easily define your own conditions:
275
+
276
+ ``` ruby
277
+ set(:probability) { |value| condition { rand <= value } }
278
+
279
+ get '/win_a_car', :probability => 0.1 do
280
+ "You won!"
281
+ end
282
+
283
+ get '/win_a_car' do
284
+ "Sorry, you lost."
285
+ end
286
+ ```
287
+
288
+ For a condition that takes multiple values use a splat:
289
+
290
+ ``` ruby
291
+ set(:auth) do |*roles| # <- notice the splat here
292
+ condition do
293
+ unless logged_in? && roles.any? {|role| current_user.in_role? role }
294
+ redirect "/login/", 303
295
+ end
296
+ end
297
+ end
298
+
299
+ get "/my/account/", :auth => [:user, :admin] do
300
+ "Your Account Details"
301
+ end
302
+
303
+ get "/only/admin/", :auth => :admin do
304
+ "Only admins are allowed here!"
305
+ end
306
+ ```
307
+
308
+ ## Return Values
309
+
310
+ The return value of a route block determines at least the response body passed
311
+ on to the HTTP client, or at least the next middleware in the Rack stack.
312
+ Most commonly, this is a string, as in the above examples. But other values are
313
+ also accepted.
314
+
315
+ You can return any object that would either be a valid Rack response, Rack
316
+ body object or HTTP status code:
317
+
318
+ * An Array with three elements: `[status (Fixnum), headers (Hash), response
319
+ body (responds to #each)]`
320
+ * An Array with two elements: `[status (Fixnum), response body (responds to
321
+ #each)]`
322
+ * An object that responds to `#each` and passes nothing but strings to
323
+ the given block
324
+ * A Fixnum representing the status code
325
+
326
+ That way we can, for instance, easily implement a streaming example:
327
+
328
+ ``` ruby
329
+ class Stream
330
+ def each
331
+ 100.times { |i| yield "#{i}\n" }
332
+ end
333
+ end
334
+
335
+ get('/') { Stream.new }
336
+ ```
337
+
338
+ You can also use the `stream` helper method (described below) to reduce boiler
339
+ plate and embed the streaming logic in the route.
340
+
341
+ ## Custom Route Matchers
342
+
343
+ As shown above, Sinatra ships with built-in support for using String patterns
344
+ and regular expressions as route matches. However, it does not stop there. You
345
+ can easily define your own matchers:
346
+
347
+ ``` ruby
348
+ class AllButPattern
349
+ Match = Struct.new(:captures)
350
+
351
+ def initialize(except)
352
+ @except = except
353
+ @captures = Match.new([])
354
+ end
355
+
356
+ def match(str)
357
+ @captures unless @except === str
358
+ end
359
+ end
360
+
361
+ def all_but(pattern)
362
+ AllButPattern.new(pattern)
363
+ end
364
+
365
+ get all_but("/index") do
366
+ # ...
367
+ end
368
+ ```
369
+
370
+ Note that the above example might be over-engineered, as it can also be
371
+ expressed as:
372
+
373
+ ``` ruby
374
+ get // do
375
+ pass if request.path_info == "/index"
376
+ # ...
377
+ end
378
+ ```
379
+
380
+ Or, using negative look ahead:
381
+
382
+ ``` ruby
383
+ get %r{^(?!/index$)} do
384
+ # ...
385
+ end
386
+ ```
387
+
388
+ ## Static Files
389
+
390
+ Static files are served from the `./public` directory. You can specify
391
+ a different location by setting the `:public_folder` option:
392
+
393
+ ``` ruby
394
+ set :public_folder, File.dirname(__FILE__) + '/static'
395
+ ```
396
+
397
+ Note that the public directory name is not included in the URL. A file
398
+ `./public/css/style.css` is made available as
399
+ `http://example.com/css/style.css`.
400
+
401
+ Use the `:static_cache_control` setting (see below) to add
402
+ `Cache-Control` header info.
403
+
404
+ ## Views / Templates
405
+
406
+ Each template language is exposed via its own rendering method. These
407
+ methods simply return a string:
408
+
409
+ ``` ruby
410
+ get '/' do
411
+ erb :index
412
+ end
413
+ ```
414
+
415
+ This renders `views/index.erb`.
416
+
417
+ Instead of a template name, you can also just pass in the template content
418
+ directly:
419
+
420
+ ``` ruby
421
+ get '/' do
422
+ code = "<%= Time.now %>"
423
+ erb code
424
+ end
425
+ ```
426
+
427
+ Templates take a second argument, the options hash:
428
+
429
+ ``` ruby
430
+ get '/' do
431
+ erb :index, :layout => :post
432
+ end
433
+ ```
434
+
435
+ This will render `views/index.erb` embedded in the
436
+ `views/post.erb` (default is `views/layout.erb`, if it exists).
437
+
438
+ Any options not understood by Sinatra will be passed on to the template
439
+ engine:
440
+
441
+ ``` ruby
442
+ get '/' do
443
+ haml :index, :format => :html5
444
+ end
445
+ ```
446
+
447
+ You can also set options per template language in general:
448
+
449
+ ``` ruby
450
+ set :haml, :format => :html5
451
+
452
+ get '/' do
453
+ haml :index
454
+ end
455
+ ```
456
+
457
+ Options passed to the render method override options set via `set`.
458
+
459
+ Available Options:
460
+
461
+ <dl>
462
+ <dt>locals</dt>
463
+ <dd>
464
+ List of locals passed to the document. Handy with partials.
465
+ Example: <tt>erb "<%= foo %>", :locals => {:foo => "bar"}</tt>
466
+ </dd>
467
+
468
+ <dt>default_encoding</dt>
469
+ <dd>
470
+ String encoding to use if uncertain. Defaults to
471
+ <tt>settings.default_encoding</tt>.
472
+ </dd>
473
+
474
+ <dt>views</dt>
475
+ <dd>
476
+ Views folder to load templates from. Defaults to <tt>settings.views</tt>.
477
+ </dd>
478
+
479
+ <dt>layout</dt>
480
+ <dd>
481
+ Whether to use a layout (<tt>true</tt> or <tt>false</tt>). If it's a Symbol, specifies
482
+ what template to use. Example: <tt>erb :index, :layout => !request.xhr?</tt>
483
+ </dd>
484
+
485
+ <dt>content_type</dt>
486
+ <dd>
487
+ Content-Type the template produces. Default depends on template language.
488
+ </dd>
489
+
490
+ <dt>scope</dt>
491
+ <dd>
492
+ Scope to render template under. Defaults to the application instance. If you
493
+ change this, instance variables and helper methods will not be available.
494
+ </dd>
495
+
496
+ <dt>layout_engine</dt>
497
+ <dd>
498
+ Template engine to use for rendering the layout. Useful for languages that
499
+ do not support layouts otherwise. Defaults to the engine used for the
500
+ template. Example: <tt>set :rdoc, :layout_engine => :erb</tt>
501
+ </dd>
502
+
503
+ <dt>layout_options</dt>
504
+ <dd>
505
+ Special options only used for rendering the layout. Example:
506
+ <tt>set :rdoc, :layout_options => { :views => 'views/layouts' }</tt>
507
+ </dd>
508
+ </dl>
509
+
510
+ Templates are assumed to be located directly under the `./views` directory. To
511
+ use a different views directory:
512
+
513
+ ``` ruby
514
+ set :views, settings.root + '/templates'
515
+ ```
516
+
517
+
518
+ One important thing to remember is that you always have to reference templates
519
+ with symbols, even if they're in a subdirectory (in this case, use:
520
+ `:'subdir/template'` or `'subdir/template'.to_sym`). You must use a symbol
521
+ because otherwise rendering methods will render any strings passed to them
522
+ directly.
523
+
524
+ ### Literal Templates
525
+
526
+ ``` ruby
527
+ get '/' do
528
+ haml '%div.title Hello World'
529
+ end
530
+ ```
531
+
532
+ Renders the template string.
533
+
534
+ ### Available Template Languages
535
+
536
+ Some languages have multiple implementations. To specify what implementation
537
+ to use (and to be thread-safe), you should simply require it first:
538
+
539
+ ``` ruby
540
+ require 'rdiscount' # or require 'bluecloth'
541
+ get('/') { markdown :index }
542
+ ```
543
+
544
+ #### Haml Templates
545
+
546
+ <table>
547
+ <tr>
548
+ <td>Dependency</td>
549
+ <td><a href="http://haml.info/" title="haml">haml</a></td>
550
+ </tr>
551
+ <tr>
552
+ <td>File Extension</td>
553
+ <td><tt>.haml</tt></td>
554
+ </tr>
555
+ <tr>
556
+ <td>Example</td>
557
+ <td><tt>haml :index, :format => :html5</tt></td>
558
+ </tr>
559
+ </table>
560
+
561
+ #### Erb Templates
562
+
563
+ <table>
564
+ <tr>
565
+ <td>Dependency</td>
566
+ <td>
567
+ <a href="http://www.kuwata-lab.com/erubis/" title="erubis">erubis</a>
568
+ or erb (included in Ruby)
569
+ </td>
570
+ </tr>
571
+ <tr>
572
+ <td>File Extensions</td>
573
+ <td><tt>.erb</tt>, <tt>.rhtml</tt> or <tt>.erubis</tt> (Erubis only)</td>
574
+ </tr>
575
+ <tr>
576
+ <td>Example</td>
577
+ <td><tt>erb :index</tt></td>
578
+ </tr>
579
+ </table>
580
+
581
+ #### Builder Templates
582
+
583
+ <table>
584
+ <tr>
585
+ <td>Dependency</td>
586
+ <td>
587
+ <a href="http://builder.rubyforge.org/" title="builder">builder</a>
588
+ </td>
589
+ </tr>
590
+ <tr>
591
+ <td>File Extension</td>
592
+ <td><tt>.builder</tt></td>
593
+ </tr>
594
+ <tr>
595
+ <td>Example</td>
596
+ <td><tt>builder { |xml| xml.em "hi" }</tt></td>
597
+ </tr>
598
+ </table>
599
+
600
+ It also takes a block for inline templates (see example).
601
+
602
+ #### Nokogiri Templates
603
+
604
+ <table>
605
+ <tr>
606
+ <td>Dependency</td>
607
+ <td><a href="http://nokogiri.org/" title="nokogiri">nokogiri</a></td>
608
+ </tr>
609
+ <tr>
610
+ <td>File Extension</td>
611
+ <td><tt>.nokogiri</tt></td>
612
+ </tr>
613
+ <tr>
614
+ <td>Example</td>
615
+ <td><tt>nokogiri { |xml| xml.em "hi" }</tt></td>
616
+ </tr>
617
+ </table>
618
+
619
+ It also takes a block for inline templates (see example).
620
+
621
+ #### Sass Templates
622
+
623
+ <table>
624
+ <tr>
625
+ <td>Dependency</td>
626
+ <td><a href="http://sass-lang.com/" title="sass">sass</a></td>
627
+ </tr>
628
+ <tr>
629
+ <td>File Extension</td>
630
+ <td><tt>.sass</tt></td>
631
+ </tr>
632
+ <tr>
633
+ <td>Example</td>
634
+ <td><tt>sass :stylesheet, :style => :expanded</tt></td>
635
+ </tr>
636
+ </table>
637
+
638
+ #### SCSS Templates
639
+
640
+ <table>
641
+ <tr>
642
+ <td>Dependency</td>
643
+ <td><a href="http://sass-lang.com/" title="sass">sass</a></td>
644
+ </tr>
645
+ <tr>
646
+ <td>File Extension</td>
647
+ <td><tt>.scss</tt></td>
648
+ </tr>
649
+ <tr>
650
+ <td>Example</td>
651
+ <td><tt>scss :stylesheet, :style => :expanded</tt></td>
652
+ </tr>
653
+ </table>
654
+
655
+ #### Less Templates
656
+
657
+ <table>
658
+ <tr>
659
+ <td>Dependency</td>
660
+ <td><a href="http://www.lesscss.org/" title="less">less</a></td>
661
+ </tr>
662
+ <tr>
663
+ <td>File Extension</td>
664
+ <td><tt>.less</tt></td>
665
+ </tr>
666
+ <tr>
667
+ <td>Example</td>
668
+ <td><tt>less :stylesheet</tt></td>
669
+ </tr>
670
+ </table>
671
+
672
+ #### Liquid Templates
673
+
674
+ <table>
675
+ <tr>
676
+ <td>Dependency</td>
677
+ <td><a href="http://www.liquidmarkup.org/" title="liquid">liquid</a></td>
678
+ </tr>
679
+ <tr>
680
+ <td>File Extension</td>
681
+ <td><tt>.liquid</tt></td>
682
+ </tr>
683
+ <tr>
684
+ <td>Example</td>
685
+ <td><tt>liquid :index, :locals => { :key => 'value' }</tt></td>
686
+ </tr>
687
+ </table>
688
+
689
+ Since you cannot call Ruby methods (except for `yield`) from a Liquid
690
+ template, you almost always want to pass locals to it.
691
+
692
+ #### Markdown Templates
693
+
694
+ <table>
695
+ <tr>
696
+ <td>Dependency</td>
697
+ <td>
698
+ Anyone of:
699
+ <a href="https://github.com/rtomayko/rdiscount" title="RDiscount">RDiscount</a>,
700
+ <a href="https://github.com/vmg/redcarpet" title="RedCarpet">RedCarpet</a>,
701
+ <a href="http://deveiate.org/projects/BlueCloth" title="BlueCloth">BlueCloth</a>,
702
+ <a href="http://kramdown.rubyforge.org/" title="kramdown">kramdown</a>,
703
+ <a href="http://maruku.rubyforge.org/" title="maruku">maruku</a>
704
+ </td>
705
+ </tr>
706
+ <tr>
707
+ <td>File Extensions</td>
708
+ <td><tt>.markdown</tt>, <tt>.mkd</tt> and <tt>.md</tt></td>
709
+ </tr>
710
+ <tr>
711
+ <td>Example</td>
712
+ <td><tt>markdown :index, :layout_engine => :erb</tt></td>
713
+ </tr>
714
+ </table>
715
+
716
+ It is not possible to call methods from markdown, nor to pass locals to it.
717
+ You therefore will usually use it in combination with another rendering
718
+ engine:
719
+
720
+ ``` ruby
721
+ erb :overview, :locals => { :text => markdown(:introduction) }
722
+ ```
723
+
724
+ Note that you may also call the `markdown` method from within other templates:
725
+
726
+ ``` ruby
727
+ %h1 Hello From Haml!
728
+ %p= markdown(:greetings)
729
+ ```
730
+
731
+ Since you cannot call Ruby from Markdown, you cannot use layouts written in
732
+ Markdown. However, it is possible to use another rendering engine for the
733
+ template than for the layout by passing the `:layout_engine` option.
734
+
735
+ #### Textile Templates
736
+
737
+ <table>
738
+ <tr>
739
+ <td>Dependency</td>
740
+ <td><a href="http://redcloth.org/" title="RedCloth">RedCloth</a></td>
741
+ </tr>
742
+ <tr>
743
+ <td>File Extension</td>
744
+ <td><tt>.textile</tt></td>
745
+ </tr>
746
+ <tr>
747
+ <td>Example</td>
748
+ <td><tt>textile :index, :layout_engine => :erb</tt></td>
749
+ </tr>
750
+ </table>
751
+
752
+ It is not possible to call methods from textile, nor to pass locals to it. You
753
+ therefore will usually use it in combination with another rendering engine:
754
+
755
+ ``` ruby
756
+ erb :overview, :locals => { :text => textile(:introduction) }
757
+ ```
758
+
759
+ Note that you may also call the `textile` method from within other templates:
760
+
761
+ ``` ruby
762
+ %h1 Hello From Haml!
763
+ %p= textile(:greetings)
764
+ ```
765
+
766
+ Since you cannot call Ruby from Textile, you cannot use layouts written in
767
+ Textile. However, it is possible to use another rendering engine for the
768
+ template than for the layout by passing the `:layout_engine` option.
769
+
770
+ #### RDoc Templates
771
+
772
+ <table>
773
+ <tr>
774
+ <td>Dependency</td>
775
+ <td><a href="http://rdoc.rubyforge.org/" title="RDoc">RDoc</a></td>
776
+ </tr>
777
+ <tr>
778
+ <td>File Extension</td>
779
+ <td><tt>.rdoc</tt></td>
780
+ </tr>
781
+ <tr>
782
+ <td>Example</td>
783
+ <td><tt>rdoc :README, :layout_engine => :erb</tt></td>
784
+ </tr>
785
+ </table>
786
+
787
+ It is not possible to call methods from rdoc, nor to pass locals to it. You
788
+ therefore will usually use it in combination with another rendering engine:
789
+
790
+ ``` ruby
791
+ erb :overview, :locals => { :text => rdoc(:introduction) }
792
+ ```
793
+
794
+ Note that you may also call the `rdoc` method from within other templates:
795
+
796
+ ``` ruby
797
+ %h1 Hello From Haml!
798
+ %p= rdoc(:greetings)
799
+ ```
800
+
801
+ Since you cannot call Ruby from RDoc, you cannot use layouts written in
802
+ RDoc. However, it is possible to use another rendering engine for the
803
+ template than for the layout by passing the `:layout_engine` option.
804
+
805
+ #### AsciiDoc Templates
806
+
807
+ <table>
808
+ <tr>
809
+ <td>Dependency</td>
810
+ <td><a href="http://asciidoctor.org/" title="Asciidoctor">Asciidoctor</a></td>
811
+ </tr>
812
+ <tr>
813
+ <td>File Extension</td>
814
+ <td><tt>.asciidoc</tt>, <tt>.adoc</tt> and <tt>.ad</tt></td>
815
+ </tr>
816
+ <tr>
817
+ <td>Example</td>
818
+ <td><tt>asciidoc :README, :layout_engine => :erb</tt></td>
819
+ </tr>
820
+ </table>
821
+
822
+ Since you cannot call Ruby methods directly from an AsciiDoc template, you almost
823
+ always want to pass locals to it.
824
+
825
+ #### Radius Templates
826
+
827
+ <table>
828
+ <tr>
829
+ <td>Dependency</td>
830
+ <td><a href="http://radius.rubyforge.org/" title="Radius">Radius</a></td>
831
+ </tr>
832
+ <tr>
833
+ <td>File Extension</td>
834
+ <td><tt>.radius</tt></td>
835
+ </tr>
836
+ <tr>
837
+ <td>Example</td>
838
+ <td><tt>radius :index, :locals => { :key => 'value' }</tt></td>
839
+ </tr>
840
+ </table>
841
+
842
+ Since you cannot call Ruby methods directly from a Radius template, you almost
843
+ always want to pass locals to it.
844
+
845
+ #### Markaby Templates
846
+
847
+ <table>
848
+ <tr>
849
+ <td>Dependency</td>
850
+ <td><a href="http://markaby.github.com/" title="Markaby">Markaby</a></td>
851
+ </tr>
852
+ <tr>
853
+ <td>File Extension</td>
854
+ <td><tt>.mab</tt></td>
855
+ </tr>
856
+ <tr>
857
+ <td>Example</td>
858
+ <td><tt>markaby { h1 "Welcome!" }</tt></td>
859
+ </tr>
860
+ </table>
861
+
862
+ It also takes a block for inline templates (see example).
863
+
864
+ #### RABL Templates
865
+
866
+ <table>
867
+ <tr>
868
+ <td>Dependency</td>
869
+ <td><a href="https://github.com/nesquena/rabl" title="Rabl">Rabl</a></td>
870
+ </tr>
871
+ <tr>
872
+ <td>File Extension</td>
873
+ <td><tt>.rabl</tt></td>
874
+ </tr>
875
+ <tr>
876
+ <td>Example</td>
877
+ <td><tt>rabl :index</tt></td>
878
+ </tr>
879
+ </table>
880
+
881
+ #### Slim Templates
882
+
883
+ <table>
884
+ <tr>
885
+ <td>Dependency</td>
886
+ <td><a href="http://slim-lang.com/" title="Slim Lang">Slim Lang</a></td>
887
+ </tr>
888
+ <tr>
889
+ <td>File Extension</td>
890
+ <td><tt>.slim</tt></td>
891
+ </tr>
892
+ <tr>
893
+ <td>Example</td>
894
+ <td><tt>slim :index</tt></td>
895
+ </tr>
896
+ </table>
897
+
898
+ #### Creole Templates
899
+
900
+ <table>
901
+ <tr>
902
+ <td>Dependency</td>
903
+ <td><a href="https://github.com/minad/creole" title="Creole">Creole</a></td>
904
+ </tr>
905
+ <tr>
906
+ <td>File Extension</td>
907
+ <td><tt>.creole</tt></td>
908
+ </tr>
909
+ <tr>
910
+ <td>Example</td>
911
+ <td><tt>creole :wiki, :layout_engine => :erb</tt></td>
912
+ </tr>
913
+ </table>
914
+
915
+ It is not possible to call methods from creole, nor to pass locals to it. You
916
+ therefore will usually use it in combination with another rendering engine:
917
+
918
+ ``` ruby
919
+ erb :overview, :locals => { :text => creole(:introduction) }
920
+ ```
921
+
922
+ Note that you may also call the `creole` method from within other templates:
923
+
924
+ ``` ruby
925
+ %h1 Hello From Haml!
926
+ %p= creole(:greetings)
927
+ ```
928
+
929
+ Since you cannot call Ruby from Creole, you cannot use layouts written in
930
+ Creole. However, it is possible to use another rendering engine for the
931
+ template than for the layout by passing the `:layout_engine` option.
932
+
933
+ #### MediaWiki Templates
934
+
935
+ <table>
936
+ <tr>
937
+ <td>Dependency</td>
938
+ <td><a href="https://github.com/nricciar/wikicloth" title="WikiCloth">WikiCloth</a></td>
939
+ </tr>
940
+ <tr>
941
+ <td>File Extension</td>
942
+ <td><tt>.mediawiki</tt> and <tt>.mw</tt></td>
943
+ </tr>
944
+ <tr>
945
+ <td>Example</td>
946
+ <td><tt>mediawiki :wiki, :layout_engine => :erb</tt></td>
947
+ </tr>
948
+ </table>
949
+
950
+ It is not possible to call methods from MediaWiki markup, nor to pass locals to it.
951
+ You therefore will usually use it in combination with another rendering engine:
952
+
953
+ ``` ruby
954
+ erb :overview, :locals => { :text => mediawiki(:introduction) }
955
+ ```
956
+
957
+ Note that you may also call the `mediawiki` method from within other templates:
958
+
959
+ ``` ruby
960
+ %h1 Hello From Haml!
961
+ %p= mediawiki(:greetings)
962
+ ```
963
+
964
+ Since you cannot call Ruby from MediaWiki, you cannot use layouts written in
965
+ MediaWiki. However, it is possible to use another rendering engine for the
966
+ template than for the layout by passing the `:layout_engine` option.
967
+
968
+ #### CoffeeScript Templates
969
+
970
+ <table>
971
+ <tr>
972
+ <td>Dependency</td>
973
+ <td>
974
+ <a href="https://github.com/josh/ruby-coffee-script" title="Ruby CoffeeScript">
975
+ CoffeeScript
976
+ </a> and a
977
+ <a href="https://github.com/sstephenson/execjs/blob/master/README.md#readme" title="ExecJS">
978
+ way to execute javascript
979
+ </a>
980
+ </td>
981
+ </tr>
982
+ <tr>
983
+ <td>File Extension</td>
984
+ <td><tt>.coffee</tt></td>
985
+ </tr>
986
+ <tr>
987
+ <td>Example</td>
988
+ <td><tt>coffee :index</tt></td>
989
+ </tr>
990
+ </table>
991
+
992
+ #### Stylus Templates
993
+
994
+ <table>
995
+ <tr>
996
+ <td>Dependency</td>
997
+ <td>
998
+ <a href="https://github.com/lucasmazza/ruby-stylus" title="Ruby Stylus">
999
+ Stylus
1000
+ </a> and a
1001
+ <a href="https://github.com/sstephenson/execjs/blob/master/README.md#readme" title="ExecJS">
1002
+ way to execute javascript
1003
+ </a>
1004
+ </td>
1005
+ </tr>
1006
+ <tr>
1007
+ <td>File Extension</td>
1008
+ <td><tt>.styl</tt></td>
1009
+ </tr>
1010
+ <tr>
1011
+ <td>Example</td>
1012
+ <td><tt>stylus :index</tt></td>
1013
+ </tr>
1014
+ </table>
1015
+
1016
+ Before being able to use Stylus templates, you need to load `stylus` and
1017
+ `stylus/tilt` first:
1018
+
1019
+ ``` ruby
1020
+ require 'sinatra'
1021
+ require 'stylus'
1022
+ require 'stylus/tilt'
1023
+
1024
+ get '/' do
1025
+ stylus :example
1026
+ end
1027
+ ```
1028
+
1029
+ #### Yajl Templates
1030
+
1031
+ <table>
1032
+ <tr>
1033
+ <td>Dependency</td>
1034
+ <td><a href="https://github.com/brianmario/yajl-ruby" title="yajl-ruby">yajl-ruby</a></td>
1035
+ </tr>
1036
+ <tr>
1037
+ <td>File Extension</td>
1038
+ <td><tt>.yajl</tt></td>
1039
+ </tr>
1040
+ <tr>
1041
+ <td>Example</td>
1042
+ <td>
1043
+ <tt>
1044
+ yajl :index,
1045
+ :locals => { :key => 'qux' },
1046
+ :callback => 'present',
1047
+ :variable => 'resource'
1048
+ </tt>
1049
+ </td>
1050
+ </tr>
1051
+ </table>
1052
+
1053
+
1054
+ The template source is evaluated as a Ruby string, and the
1055
+ resulting json variable is converted using `#to_json`:
1056
+
1057
+ ``` ruby
1058
+ json = { :foo => 'bar' }
1059
+ json[:baz] = key
1060
+ ```
1061
+
1062
+ The `:callback` and `:variable` options can be used to decorate the rendered
1063
+ object:
1064
+
1065
+ ``` javascript
1066
+ var resource = {"foo":"bar","baz":"qux"};
1067
+ present(resource);
1068
+ ```
1069
+
1070
+ #### WLang Templates
1071
+
1072
+ <table>
1073
+ <tr>
1074
+ <td>Dependency</td>
1075
+ <td><a href="https://github.com/blambeau/wlang/" title="WLang">WLang</a></td>
1076
+ </tr>
1077
+ <tr>
1078
+ <td>File Extension</td>
1079
+ <td><tt>.wlang</tt></td>
1080
+ </tr>
1081
+ <tr>
1082
+ <td>Example</td>
1083
+ <td><tt>wlang :index, :locals => { :key => 'value' }</tt></td>
1084
+ </tr>
1085
+ </table>
1086
+
1087
+ Since calling ruby methods is not idiomatic in WLang, you almost always want to pass locals
1088
+ to it. Layouts written in WLang and `yield` are supported, though.
1089
+
1090
+ ### Accessing Variables in Templates
1091
+
1092
+ Templates are evaluated within the same context as route handlers. Instance
1093
+ variables set in route handlers are directly accessible by templates:
1094
+
1095
+ ``` ruby
1096
+ get '/:id' do
1097
+ @foo = Foo.find(params[:id])
1098
+ haml '%h1= @foo.name'
1099
+ end
1100
+ ```
1101
+
1102
+ Or, specify an explicit Hash of local variables:
1103
+
1104
+ ``` ruby
1105
+ get '/:id' do
1106
+ foo = Foo.find(params[:id])
1107
+ haml '%h1= bar.name', :locals => { :bar => foo }
1108
+ end
1109
+ ```
1110
+
1111
+ This is typically used when rendering templates as partials from within
1112
+ other templates.
1113
+
1114
+ ### Templates with `yield` and nested layouts
1115
+
1116
+ A layout is usually just a template that calls `yield`.
1117
+ Such a template can be used either through the `:template` option as
1118
+ described above, or it can be rendered with a block as follows:
1119
+
1120
+ ``` ruby
1121
+ erb :post, :layout => false do
1122
+ erb :index
1123
+ end
1124
+ ```
1125
+
1126
+ This code is mostly equivalent to `erb :index, :layout => :post`.
1127
+
1128
+ Passing blocks to rendering methods is most useful for creating nested
1129
+ layouts:
1130
+
1131
+ ``` ruby
1132
+ erb :main_layout, :layout => false do
1133
+ erb :admin_layout do
1134
+ erb :user
1135
+ end
1136
+ end
1137
+ ```
1138
+
1139
+ This can also be done in fewer lines of code with:
1140
+
1141
+ ``` ruby
1142
+ erb :admin_layout, :layout => :main_layout do
1143
+ erb :user
1144
+ end
1145
+ ```
1146
+
1147
+ Currently, the following rendering methods accept a block: `erb`, `haml`,
1148
+ `liquid`, `slim `, `wlang`.
1149
+ Also the general `render` method accepts a block.
1150
+
1151
+ ### Inline Templates
1152
+
1153
+ Templates may be defined at the end of the source file:
1154
+
1155
+ ``` ruby
1156
+ require 'sinatra'
1157
+
1158
+ get '/' do
1159
+ haml :index
1160
+ end
1161
+
1162
+ __END__
1163
+
1164
+ @@ layout
1165
+ %html
1166
+ = yield
1167
+
1168
+ @@ index
1169
+ %div.title Hello world.
1170
+ ```
1171
+
1172
+ NOTE: Inline templates defined in the source file that requires sinatra are
1173
+ automatically loaded. Call `enable :inline_templates` explicitly if you
1174
+ have inline templates in other source files.
1175
+
1176
+ ### Named Templates
1177
+
1178
+ Templates may also be defined using the top-level `template` method:
1179
+
1180
+ ``` ruby
1181
+ template :layout do
1182
+ "%html\n =yield\n"
1183
+ end
1184
+
1185
+ template :index do
1186
+ '%div.title Hello World!'
1187
+ end
1188
+
1189
+ get '/' do
1190
+ haml :index
1191
+ end
1192
+ ```
1193
+
1194
+ If a template named "layout" exists, it will be used each time a template
1195
+ is rendered. You can individually disable layouts by passing
1196
+ `:layout => false` or disable them by default via
1197
+ `set :haml, :layout => false`:
1198
+
1199
+ ``` ruby
1200
+ get '/' do
1201
+ haml :index, :layout => !request.xhr?
1202
+ end
1203
+ ```
1204
+
1205
+ ### Associating File Extensions
1206
+
1207
+ To associate a file extension with a template engine, use
1208
+ `Tilt.register`. For instance, if you like to use the file extension
1209
+ `tt` for Textile templates, you can do the following:
1210
+
1211
+ ``` ruby
1212
+ Tilt.register :tt, Tilt[:textile]
1213
+ ```
1214
+
1215
+ ### Adding Your Own Template Engine
1216
+
1217
+ First, register your engine with Tilt, then create a rendering method:
1218
+
1219
+ ``` ruby
1220
+ Tilt.register :myat, MyAwesomeTemplateEngine
1221
+
1222
+ helpers do
1223
+ def myat(*args) render(:myat, *args) end
1224
+ end
1225
+
1226
+ get '/' do
1227
+ myat :index
1228
+ end
1229
+ ```
1230
+
1231
+ Renders `./views/index.myat`. See https://github.com/rtomayko/tilt to
1232
+ learn more about Tilt.
1233
+
1234
+ ## Filters
1235
+
1236
+ Before filters are evaluated before each request within the same
1237
+ context as the routes will be and can modify the request and response. Instance
1238
+ variables set in filters are accessible by routes and templates:
1239
+
1240
+ ``` ruby
1241
+ before do
1242
+ @note = 'Hi!'
1243
+ request.path_info = '/foo/bar/baz'
1244
+ end
1245
+
1246
+ get '/foo/*' do
1247
+ @note #=> 'Hi!'
1248
+ params[:splat] #=> 'bar/baz'
1249
+ end
1250
+ ```
1251
+
1252
+ After filters are evaluated after each request within the same
1253
+ context as the routes will be and can also modify the request and response. Instance
1254
+ variables set in before filters and routes are accessible by after filters:
1255
+
1256
+ ``` ruby
1257
+ after do
1258
+ puts response.status
1259
+ end
1260
+ ```
1261
+
1262
+ Note: Unless you use the `body` method rather than just returning a String from
1263
+ the routes, the body will not yet be available in the after filter, since it is
1264
+ generated later on.
1265
+
1266
+ Filters optionally take a pattern, causing them to be evaluated only if the
1267
+ request path matches that pattern:
1268
+
1269
+ ``` ruby
1270
+ before '/protected/*' do
1271
+ authenticate!
1272
+ end
1273
+
1274
+ after '/create/:slug' do |slug|
1275
+ session[:last_slug] = slug
1276
+ end
1277
+ ```
1278
+
1279
+ Like routes, filters also take conditions:
1280
+
1281
+ ``` ruby
1282
+ before :agent => /Songbird/ do
1283
+ # ...
1284
+ end
1285
+
1286
+ after '/blog/*', :host_name => 'example.com' do
1287
+ # ...
1288
+ end
1289
+ ```
1290
+
1291
+ ## Helpers
1292
+
1293
+ Use the top-level `helpers` method to define helper methods for use in
1294
+ route handlers and templates:
1295
+
1296
+ ``` ruby
1297
+ helpers do
1298
+ def bar(name)
1299
+ "#{name}bar"
1300
+ end
1301
+ end
1302
+
1303
+ get '/:name' do
1304
+ bar(params[:name])
1305
+ end
1306
+ ```
1307
+
1308
+ Alternatively, helper methods can be separately defined in a module:
1309
+
1310
+ ``` ruby
1311
+ module FooUtils
1312
+ def foo(name) "#{name}foo" end
1313
+ end
1314
+
1315
+ module BarUtils
1316
+ def bar(name) "#{name}bar" end
1317
+ end
1318
+
1319
+ helpers FooUtils, BarUtils
1320
+ ```
1321
+
1322
+ The effect is the same as including the modules in the application class.
1323
+
1324
+ ### Using Sessions
1325
+
1326
+ A session is used to keep state during requests. If activated, you have one
1327
+ session hash per user session:
1328
+
1329
+ ``` ruby
1330
+ enable :sessions
1331
+
1332
+ get '/' do
1333
+ "value = " << session[:value].inspect
1334
+ end
1335
+
1336
+ get '/:value' do
1337
+ session[:value] = params[:value]
1338
+ end
1339
+ ```
1340
+
1341
+ Note that `enable :sessions` actually stores all data in a cookie. This
1342
+ might not always be what you want (storing lots of data will increase your
1343
+ traffic, for instance). You can use any Rack session middleware: in order to
1344
+ do so, do **not** call `enable :sessions`, but instead pull in your
1345
+ middleware of choice as you would any other middleware:
1346
+
1347
+ ``` ruby
1348
+ use Rack::Session::Pool, :expire_after => 2592000
1349
+
1350
+ get '/' do
1351
+ "value = " << session[:value].inspect
1352
+ end
1353
+
1354
+ get '/:value' do
1355
+ session[:value] = params[:value]
1356
+ end
1357
+ ```
1358
+
1359
+ To improve security, the session data in the cookie is signed with a session
1360
+ secret. A random secret is generated for you by Sinatra. However, since this
1361
+ secret will change with every start of your application, you might want to
1362
+ set the secret yourself, so all your application instances share it:
1363
+
1364
+ ``` ruby
1365
+ set :session_secret, 'super secret'
1366
+ ```
1367
+
1368
+ If you want to configure it further, you may also store a hash with options in
1369
+ the `sessions` setting:
1370
+
1371
+ ``` ruby
1372
+ set :sessions, :domain => 'foo.com'
1373
+ ```
1374
+
1375
+ To share your session across other apps on subdomains of foo.com, prefix the
1376
+ domain with a *.* like this instead:
1377
+
1378
+ ``` ruby
1379
+ set :sessions, :domain => '.foo.com'
1380
+ ```
1381
+
1382
+ ### Halting
1383
+
1384
+ To immediately stop a request within a filter or route use:
1385
+
1386
+ ``` ruby
1387
+ halt
1388
+ ```
1389
+
1390
+ You can also specify the status when halting:
1391
+
1392
+ ``` ruby
1393
+ halt 410
1394
+ ```
1395
+
1396
+ Or the body:
1397
+
1398
+ ``` ruby
1399
+ halt 'this will be the body'
1400
+ ```
1401
+
1402
+ Or both:
1403
+
1404
+ ``` ruby
1405
+ halt 401, 'go away!'
1406
+ ```
1407
+
1408
+ With headers:
1409
+
1410
+ ``` ruby
1411
+ halt 402, {'Content-Type' => 'text/plain'}, 'revenge'
1412
+ ```
1413
+
1414
+ It is of course possible to combine a template with `halt`:
1415
+
1416
+ ``` ruby
1417
+ halt erb(:error)
1418
+ ```
1419
+
1420
+ ### Passing
1421
+
1422
+ A route can punt processing to the next matching route using `pass`:
1423
+
1424
+ ``` ruby
1425
+ get '/guess/:who' do
1426
+ pass unless params[:who] == 'Frank'
1427
+ 'You got me!'
1428
+ end
1429
+
1430
+ get '/guess/*' do
1431
+ 'You missed!'
1432
+ end
1433
+ ```
1434
+
1435
+ The route block is immediately exited and control continues with the next
1436
+ matching route. If no matching route is found, a 404 is returned.
1437
+
1438
+ ### Triggering Another Route
1439
+
1440
+ Sometimes `pass` is not what you want, instead you would like to get the result
1441
+ of calling another route. Simply use `call` to achieve this:
1442
+
1443
+ ``` ruby
1444
+ get '/foo' do
1445
+ status, headers, body = call env.merge("PATH_INFO" => '/bar')
1446
+ [status, headers, body.map(&:upcase)]
1447
+ end
1448
+
1449
+ get '/bar' do
1450
+ "bar"
1451
+ end
1452
+ ```
1453
+
1454
+ Note that in the example above, you would ease testing and increase performance
1455
+ by simply moving `"bar"` into a helper used by both `/foo`
1456
+ and `/bar`.
1457
+
1458
+ If you want the request to be sent to the same application instance rather than
1459
+ a duplicate, use `call!` instead of `call`.
1460
+
1461
+ Check out the Rack specification if you want to learn more about `call`.
1462
+
1463
+ ### Setting Body, Status Code and Headers
1464
+
1465
+ It is possible and recommended to set the status code and response body with the
1466
+ return value of the route block. However, in some scenarios you might want to
1467
+ set the body at an arbitrary point in the execution flow. You can do so with the
1468
+ `body` helper method. If you do so, you can use that method from there on to
1469
+ access the body:
1470
+
1471
+ ``` ruby
1472
+ get '/foo' do
1473
+ body "bar"
1474
+ end
1475
+
1476
+ after do
1477
+ puts body
1478
+ end
1479
+ ```
1480
+
1481
+ It is also possible to pass a block to `body`, which will be executed by the
1482
+ Rack handler (this can be used to implement streaming, see "Return Values").
1483
+
1484
+ Similar to the body, you can also set the status code and headers:
1485
+
1486
+ ``` ruby
1487
+ get '/foo' do
1488
+ status 418
1489
+ headers \
1490
+ "Allow" => "BREW, POST, GET, PROPFIND, WHEN",
1491
+ "Refresh" => "Refresh: 20; http://www.ietf.org/rfc/rfc2324.txt"
1492
+ body "I'm a tea pot!"
1493
+ end
1494
+ ```
1495
+
1496
+ Like `body`, `headers` and `status` with no arguments can be used to access
1497
+ their current values.
1498
+
1499
+ ### Streaming Responses
1500
+
1501
+ Sometimes you want to start sending out data while still generating parts of
1502
+ the response body. In extreme examples, you want to keep sending data until
1503
+ the client closes the connection. You can use the `stream` helper to avoid
1504
+ creating your own wrapper:
1505
+
1506
+ ``` ruby
1507
+ get '/' do
1508
+ stream do |out|
1509
+ out << "It's gonna be legen -\n"
1510
+ sleep 0.5
1511
+ out << " (wait for it) \n"
1512
+ sleep 1
1513
+ out << "- dary!\n"
1514
+ end
1515
+ end
1516
+ ```
1517
+
1518
+ This allows you to implement streaming APIs,
1519
+ [Server Sent Events](http://dev.w3.org/html5/eventsource/), and can be used as
1520
+ the basis for [WebSockets](http://en.wikipedia.org/wiki/WebSocket). It can also be
1521
+ used to increase throughput if some but not all content depends on a slow
1522
+ resource.
1523
+
1524
+ Note that the streaming behavior, especially the number of concurrent requests,
1525
+ highly depends on the web server used to serve the application. Some servers,
1526
+ like WEBRick, might not even support streaming at all. If the server does not
1527
+ support streaming, the body will be sent all at once after the block passed to
1528
+ `stream` finishes executing. Streaming does not work at all with Shotgun.
1529
+
1530
+ If the optional parameter is set to `keep_open`, it will not call `close` on
1531
+ the stream object, allowing you to close it at any later point in the
1532
+ execution flow. This only works on evented servers, like Thin and Rainbows.
1533
+ Other servers will still close the stream:
1534
+
1535
+ ``` ruby
1536
+ # long polling
1537
+
1538
+ set :server, :thin
1539
+ connections = []
1540
+
1541
+ get '/subscribe' do
1542
+ # register a client's interest in server events
1543
+ stream(:keep_open) { |out| connections << out }
1544
+
1545
+ # purge dead connections
1546
+ connections.reject!(&:closed?)
1547
+
1548
+ # acknowledge
1549
+ "subscribed"
1550
+ end
1551
+
1552
+ post '/message' do
1553
+ connections.each do |out|
1554
+ # notify client that a new message has arrived
1555
+ out << params[:message] << "\n"
1556
+
1557
+ # indicate client to connect again
1558
+ out.close
1559
+ end
1560
+
1561
+ # acknowledge
1562
+ "message received"
1563
+ end
1564
+ ```
1565
+
1566
+ ### Logging
1567
+
1568
+ In the request scope, the `logger` helper exposes a `Logger` instance:
1569
+
1570
+ ``` ruby
1571
+ get '/' do
1572
+ logger.info "loading data"
1573
+ # ...
1574
+ end
1575
+ ```
1576
+
1577
+ This logger will automatically take your Rack handler's logging settings into
1578
+ account. If logging is disabled, this method will return a dummy object, so
1579
+ you do not have to worry about it in your routes and filters.
1580
+
1581
+ Note that logging is only enabled for `Sinatra::Application` by
1582
+ default, so if you inherit from `Sinatra::Base`, you probably want to
1583
+ enable it yourself:
1584
+
1585
+ ``` ruby
1586
+ class MyApp < Sinatra::Base
1587
+ configure :production, :development do
1588
+ enable :logging
1589
+ end
1590
+ end
1591
+ ```
1592
+
1593
+ To avoid any logging middleware to be set up, set the `logging` setting to
1594
+ `nil`. However, keep in mind that `logger` will in that case return `nil`. A
1595
+ common use case is when you want to set your own logger. Sinatra will use
1596
+ whatever it will find in `env['rack.logger']`.
1597
+
1598
+ ### Mime Types
1599
+
1600
+ When using `send_file` or static files you may have mime types Sinatra
1601
+ doesn't understand. Use `mime_type` to register them by file extension:
1602
+
1603
+ ``` ruby
1604
+ configure do
1605
+ mime_type :foo, 'text/foo'
1606
+ end
1607
+ ```
1608
+
1609
+ You can also use it with the `content_type` helper:
1610
+
1611
+ ``` ruby
1612
+ get '/' do
1613
+ content_type :foo
1614
+ "foo foo foo"
1615
+ end
1616
+ ```
1617
+
1618
+ ### Generating URLs
1619
+
1620
+ For generating URLs you should use the `url` helper method, for instance, in
1621
+ Haml:
1622
+
1623
+ ``` ruby
1624
+ %a{:href => url('/foo')} foo
1625
+ ```
1626
+
1627
+ It takes reverse proxies and Rack routers into account, if present.
1628
+
1629
+ This method is also aliased to `to` (see below for an example).
1630
+
1631
+ ### Browser Redirect
1632
+
1633
+ You can trigger a browser redirect with the `redirect` helper method:
1634
+
1635
+ ``` ruby
1636
+ get '/foo' do
1637
+ redirect to('/bar')
1638
+ end
1639
+ ```
1640
+
1641
+ Any additional parameters are handled like arguments passed to `halt`:
1642
+
1643
+ ``` ruby
1644
+ redirect to('/bar'), 303
1645
+ redirect 'http://google.com', 'wrong place, buddy'
1646
+ ```
1647
+
1648
+ You can also easily redirect back to the page the user came from with
1649
+ `redirect back`:
1650
+
1651
+ ``` ruby
1652
+ get '/foo' do
1653
+ "<a href='/bar'>do something</a>"
1654
+ end
1655
+
1656
+ get '/bar' do
1657
+ do_something
1658
+ redirect back
1659
+ end
1660
+ ```
1661
+
1662
+ To pass arguments with a redirect, either add them to the query:
1663
+
1664
+ ``` ruby
1665
+ redirect to('/bar?sum=42')
1666
+ ```
1667
+
1668
+ Or use a session:
1669
+
1670
+ ``` ruby
1671
+ enable :sessions
1672
+
1673
+ get '/foo' do
1674
+ session[:secret] = 'foo'
1675
+ redirect to('/bar')
1676
+ end
1677
+
1678
+ get '/bar' do
1679
+ session[:secret]
1680
+ end
1681
+ ```
1682
+
1683
+ ### Cache Control
1684
+
1685
+ Setting your headers correctly is the foundation for proper HTTP caching.
1686
+
1687
+ You can easily set the Cache-Control header like this:
1688
+
1689
+ ``` ruby
1690
+ get '/' do
1691
+ cache_control :public
1692
+ "cache it!"
1693
+ end
1694
+ ```
1695
+
1696
+ Pro tip: Set up caching in a before filter:
1697
+
1698
+ ``` ruby
1699
+ before do
1700
+ cache_control :public, :must_revalidate, :max_age => 60
1701
+ end
1702
+ ```
1703
+
1704
+ If you are using the `expires` helper to set the corresponding header,
1705
+ `Cache-Control` will be set automatically for you:
1706
+
1707
+ ``` ruby
1708
+ before do
1709
+ expires 500, :public, :must_revalidate
1710
+ end
1711
+ ```
1712
+
1713
+ To properly use caches, you should consider using `etag` or `last_modified`.
1714
+ It is recommended to call those helpers *before* doing any heavy lifting, as they
1715
+ will immediately flush a response if the client already has the current
1716
+ version in its cache:
1717
+
1718
+ ``` ruby
1719
+ get '/article/:id' do
1720
+ @article = Article.find params[:id]
1721
+ last_modified @article.updated_at
1722
+ etag @article.sha1
1723
+ erb :article
1724
+ end
1725
+ ```
1726
+
1727
+ It is also possible to use a
1728
+ [weak ETag](http://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation):
1729
+
1730
+ ``` ruby
1731
+ etag @article.sha1, :weak
1732
+ ```
1733
+
1734
+ These helpers will not do any caching for you, but rather feed the necessary
1735
+ information to your cache. If you are looking for a quick reverse-proxy caching
1736
+ solution, try [rack-cache](https://github.com/rtomayko/rack-cache):
1737
+
1738
+ ``` ruby
1739
+ require "rack/cache"
1740
+ require "sinatra"
1741
+
1742
+ use Rack::Cache
1743
+
1744
+ get '/' do
1745
+ cache_control :public, :max_age => 36000
1746
+ sleep 5
1747
+ "hello"
1748
+ end
1749
+ ```
1750
+
1751
+ Use the `:static_cache_control` setting (see below) to add
1752
+ `Cache-Control` header info to static files.
1753
+
1754
+ According to RFC 2616, your application should behave differently if the If-Match
1755
+ or If-None-Match header is set to `*`, depending on whether the resource
1756
+ requested is already in existence. Sinatra assumes resources for safe (like get)
1757
+ and idempotent (like put) requests are already in existence, whereas other
1758
+ resources (for instance post requests) are treated as new resources. You
1759
+ can change this behavior by passing in a `:new_resource` option:
1760
+
1761
+ ``` ruby
1762
+ get '/create' do
1763
+ etag '', :new_resource => true
1764
+ Article.create
1765
+ erb :new_article
1766
+ end
1767
+ ```
1768
+
1769
+ If you still want to use a weak ETag, pass in a `:kind` option:
1770
+
1771
+ ``` ruby
1772
+ etag '', :new_resource => true, :kind => :weak
1773
+ ```
1774
+
1775
+ ### Sending Files
1776
+
1777
+ For sending files, you can use the `send_file` helper method:
1778
+
1779
+ ``` ruby
1780
+ get '/' do
1781
+ send_file 'foo.png'
1782
+ end
1783
+ ```
1784
+
1785
+ It also takes options:
1786
+
1787
+ ``` ruby
1788
+ send_file 'foo.png', :type => :jpg
1789
+ ```
1790
+
1791
+ The options are:
1792
+
1793
+ <dl>
1794
+ <dt>filename</dt>
1795
+ <dd>file name, in response, defaults to the real file name.</dd>
1796
+
1797
+ <dt>last_modified</dt>
1798
+ <dd>value for Last-Modified header, defaults to the file's mtime.</dd>
1799
+
1800
+ <dt>type</dt>
1801
+ <dd>content type to use, guessed from the file extension if missing.</dd>
1802
+
1803
+ <dt>disposition</dt>
1804
+ <dd>
1805
+ used for Content-Disposition, possible value: <tt>nil</tt> (default),
1806
+ <tt>:attachment</tt> and <tt>:inline</tt>
1807
+ </dd>
1808
+
1809
+ <dt>length</dt>
1810
+ <dd>Content-Length header, defaults to file size.</dd>
1811
+
1812
+ <dt>status</dt>
1813
+ <dd>
1814
+ Status code to be sent. Useful when sending a static file as an error page.
1815
+
1816
+ If supported by the Rack handler, other means than streaming from the Ruby
1817
+ process will be used. If you use this helper method, Sinatra will automatically
1818
+ handle range requests.
1819
+ </dd>
1820
+ </dl>
1821
+
1822
+ ### Accessing the Request Object
1823
+
1824
+ The incoming request object can be accessed from request level (filter, routes,
1825
+ error handlers) through the `request` method:
1826
+
1827
+ ``` ruby
1828
+ # app running on http://example.com/example
1829
+ get '/foo' do
1830
+ t = %w[text/css text/html application/javascript]
1831
+ request.accept # ['text/html', '*/*']
1832
+ request.accept? 'text/xml' # true
1833
+ request.preferred_type(t) # 'text/html'
1834
+ request.body # request body sent by the client (see below)
1835
+ request.scheme # "http"
1836
+ request.script_name # "/example"
1837
+ request.path_info # "/foo"
1838
+ request.port # 80
1839
+ request.request_method # "GET"
1840
+ request.query_string # ""
1841
+ request.content_length # length of request.body
1842
+ request.media_type # media type of request.body
1843
+ request.host # "example.com"
1844
+ request.get? # true (similar methods for other verbs)
1845
+ request.form_data? # false
1846
+ request["some_param"] # value of some_param parameter. [] is a shortcut to the params hash.
1847
+ request.referrer # the referrer of the client or '/'
1848
+ request.user_agent # user agent (used by :agent condition)
1849
+ request.cookies # hash of browser cookies
1850
+ request.xhr? # is this an ajax request?
1851
+ request.url # "http://example.com/example/foo"
1852
+ request.path # "/example/foo"
1853
+ request.ip # client IP address
1854
+ request.secure? # false (would be true over ssl)
1855
+ request.forwarded? # true (if running behind a reverse proxy)
1856
+ request.env # raw env hash handed in by Rack
1857
+ end
1858
+ ```
1859
+
1860
+ Some options, like `script_name` or `path_info`, can also be
1861
+ written:
1862
+
1863
+ ``` ruby
1864
+ before { request.path_info = "/" }
1865
+
1866
+ get "/" do
1867
+ "all requests end up here"
1868
+ end
1869
+ ```
1870
+
1871
+ The `request.body` is an IO or StringIO object:
1872
+
1873
+ ``` ruby
1874
+ post "/api" do
1875
+ request.body.rewind # in case someone already read it
1876
+ data = JSON.parse request.body.read
1877
+ "Hello #{data['name']}!"
1878
+ end
1879
+ ```
1880
+
1881
+ ### Attachments
1882
+
1883
+ You can use the `attachment` helper to tell the browser the response should be
1884
+ stored on disk rather than displayed in the browser:
1885
+
1886
+ ``` ruby
1887
+ get '/' do
1888
+ attachment
1889
+ "store it!"
1890
+ end
1891
+ ```
1892
+
1893
+ You can also pass it a file name:
1894
+
1895
+ ``` ruby
1896
+ get '/' do
1897
+ attachment "info.txt"
1898
+ "store it!"
1899
+ end
1900
+ ```
1901
+
1902
+ ### Dealing with Date and Time
1903
+
1904
+ Sinatra offers a `time_for` helper method that generates a Time object
1905
+ from the given value. It is also able to convert `DateTime`, `Date` and
1906
+ similar classes:
1907
+
1908
+ ``` ruby
1909
+ get '/' do
1910
+ pass if Time.now > time_for('Dec 23, 2012')
1911
+ "still time"
1912
+ end
1913
+ ```
1914
+
1915
+ This method is used internally by `expires`, `last_modified` and akin. You can
1916
+ therefore easily extend the behavior of those methods by overriding `time_for`
1917
+ in your application:
1918
+
1919
+ ``` ruby
1920
+ helpers do
1921
+ def time_for(value)
1922
+ case value
1923
+ when :yesterday then Time.now - 24*60*60
1924
+ when :tomorrow then Time.now + 24*60*60
1925
+ else super
1926
+ end
1927
+ end
1928
+ end
1929
+
1930
+ get '/' do
1931
+ last_modified :yesterday
1932
+ expires :tomorrow
1933
+ "hello"
1934
+ end
1935
+ ```
1936
+
1937
+ ### Looking Up Template Files
1938
+
1939
+ The `find_template` helper is used to find template files for rendering:
1940
+
1941
+ ``` ruby
1942
+ find_template settings.views, 'foo', Tilt[:haml] do |file|
1943
+ puts "could be #{file}"
1944
+ end
1945
+ ```
1946
+
1947
+ This is not really useful. But it is useful that you can actually override this
1948
+ method to hook in your own lookup mechanism. For instance, if you want to be
1949
+ able to use more than one view directory:
1950
+
1951
+ ``` ruby
1952
+ set :views, ['views', 'templates']
1953
+
1954
+ helpers do
1955
+ def find_template(views, name, engine, &block)
1956
+ Array(views).each { |v| super(v, name, engine, &block) }
1957
+ end
1958
+ end
1959
+ ```
1960
+
1961
+ Another example would be using different directories for different engines:
1962
+
1963
+ ``` ruby
1964
+ set :views, :sass => 'views/sass', :haml => 'templates', :default => 'views'
1965
+
1966
+ helpers do
1967
+ def find_template(views, name, engine, &block)
1968
+ _, folder = views.detect { |k,v| engine == Tilt[k] }
1969
+ folder ||= views[:default]
1970
+ super(folder, name, engine, &block)
1971
+ end
1972
+ end
1973
+ ```
1974
+
1975
+ You can also easily wrap this up in an extension and share with others!
1976
+
1977
+ Note that `find_template` does not check if the file really exists but
1978
+ rather calls the given block for all possible paths. This is not a performance
1979
+ issue, since `render` will use `break` as soon as a file is found. Also,
1980
+ template locations (and content) will be cached if you are not running in
1981
+ development mode. You should keep that in mind if you write a really crazy
1982
+ method.
1983
+
1984
+ ## Configuration
1985
+
1986
+ Run once, at startup, in any environment:
1987
+
1988
+ ``` ruby
1989
+ configure do
1990
+ # setting one option
1991
+ set :option, 'value'
1992
+
1993
+ # setting multiple options
1994
+ set :a => 1, :b => 2
1995
+
1996
+ # same as `set :option, true`
1997
+ enable :option
1998
+
1999
+ # same as `set :option, false`
2000
+ disable :option
2001
+
2002
+ # you can also have dynamic settings with blocks
2003
+ set(:css_dir) { File.join(views, 'css') }
2004
+ end
2005
+ ```
2006
+
2007
+ Run only when the environment (`RACK_ENV` environment variable) is set to
2008
+ `:production`:
2009
+
2010
+ ``` ruby
2011
+ configure :production do
2012
+ ...
2013
+ end
2014
+ ```
2015
+
2016
+ Run when the environment is set to either `:production` or `:test`:
2017
+
2018
+ ```ruby
2019
+ configure :production, :test do
2020
+ ...
2021
+ end
2022
+ ```
2023
+
2024
+ You can access those options via `settings`:
2025
+
2026
+ ``` ruby
2027
+ configure do
2028
+ set :foo, 'bar'
2029
+ end
2030
+
2031
+ get '/' do
2032
+ settings.foo? # => true
2033
+ settings.foo # => 'bar'
2034
+ ...
2035
+ end
2036
+ ```
2037
+
2038
+ ### Configuring attack protection
2039
+
2040
+ Sinatra is using
2041
+ [Rack::Protection](https://github.com/rkh/rack-protection#readme) to defend
2042
+ your application against common, opportunistic attacks. You can easily disable
2043
+ this behavior (which will open up your application to tons of common
2044
+ vulnerabilities):
2045
+
2046
+ ``` ruby
2047
+ disable :protection
2048
+ ```
2049
+
2050
+ To skip a single defense layer, set `protection` to an options hash:
2051
+
2052
+ ``` ruby
2053
+ set :protection, :except => :path_traversal
2054
+ ```
2055
+ You can also hand in an array in order to disable a list of protections:
2056
+
2057
+ ``` ruby
2058
+ set :protection, :except => [:path_traversal, :session_hijacking]
2059
+ ```
2060
+
2061
+ By default, Sinatra will only set up session based protection if `:sessions`
2062
+ has been enabled. Sometimes you want to set up sessions on your own, though. In
2063
+ that case you can get it to set up session based protections by passing the
2064
+ `:session` option:
2065
+
2066
+ ``` ruby
2067
+ use Rack::Session::Pool
2068
+ set :protection, :session => true
2069
+ ```
2070
+
2071
+ ### Available Settings
2072
+
2073
+ <dl>
2074
+ <dt>absolute_redirects</dt>
2075
+ <dd>
2076
+ If disabled, Sinatra will allow relative redirects, however, Sinatra will no
2077
+ longer conform with RFC 2616 (HTTP 1.1), which only allows absolute redirects.
2078
+ </dd>
2079
+ <dd>
2080
+ Enable if your app is running behind a reverse proxy that has not been set up
2081
+ properly. Note that the <tt>url</tt> helper will still produce absolute URLs, unless you
2082
+ pass in <tt>false</tt> as the second parameter.
2083
+ </dd>
2084
+ <dd>Disabled by default.</dd>
2085
+
2086
+ <dt>add_charsets</dt>
2087
+ <dd>
2088
+ Mime types the <tt>content_type</tt> helper will automatically add the charset info to.
2089
+ You should add to it rather than overriding this option:
2090
+ <tt>settings.add_charsets << "application/foobar"</tt>
2091
+ </dd>
2092
+
2093
+ <dt>app_file</dt>
2094
+ <dd>
2095
+ Path to the main application file, used to detect project root, views and public
2096
+ folder and inline templates.
2097
+ </dd>
2098
+
2099
+ <dt>bind</dt>
2100
+ <dd>IP address to bind to (default: <tt>0.0.0.0</tt> <em>or</em> <tt>localhost</tt> if your `environment` is set to development.). Only used for built-in server.</dd>
2101
+
2102
+ <dt>default_encoding</dt>
2103
+ <dd>Encoding to assume if unknown (defaults to <tt>"utf-8"</tt>).</dd>
2104
+
2105
+ <dt>dump_errors</dt>
2106
+ <dd>Display errors in the log.</dd>
2107
+
2108
+ <dt>environment</dt>
2109
+ <dd>
2110
+ Current environment. Defaults to <tt>ENV['RACK_ENV']</tt>, or <tt>"development"</tt> if
2111
+ not available.
2112
+ </dd>
2113
+
2114
+ <dt>logging</dt>
2115
+ <dd>Use the logger.</dd>
2116
+
2117
+ <dt>lock</dt>
2118
+ <dd>
2119
+ Places a lock around every request, only running processing on request
2120
+ per Ruby process concurrently.
2121
+ </dd>
2122
+ <dd>Enabled if your app is not thread-safe. Disabled per default.</dd>
2123
+
2124
+ <dt>method_override</dt>
2125
+ <dd>
2126
+ Use <tt>_method</tt> magic to allow put/delete forms in browsers that
2127
+ don't support it.
2128
+ </dd>
2129
+
2130
+ <dt>port</dt>
2131
+ <dd>Port to listen on. Only used for built-in server.</dd>
2132
+
2133
+ <dt>prefixed_redirects</dt>
2134
+ <dd>
2135
+ Whether or not to insert <tt>request.script_name</tt> into redirects if no
2136
+ absolute path is given. That way <tt>redirect '/foo'</tt> would behave like
2137
+ <tt>redirect to('/foo')</tt>. Disabled per default.
2138
+ </dd>
2139
+
2140
+ <dt>protection</dt>
2141
+ <dd>Whether or not to enable web attack protections. See protection section above.</dd>
2142
+
2143
+ <dt>public_dir</dt>
2144
+ <dd>Alias for <tt>public_folder</tt>. See below.</dd>
2145
+
2146
+ <dt>public_folder</dt>
2147
+ <dd>
2148
+ Path to the folder public files are served from. Only used if static
2149
+ file serving is enabled (see <tt>static</tt> setting below). Inferred from
2150
+ <tt>app_file</tt> setting if not set.
2151
+ </dd>
2152
+
2153
+ <dt>reload_templates</dt>
2154
+ <dd>
2155
+ Whether or not to reload templates between requests. Enabled in development mode.
2156
+ </dd>
2157
+
2158
+ <dt>root</dt>
2159
+ <dd>
2160
+ Path to project root folder. Inferred from <tt>app_file</tt> setting if not set.
2161
+ </dd>
2162
+
2163
+ <dt>raise_errors</dt>
2164
+ <dd>
2165
+ Raise exceptions (will stop application). Enabled by default when
2166
+ <tt>environment</tt> is set to <tt>"test"</tt>, disabled otherwise.
2167
+ </dd>
2168
+
2169
+ <dt>run</dt>
2170
+ <dd>
2171
+ If enabled, Sinatra will handle starting the web server. Do not
2172
+ enable if using rackup or other means.
2173
+ </dd>
2174
+
2175
+ <dt>running</dt>
2176
+ <dd>Is the built-in server running now? Do not change this setting!</dd>
2177
+
2178
+ <dt>server</dt>
2179
+ <dd>
2180
+ Server or list of servers to use for built-in server. Order indicates
2181
+ priority, default depends on Ruby implementation.
2182
+ </dd>
2183
+
2184
+ <dt>sessions</dt>
2185
+ <dd>
2186
+ Enable cookie-based sessions support using <tt>Rack::Session::Cookie</tt>.
2187
+ See 'Using Sessions' section for more information.
2188
+ </dd>
2189
+
2190
+ <dt>show_exceptions</dt>
2191
+ <dd>
2192
+ Show a stack trace in the browser when an exception
2193
+ happens. Enabled by default when <tt>environment</tt>
2194
+ is set to <tt>"development"</tt>, disabled otherwise.
2195
+ </dd>
2196
+ <dd>
2197
+ Can also be set to <tt>:after_handler</tt> to trigger
2198
+ app-specified error handling before showing a stack
2199
+ trace in the browser.
2200
+ </dd>
2201
+
2202
+ <dt>static</dt>
2203
+ <dd>Whether Sinatra should handle serving static files.</dd>
2204
+ <dd>Disable when using a server able to do this on its own.</dd>
2205
+ <dd>Disabling will boost performance.</dd>
2206
+ <dd>
2207
+ Enabled per default in classic style, disabled for
2208
+ modular apps.
2209
+ </dd>
2210
+
2211
+ <dt>static_cache_control</dt>
2212
+ <dd>
2213
+ When Sinatra is serving static files, set this to add
2214
+ <tt>Cache-Control</tt> headers to the responses. Uses the
2215
+ <tt>cache_control</tt> helper. Disabled by default.
2216
+ </dd>
2217
+ <dd>
2218
+ Use an explicit array when setting multiple values:
2219
+ <tt>set :static_cache_control, [:public, :max_age => 300]</tt>
2220
+ </dd>
2221
+
2222
+ <dt>threaded</dt>
2223
+ <dd>
2224
+ If set to <tt>true</tt>, will tell Thin to use <tt>EventMachine.defer</tt>
2225
+ for processing the request.
2226
+ </dd>
2227
+
2228
+ <dt>traps</dt>
2229
+ <dd>Whether Sinatra should handle system signals.</dd>
2230
+
2231
+ <dt>views</dt>
2232
+ <dd>
2233
+ Path to the views folder. Inferred from <tt>app_file</tt> setting if
2234
+ not set.
2235
+ </dd>
2236
+
2237
+ <dt>x_cascade</dt>
2238
+ <dd>
2239
+ Whether or not to set the X-Cascade header if no route matches.
2240
+ Defaults to <tt>true</tt>.
2241
+ </dd>
2242
+ </dl>
2243
+
2244
+ ## Environments
2245
+
2246
+ There are three predefined `environments`: `"development"`,
2247
+ `"production"` and `"test"`. Environments can be set
2248
+ through the `RACK_ENV` environment variable. The default value is
2249
+ `"development"`. In the `"development"` environment all templates are reloaded between
2250
+ requests, and special `not_found` and `error` handlers
2251
+ display stack traces in your browser.
2252
+ In the `"production"` and `"test"` environments, templates are cached by default.
2253
+
2254
+ To run different environments, set the `RACK_ENV` environment variable:
2255
+
2256
+ ``` shell
2257
+ RACK_ENV=production ruby my_app.rb
2258
+ ```
2259
+
2260
+ You can use predefined methods: `development?`, `test?` and `production?` to
2261
+ check the current environment setting:
2262
+
2263
+ ``` ruby
2264
+ get '/' do
2265
+ if settings.development?
2266
+ "development!"
2267
+ else
2268
+ "not development!"
2269
+ end
2270
+ end
2271
+ ```
2272
+
2273
+ ## Error Handling
2274
+
2275
+ Error handlers run within the same context as routes and before filters, which
2276
+ means you get all the goodies it has to offer, like `haml`,
2277
+ `erb`, `halt`, etc.
2278
+
2279
+ ### Not Found
2280
+
2281
+ When a `Sinatra::NotFound` exception is raised, or the response's status
2282
+ code is 404, the `not_found` handler is invoked:
2283
+
2284
+ ``` ruby
2285
+ not_found do
2286
+ 'This is nowhere to be found.'
2287
+ end
2288
+ ```
2289
+
2290
+ ### Error
2291
+
2292
+ The `error` handler is invoked any time an exception is raised from a route
2293
+ block or a filter. The exception object can be obtained from the
2294
+ `sinatra.error` Rack variable:
2295
+
2296
+ ``` ruby
2297
+ error do
2298
+ 'Sorry there was a nasty error - ' + env['sinatra.error'].name
2299
+ end
2300
+ ```
2301
+
2302
+ Custom errors:
2303
+
2304
+ ``` ruby
2305
+ error MyCustomError do
2306
+ 'So what happened was...' + env['sinatra.error'].message
2307
+ end
2308
+ ```
2309
+
2310
+ Then, if this happens:
2311
+
2312
+ ``` ruby
2313
+ get '/' do
2314
+ raise MyCustomError, 'something bad'
2315
+ end
2316
+ ```
2317
+
2318
+ You get this:
2319
+
2320
+ ```
2321
+ So what happened was... something bad
2322
+ ```
2323
+
2324
+ Alternatively, you can install an error handler for a status code:
2325
+
2326
+ ``` ruby
2327
+ error 403 do
2328
+ 'Access forbidden'
2329
+ end
2330
+
2331
+ get '/secret' do
2332
+ 403
2333
+ end
2334
+ ```
2335
+
2336
+ Or a range:
2337
+
2338
+ ``` ruby
2339
+ error 400..510 do
2340
+ 'Boom'
2341
+ end
2342
+ ```
2343
+
2344
+ Sinatra installs special `not_found` and `error` handlers when
2345
+ running under the development environment to display nice stack traces
2346
+ and additional debugging information in your browser.
2347
+
2348
+ ## Rack Middleware
2349
+
2350
+ Sinatra rides on [Rack](http://rack.rubyforge.org/), a minimal standard
2351
+ interface for Ruby web frameworks. One of Rack's most interesting capabilities
2352
+ for application developers is support for "middleware" -- components that sit
2353
+ between the server and your application monitoring and/or manipulating the
2354
+ HTTP request/response to provide various types of common functionality.
2355
+
2356
+ Sinatra makes building Rack middleware pipelines a cinch via a top-level
2357
+ `use` method:
2358
+
2359
+ ``` ruby
2360
+ require 'sinatra'
2361
+ require 'my_custom_middleware'
2362
+
2363
+ use Rack::Lint
2364
+ use MyCustomMiddleware
2365
+
2366
+ get '/hello' do
2367
+ 'Hello World'
2368
+ end
2369
+ ```
2370
+
2371
+ The semantics of `use` are identical to those defined for the
2372
+ [Rack::Builder](http://rack.rubyforge.org/doc/classes/Rack/Builder.html) DSL
2373
+ (most frequently used from rackup files). For example, the `use` method
2374
+ accepts multiple/variable args as well as blocks:
2375
+
2376
+ ``` ruby
2377
+ use Rack::Auth::Basic do |username, password|
2378
+ username == 'admin' && password == 'secret'
2379
+ end
2380
+ ```
2381
+
2382
+ Rack is distributed with a variety of standard middleware for logging,
2383
+ debugging, URL routing, authentication, and session handling. Sinatra uses
2384
+ many of these components automatically based on configuration so you
2385
+ typically don't have to `use` them explicitly.
2386
+
2387
+ You can find useful middleware in
2388
+ [rack](https://github.com/rack/rack/tree/master/lib/rack),
2389
+ [rack-contrib](https://github.com/rack/rack-contrib#readm),
2390
+ or in the [Rack wiki](https://github.com/rack/rack/wiki/List-of-Middleware).
2391
+
2392
+ ## Testing
2393
+
2394
+ Sinatra tests can be written using any Rack-based testing library or framework.
2395
+ [Rack::Test](http://rdoc.info/github/brynary/rack-test/master/frames)
2396
+ is recommended:
2397
+
2398
+ ``` ruby
2399
+ require 'my_sinatra_app'
2400
+ require 'test/unit'
2401
+ require 'rack/test'
2402
+
2403
+ class MyAppTest < Test::Unit::TestCase
2404
+ include Rack::Test::Methods
2405
+
2406
+ def app
2407
+ Sinatra::Application
2408
+ end
2409
+
2410
+ def test_my_default
2411
+ get '/'
2412
+ assert_equal 'Hello World!', last_response.body
2413
+ end
2414
+
2415
+ def test_with_params
2416
+ get '/meet', :name => 'Frank'
2417
+ assert_equal 'Hello Frank!', last_response.body
2418
+ end
2419
+
2420
+ def test_with_rack_env
2421
+ get '/', {}, 'HTTP_USER_AGENT' => 'Songbird'
2422
+ assert_equal "You're using Songbird!", last_response.body
2423
+ end
2424
+ end
2425
+ ```
2426
+
2427
+ Note: If you are using Sinatra in the modular style, replace `Sinatra::Application`
2428
+ above with the class name of your app.
2429
+
2430
+ ## Sinatra::Base - Middleware, Libraries, and Modular Apps
2431
+
2432
+ Defining your app at the top-level works well for micro-apps but has
2433
+ considerable drawbacks when building reusable components such as Rack
2434
+ middleware, Rails metal, simple libraries with a server component, or even
2435
+ Sinatra extensions. The top-level assumes a micro-app style configuration
2436
+ (e.g., a single application file, `./public` and `./views`
2437
+ directories, logging, exception detail page, etc.). That's where
2438
+ `Sinatra::Base` comes into play:
2439
+
2440
+ ``` ruby
2441
+ require 'sinatra/base'
2442
+
2443
+ class MyApp < Sinatra::Base
2444
+ set :sessions, true
2445
+ set :foo, 'bar'
2446
+
2447
+ get '/' do
2448
+ 'Hello world!'
2449
+ end
2450
+ end
2451
+ ```
2452
+
2453
+ The methods available to `Sinatra::Base` subclasses are exactly the same as those
2454
+ available via the top-level DSL. Most top-level apps can be converted to
2455
+ `Sinatra::Base` components with two modifications:
2456
+
2457
+ * Your file should require `sinatra/base` instead of `sinatra`;
2458
+ otherwise, all of Sinatra's DSL methods are imported into the main
2459
+ namespace.
2460
+ * Put your app's routes, error handlers, filters, and options in a subclass
2461
+ of `Sinatra::Base`.
2462
+
2463
+ `Sinatra::Base` is a blank slate. Most options are disabled by default,
2464
+ including the built-in server. See
2465
+ [Configuring Settings](http://sinatra.github.com/configuration.html)
2466
+ for details on available options and their behavior. If you want
2467
+ behavior more similar to when you define your app at the top level (also
2468
+ know as Classic style), you
2469
+ can subclass `Sinatra::Application`.
2470
+
2471
+ ``` ruby
2472
+ require 'sinatra/base'
2473
+
2474
+ class MyApp < Sinatra::Application
2475
+ get '/' do
2476
+ 'Hello world!'
2477
+ end
2478
+ end
2479
+ ```
2480
+
2481
+ ### Modular vs. Classic Style
2482
+
2483
+ Contrary to common belief, there is nothing wrong with the classic style. If it
2484
+ suits your application, you do not have to switch to a modular application.
2485
+
2486
+ The main disadvantage of using the classic style rather than the modular style is that
2487
+ you will only have one Sinatra application per Ruby process. If you plan to use
2488
+ more than one, switch to the modular style. There is no reason you cannot mix
2489
+ the modular and the classic styles.
2490
+
2491
+ If switching from one style to the other, you should be aware of slightly
2492
+ different default settings:
2493
+
2494
+ <table>
2495
+ <tr>
2496
+ <th>Setting</th>
2497
+ <th>Classic</th>
2498
+ <th>Modular</th>
2499
+ <th>Modular</th>
2500
+ </tr>
2501
+
2502
+ <tr>
2503
+ <td>app_file</td>
2504
+ <td>file loading sinatra</td>
2505
+ <td>file subclassing Sinatra::Base</td>
2506
+ <td>file subclassing Sinatra::Application</td>
2507
+ </tr>
2508
+
2509
+ <tr>
2510
+ <td>run</td>
2511
+ <td>$0 == app_file</td>
2512
+ <td>false</td>
2513
+ <td>false</td>
2514
+ </tr>
2515
+
2516
+ <tr>
2517
+ <td>logging</td>
2518
+ <td>true</td>
2519
+ <td>false</td>
2520
+ <td>true</td>
2521
+ </tr>
2522
+
2523
+ <tr>
2524
+ <td>method_override</td>
2525
+ <td>true</td>
2526
+ <td>false</td>
2527
+ <td>true</td>
2528
+ </tr>
2529
+
2530
+ <tr>
2531
+ <td>inline_templates</td>
2532
+ <td>true</td>
2533
+ <td>false</td>
2534
+ <td>true</td>
2535
+ </tr>
2536
+
2537
+ <tr>
2538
+ <td>static</td>
2539
+ <td>true</td>
2540
+ <td>false</td>
2541
+ <td>true</td>
2542
+ </tr>
2543
+ </table>
2544
+
2545
+ ### Serving a Modular Application
2546
+
2547
+ There are two common options for starting a modular app, actively starting with
2548
+ `run!`:
2549
+
2550
+ ``` ruby
2551
+ # my_app.rb
2552
+ require 'sinatra/base'
2553
+
2554
+ class MyApp < Sinatra::Base
2555
+ # ... app code here ...
2556
+
2557
+ # start the server if ruby file executed directly
2558
+ run! if app_file == $0
2559
+ end
2560
+ ```
2561
+
2562
+ Start with:
2563
+
2564
+ ``` shell
2565
+ ruby my_app.rb
2566
+ ```
2567
+
2568
+ Or with a `config.ru` file, which allows using any Rack handler:
2569
+
2570
+ ``` ruby
2571
+ # config.ru (run with rackup)
2572
+ require './my_app'
2573
+ run MyApp
2574
+ ```
2575
+
2576
+ Run:
2577
+
2578
+ ``` shell
2579
+ rackup -p 4567
2580
+ ```
2581
+
2582
+ ### Using a Classic Style Application with a config.ru
2583
+
2584
+ Write your app file:
2585
+
2586
+ ``` ruby
2587
+ # app.rb
2588
+ require 'sinatra'
2589
+
2590
+ get '/' do
2591
+ 'Hello world!'
2592
+ end
2593
+ ```
2594
+
2595
+ And a corresponding `config.ru`:
2596
+
2597
+ ``` ruby
2598
+ require './app'
2599
+ run Sinatra::Application
2600
+ ```
2601
+
2602
+ ### When to use a config.ru?
2603
+
2604
+ A `config.ru` file is recommended if:
2605
+
2606
+ * You want to deploy with a different Rack handler (Passenger, Unicorn,
2607
+ Heroku, ...).
2608
+ * You want to use more than one subclass of `Sinatra::Base`.
2609
+ * You want to use Sinatra only for middleware, and not as an endpoint.
2610
+
2611
+ **There is no need to switch to a `config.ru` simply because you
2612
+ switched to the modular style, and you don't have to use the modular style for running
2613
+ with a `config.ru`.**
2614
+
2615
+ ### Using Sinatra as Middleware
2616
+
2617
+ Not only is Sinatra able to use other Rack middleware, any Sinatra application
2618
+ can in turn be added in front of any Rack endpoint as middleware itself. This
2619
+ endpoint could be another Sinatra application, or any other Rack-based
2620
+ application (Rails/Ramaze/Camping/...):
2621
+
2622
+ ``` ruby
2623
+ require 'sinatra/base'
2624
+
2625
+ class LoginScreen < Sinatra::Base
2626
+ enable :sessions
2627
+
2628
+ get('/login') { haml :login }
2629
+
2630
+ post('/login') do
2631
+ if params[:name] == 'admin' && params[:password] == 'admin'
2632
+ session['user_name'] = params[:name]
2633
+ else
2634
+ redirect '/login'
2635
+ end
2636
+ end
2637
+ end
2638
+
2639
+ class MyApp < Sinatra::Base
2640
+ # middleware will run before filters
2641
+ use LoginScreen
2642
+
2643
+ before do
2644
+ unless session['user_name']
2645
+ halt "Access denied, please <a href='/login'>login</a>."
2646
+ end
2647
+ end
2648
+
2649
+ get('/') { "Hello #{session['user_name']}." }
2650
+ end
2651
+ ```
2652
+
2653
+ ### Dynamic Application Creation
2654
+
2655
+ Sometimes you want to create new applications at runtime without having to
2656
+ assign them to a constant. You can do this with `Sinatra.new`:
2657
+
2658
+ ``` ruby
2659
+ require 'sinatra/base'
2660
+ my_app = Sinatra.new { get('/') { "hi" } }
2661
+ my_app.run!
2662
+ ```
2663
+
2664
+ It takes the application to inherit from as an optional argument:
2665
+
2666
+ ```ruby
2667
+ # config.ru (run with rackup)
2668
+ require 'sinatra/base'
2669
+
2670
+ controller = Sinatra.new do
2671
+ enable :logging
2672
+ helpers MyHelpers
2673
+ end
2674
+
2675
+ map('/a') do
2676
+ run Sinatra.new(controller) { get('/') { 'a' } }
2677
+ end
2678
+
2679
+ map('/b') do
2680
+ run Sinatra.new(controller) { get('/') { 'b' } }
2681
+ end
2682
+ ```
2683
+
2684
+ This is especially useful for testing Sinatra extensions or using Sinatra in
2685
+ your own library.
2686
+
2687
+ This also makes using Sinatra as middleware extremely easy:
2688
+
2689
+ ``` ruby
2690
+ require 'sinatra/base'
2691
+
2692
+ use Sinatra do
2693
+ get('/') { ... }
2694
+ end
2695
+
2696
+ run RailsProject::Application
2697
+ ```
2698
+
2699
+ ## Scopes and Binding
2700
+
2701
+ The scope you are currently in determines what methods and variables are
2702
+ available.
2703
+
2704
+ ### Application/Class Scope
2705
+
2706
+ Every Sinatra application corresponds to a subclass of `Sinatra::Base`.
2707
+ If you are using the top-level DSL (`require 'sinatra'`), then this
2708
+ class is `Sinatra::Application`, otherwise it is the subclass you
2709
+ created explicitly. At class level you have methods like `get` or `before`, but
2710
+ you cannot access the `request` or `session` objects, as there is only a
2711
+ single application class for all requests.
2712
+
2713
+ Options created via `set` are methods at class level:
2714
+
2715
+ ``` ruby
2716
+ class MyApp < Sinatra::Base
2717
+ # Hey, I'm in the application scope!
2718
+ set :foo, 42
2719
+ foo # => 42
2720
+
2721
+ get '/foo' do
2722
+ # Hey, I'm no longer in the application scope!
2723
+ end
2724
+ end
2725
+ ```
2726
+
2727
+ You have the application scope binding inside:
2728
+
2729
+ * Your application class body
2730
+ * Methods defined by extensions
2731
+ * The block passed to `helpers`
2732
+ * Procs/blocks used as value for `set`
2733
+ * The block passed to `Sinatra.new`
2734
+
2735
+ You can reach the scope object (the class) like this:
2736
+
2737
+ * Via the object passed to configure blocks (`configure { |c| ... }`)
2738
+ * `settings` from within the request scope
2739
+
2740
+ ### Request/Instance Scope
2741
+
2742
+ For every incoming request, a new instance of your application class is
2743
+ created, and all handler blocks run in that scope. From within this scope you
2744
+ can access the `request` and `session` objects or call rendering methods like
2745
+ `erb` or `haml`. You can access the application scope from within the request
2746
+ scope via the `settings` helper:
2747
+
2748
+ ``` ruby
2749
+ class MyApp < Sinatra::Base
2750
+ # Hey, I'm in the application scope!
2751
+ get '/define_route/:name' do
2752
+ # Request scope for '/define_route/:name'
2753
+ @value = 42
2754
+
2755
+ settings.get("/#{params[:name]}") do
2756
+ # Request scope for "/#{params[:name]}"
2757
+ @value # => nil (not the same request)
2758
+ end
2759
+
2760
+ "Route defined!"
2761
+ end
2762
+ end
2763
+ ```
2764
+
2765
+ You have the request scope binding inside:
2766
+
2767
+ * get, head, post, put, delete, options, patch, link, and unlink blocks
2768
+ * before and after filters
2769
+ * helper methods
2770
+ * templates/views
2771
+
2772
+ ### Delegation Scope
2773
+
2774
+ The delegation scope just forwards methods to the class scope. However, it
2775
+ does not behave exactly like the class scope, as you do not have the class
2776
+ binding. Only methods explicitly marked for delegation are available, and you
2777
+ do not share variables/state with the class scope (read: you have a different
2778
+ `self`). You can explicitly add method delegations by calling
2779
+ `Sinatra::Delegator.delegate :method_name`.
2780
+
2781
+ You have the delegate scope binding inside:
2782
+
2783
+ * The top level binding, if you did `require "sinatra"`
2784
+ * An object extended with the `Sinatra::Delegator` mixin
2785
+
2786
+ Have a look at the code for yourself: here's the
2787
+ [Sinatra::Delegator mixin](https://github.com/sinatra/sinatra/blob/ca06364/lib/sinatra/base.rb#L1609-1633)
2788
+ being [extending the main object](https://github.com/sinatra/sinatra/blob/ca06364/lib/sinatra/main.rb#L28-30).
2789
+
2790
+ ## Command Line
2791
+
2792
+ Sinatra applications can be run directly:
2793
+
2794
+ ``` shell
2795
+ ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-o HOST] [-s HANDLER]
2796
+ ```
2797
+
2798
+ Options are:
2799
+
2800
+ ```
2801
+ -h # help
2802
+ -p # set the port (default is 4567)
2803
+ -o # set the host (default is 0.0.0.0)
2804
+ -e # set the environment (default is development)
2805
+ -s # specify rack server/handler (default is thin)
2806
+ -x # turn on the mutex lock (default is off)
2807
+ ```
2808
+
2809
+ ## Requirement
2810
+
2811
+ The following Ruby versions are officially supported:
2812
+ <dl>
2813
+ <dt>Ruby 1.8.7</dt>
2814
+ <dd>
2815
+ 1.8.7 is fully supported, however, if nothing is keeping you from it, we
2816
+ recommend upgrading or switching to JRuby or Rubinius. Support for 1.8.7
2817
+ will not be dropped before Sinatra 2.0. Ruby 1.8.6 is no longer supported.
2818
+ </dd>
2819
+
2820
+ <dt>Ruby 1.9.2</dt>
2821
+ <dd>
2822
+ 1.9.2 is fully supported. Do not use 1.9.2p0, as it is known to cause
2823
+ segmentation faults when running Sinatra. Official support will continue
2824
+ at least until the release of Sinatra 1.5.
2825
+ </dd>
2826
+
2827
+ <dt>Ruby 1.9.3</dt>
2828
+ <dd>
2829
+ 1.9.3 is fully supported and recommended. Please note that switching to 1.9.3
2830
+ from an earlier version will invalidate all sessions. 1.9.3 will be supported
2831
+ until the release of Sinatra 2.0.
2832
+ </dd>
2833
+
2834
+ <dt>Ruby 2.0.0</dt>
2835
+ <dd>
2836
+ 2.0.0 is fully supported and recommended. There are currently no plans to drop
2837
+ official support for it.
2838
+ </dd>
2839
+
2840
+ <dt>Rubinius</dt>
2841
+ <dd>
2842
+ Rubinius is officially supported (Rubinius >= 2.x). It is recommended to
2843
+ <tt>gem install puma</tt>.
2844
+ </dd>
2845
+
2846
+ <dt>JRuby</dt>
2847
+ <dd>
2848
+ The latest stable release of JRuby is officially supported. It is not
2849
+ recommended to use C extensions with JRuby. It is recommended to
2850
+ <tt>gem install trinidad</tt>.
2851
+ </dd>
2852
+ </dl>
2853
+
2854
+ We also keep an eye on upcoming Ruby versions.
2855
+
2856
+ The following Ruby implementations are not officially supported but still are
2857
+ known to run Sinatra:
2858
+
2859
+ * Older versions of JRuby and Rubinius
2860
+ * Ruby Enterprise Edition
2861
+ * MacRuby, Maglev, IronRuby
2862
+ * Ruby 1.9.0 and 1.9.1 (but we do recommend against using those)
2863
+
2864
+ Not being officially supported means if things only break there and not on a
2865
+ supported platform, we assume it's not our issue but theirs.
2866
+
2867
+ We also run our CI against ruby-head (the upcoming 2.1.0), but we can't
2868
+ guarantee anything, since it is constantly moving. Expect 2.1.0 to be fully
2869
+ supported.
2870
+
2871
+ Sinatra should work on any operating system supported by the chosen Ruby
2872
+ implementation.
2873
+
2874
+ If you run MacRuby, you should `gem install control_tower`.
2875
+
2876
+ Sinatra currently doesn't run on Cardinal, SmallRuby, BlueRuby or any
2877
+ Ruby version prior to 1.8.7.
2878
+
2879
+ ## The Bleeding Edge
2880
+
2881
+ If you would like to use Sinatra's latest bleeding-edge code, feel free to run your
2882
+ application against the master branch, it should be rather stable.
2883
+
2884
+ We also push out prerelease gems from time to time, so you can do a
2885
+
2886
+ ``` shell
2887
+ gem install sinatra --pre
2888
+ ```
2889
+
2890
+ to get some of the latest features.
2891
+
2892
+ ### With Bundler
2893
+
2894
+ If you want to run your application with the latest Sinatra, using
2895
+ [Bundler](http://gembundler.com/) is the recommended way.
2896
+
2897
+ First, install bundler, if you haven't:
2898
+
2899
+ ``` shell
2900
+ gem install bundler
2901
+ ```
2902
+
2903
+ Then, in your project directory, create a `Gemfile`:
2904
+
2905
+ ```ruby
2906
+ source 'https://rubygems.org'
2907
+ gem 'sinatra', :github => "sinatra/sinatra"
2908
+
2909
+ # other dependencies
2910
+ gem 'haml' # for instance, if you use haml
2911
+ gem 'activerecord', '~> 3.0' # maybe you also need ActiveRecord 3.x
2912
+ ```
2913
+
2914
+ Note that you will have to list all your application's dependencies in the `Gemfile`.
2915
+ Sinatra's direct dependencies (Rack and Tilt) will, however, be automatically
2916
+ fetched and added by Bundler.
2917
+
2918
+ Now you can run your app like this:
2919
+
2920
+ ``` shell
2921
+ bundle exec ruby myapp.rb
2922
+ ```
2923
+
2924
+ ### Roll Your Own
2925
+
2926
+ Create a local clone and run your app with the `sinatra/lib` directory
2927
+ on the `$LOAD_PATH`:
2928
+
2929
+ ``` shell
2930
+ cd myapp
2931
+ git clone git://github.com/sinatra/sinatra.git
2932
+ ruby -I sinatra/lib myapp.rb
2933
+ ```
2934
+
2935
+ To update the Sinatra sources in the future:
2936
+
2937
+ ``` shell
2938
+ cd myapp/sinatra
2939
+ git pull
2940
+ ```
2941
+
2942
+ ### Install Globally
2943
+
2944
+ You can build the gem on your own:
2945
+
2946
+ ``` shell
2947
+ git clone git://github.com/sinatra/sinatra.git
2948
+ cd sinatra
2949
+ rake sinatra.gemspec
2950
+ rake install
2951
+ ```
2952
+
2953
+ If you install gems as root, the last step should be:
2954
+
2955
+ ``` shell
2956
+ sudo rake install
2957
+ ```
2958
+
2959
+ ## Versioning
2960
+
2961
+ Sinatra follows [Semantic Versioning](http://semver.org/), both SemVer and
2962
+ SemVerTag.
2963
+
2964
+ ## Further Reading
2965
+
2966
+ * [Project Website](http://www.sinatrarb.com/) - Additional documentation,
2967
+ news, and links to other resources.
2968
+ * [Contributing](http://www.sinatrarb.com/contributing) - Find a bug? Need
2969
+ help? Have a patch?
2970
+ * [Issue tracker](http://github.com/sinatra/sinatra/issues)
2971
+ * [Twitter](http://twitter.com/sinatra)
2972
+ * [Mailing List](http://groups.google.com/group/sinatrarb/topics)
2973
+ * IRC: [#sinatra](irc://chat.freenode.net/#sinatra) on http://freenode.net
2974
+ * [Sinatra Book](http://sinatra-book.gittr.com) Cookbook Tutorial
2975
+ * [Sinatra Recipes](http://recipes.sinatrarb.com/) Community
2976
+ contributed recipes
2977
+ * API documentation for the [latest release](http://rubydoc.info/gems/sinatra)
2978
+ or the [current HEAD](http://rubydoc.info/github/sinatra/sinatra) on
2979
+ http://rubydoc.info
2980
+ * [CI server](http://travis-ci.org/sinatra/sinatra)