sinatra 2.2.0 → 3.2.0

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