sinatra 1.4.0.d → 1.4.0

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

Potentially problematic release.


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

data/CHANGES CHANGED
@@ -1,4 +1,4 @@
1
- = 1.4.0 / Not Yet Released
1
+ = 1.4.0 / 2013-03-15
2
2
 
3
3
  * Add support for LINK and UNLINK requests. (Konstantin Haase)
4
4
 
@@ -39,7 +39,7 @@
39
39
  * In addition to WebRick, Thin and Mongrel, Sinatra will now automatically pick
40
40
  up Puma, Trinidad, ControlTower or Net::HTTP::Server when installed. The
41
41
  logic for picking the server has been improved and now depends on the Ruby
42
- implementation used. (Mark Rada, Konstantin Haase)
42
+ implementation used. (Mark Rada, Konstantin Haase, Patricio Mac Adden)
43
43
 
44
44
  * "Sinatra doesn't know this ditty" pages now show the app class when running
45
45
  a modular application. This helps detecting where the response came from when
@@ -62,7 +62,8 @@
62
62
 
63
63
  * Make route parsing regex more robust. (Zoltan Dezso, Konstantin Haase)
64
64
 
65
- * Improve Accept header parsing, expose parameters. (Pieter van de Bruggen)
65
+ * Improve Accept header parsing, expose parameters. (Pieter van de Bruggen,
66
+ Konstantin Haase)
66
67
 
67
68
  * Add `layout_options` render option. Allows you, amongst other things, to
68
69
  render a layout from a different folder. (Konstantin Haase)
@@ -86,7 +87,7 @@
86
87
  * Improve documentation. (Kashyap, Stanislav Chistenko, Zachary Scott,
87
88
  Anthony Accomazzo, Peter Suschlik, Rachel Mehl, ymmtmsys, Anurag Priyam,
88
89
  burningTyger, Tony Miller, akicho8, Vasily Polovnyov, Markus Prinz,
89
- Alexey Muranov, Konstantin Haase)
90
+ Alexey Muranov, Erik Johnson, Vipul A M, Konstantin Haase)
90
91
 
91
92
  * Convert documentation to Markdown. (Kashyap, Robin Dupret, burningTyger,
92
93
  Vasily Polovnyov, Iain Barnett, Giuseppe Capizzi, Neil West)
@@ -99,7 +100,7 @@
99
100
  * Recalculate Content-Length even if hard coded if body is reset. Relevant
100
101
  mostly for error handlers. (Nathan Esquenazi, Konstantin Haase)
101
102
 
102
- * Plus sing is once again kept as such when used for URL matches. (Konstantin
103
+ * Plus sign is once again kept as such when used for URL matches. (Konstantin
103
104
  Haase)
104
105
 
105
106
  * Take views option into account for template caching. (Konstantin Haase)
@@ -112,6 +113,22 @@
112
113
 
113
114
  * Make tests run without warnings. (Patricio Mac Adden)
114
115
 
116
+ * Make sure value returned by `mime_type` is a String or nil, even when a
117
+ different object is passed in, like an AcceptEntry. (Konstantin Haase)
118
+
119
+ * Exceptions in `after` filter are now handled like any other exception.
120
+ (Nathan Esquenazi)
121
+
122
+ = 1.3.6 (backport release) / 2013-03-15
123
+
124
+ Backported from 1.4.0:
125
+
126
+ * Take views option into account for template caching. (Konstantin Haase)
127
+
128
+ * Improve documentation (Konstantin Haase)
129
+
130
+ * No longer override `define_singleton_method`. (Konstantin Haase)
131
+
115
132
  = 1.3.5 / 2013-02-25
116
133
 
117
134
  * Fix for RubyGems 2.0 (Uchio KONDO)
@@ -326,6 +343,20 @@
326
343
  * Fix handling of broken query params when displaying exceptions. (Luke
327
344
  Jahnke)
328
345
 
346
+ = 1.2.9 (backports release) / 2013-03-15
347
+
348
+ IMPORTANT: THIS IS THE LAST 1.2.x RELEASE, PLEASE UPGRADE.
349
+
350
+ * Display EOL warning when loading Sinatra. (Konstantin Haase)
351
+
352
+ * Improve documentation. (Anurag Priyam, Konstantin Haase)
353
+
354
+ * Do not modify the load path. (Konstantin Haase)
355
+
356
+ * Display deprecation warning if RUBY_IGNORE_CALLERS is used. (Konstantin Haase)
357
+
358
+ * Add backports library so we can still run on Ruby 1.8.6. (Konstantin Haase)
359
+
329
360
  = 1.2.8 (backports release) / 2011-12-30
330
361
 
331
362
  Backported from 1.3.2:
data/Gemfile CHANGED
@@ -41,8 +41,11 @@ gem 'maruku'
41
41
  gem 'creole'
42
42
  gem 'markaby'
43
43
  gem 'radius'
44
- gem 'rabl' unless RUBY_ENGINE =~ /jruby|maglev/
44
+ gem 'rabl' unless RUBY_ENGINE =~ /jruby|maglev/
45
45
  gem 'wlang', '>= 2.0.1' unless RUBY_ENGINE =~ /jruby|rbx/
46
+ gem 'therubyracer' unless RUBY_ENGINE =~ /jruby|rbx/
47
+ gem 'redcarpet' unless RUBY_ENGINE == 'jruby'
48
+ gem 'bluecloth' unless RUBY_ENGINE == 'jruby'
46
49
 
47
50
  if RUBY_ENGINE != 'rbx' or RUBY_VERSION < '1.9'
48
51
  gem 'liquid'
@@ -72,12 +75,9 @@ if RUBY_ENGINE != 'jruby' or not ENV['TRAVIS']
72
75
  end
73
76
  gem 'RedCloth' unless RUBY_ENGINE == "macruby"
74
77
  gem 'puma'
75
-
76
- ## bluecloth is broken
77
- #gem 'bluecloth'
78
78
  end
79
79
 
80
- gem 'net-http-server'
80
+ gem 'net-http-server' unless RUBY_VERSION == '1.8.7' || RUBY_ENGINE =~ /jruby|rbx/
81
81
 
82
82
  platforms :ruby_18, :jruby do
83
83
  gem 'json' unless RUBY_VERSION > '1.9' # is there a jruby but 1.8 only selector?
@@ -9,18 +9,18 @@ schnelle Erstellen von Webanwendungen in Ruby mit minimalem Aufwand
9
9
  ermöglicht:
10
10
 
11
11
  ```ruby
12
- # myapp.rb
13
- require 'sinatra'
14
- get '/' do
15
- 'Hallo Welt!'
16
- end
12
+ # myapp.rb
13
+ require 'sinatra'
14
+ get '/' do
15
+ 'Hallo Welt!'
16
+ end
17
17
  ```
18
18
 
19
19
  Einfach via `rubygems` installieren und starten:
20
20
 
21
21
  ```ruby
22
- gem install sinatra
23
- ruby myapp.rb
22
+ gem install sinatra
23
+ ruby myapp.rb
24
24
  ```
25
25
 
26
26
  Die Seite kann nun unter http://localhost:4567 betrachtet werden.
@@ -28,31 +28,124 @@ Die Seite kann nun unter http://localhost:4567 betrachtet werden.
28
28
  Es wird empfohlen, den Thin-Server via `gem install thin` zu installieren, den
29
29
  Sinatra dann, soweit vorhanden, automatisch verwendet.
30
30
 
31
+ ## Inhalt
32
+
33
+ * [Sinatra](#sinatra)
34
+ * [Routen](#routen)
35
+ * [Bedingungen](#bedingungen)
36
+ * [Rückgabewerte](#rckgabewerte)
37
+ * [Eigene Routen-Muster](#eigene-routen-muster)
38
+ * [Statische Dateien](#statische-dateien)
39
+ * [Views/Templates](#viewstemplates)
40
+ * [Direkte Templates](#direkte-templates)
41
+ * [Verfügbare Templatesprachen](#verfgbare-templatesprachen)
42
+ * [Haml Templates](#haml-templates)
43
+ * [Erb Templates](#erb-templates)
44
+ * [Builder Templates](#builder-templates)
45
+ * [Nokogiri Templates](#nokogiri-templates)
46
+ * [Sass Templates](#sass-templates)
47
+ * [SCSS Templates](#scss-templates)
48
+ * [Less Templates](#less-templates)
49
+ * [Liquid Templates](#liquid-templates)
50
+ * [Markdown Templates](#markdown-templates)
51
+ * [Textile Templates](#textile-templates)
52
+ * [RDoc Templates](#rdoc-templates)
53
+ * [Radius Templates](#radius-templates)
54
+ * [Markaby Templates](#markaby-templates)
55
+ * [RABL Templates](#rabl-templates)
56
+ * [Slim Templates](#slim-templates)
57
+ * [Creole Templates](#creole-templates)
58
+ * [CoffeeScript Templates](#coffeescript-templates)
59
+ * [Stylus Templates](#stylus-templates)
60
+ * [Yajl Templates](#yajl-templates)
61
+ * [WLang Templates](#wlang-templates)
62
+ * [Auf Variablen in Templates zugreifen](#auf-variablen-in-templates-zugreifen)
63
+ * [Templates mit `yield` und verschachtelte Layouts](#templates-mit-yield-und-verschachtelte-layouts)
64
+ * [Inline-Templates](#inline-templates)
65
+ * [Benannte Templates](#benannte-templates)
66
+ * [Dateiendungen zuordnen](#dateiendungen-zuordnen)
67
+ * [Eine eigene Template-Engine hinzufügen](#eine-eigene-template-engine-hinzufgen)
68
+ * [Filter](#filter)
69
+ * [Helfer](#helfer)
70
+ * [Sessions verwenden](#sessions-verwenden)
71
+ * [Anhalten](#anhalten)
72
+ * [Weiterspringen](#weiterspringen)
73
+ * [Eine andere Route ansteuern](#eine-andere-route-ansteuern)
74
+ * [Body, Status-Code und Header setzen](#body-status-code-und-header-setzen)
75
+ * [Response-Streams](#response-streams)
76
+ * [Logger](#logger)
77
+ * [Mime-Types](#mime-types)
78
+ * [URLs generieren](#urls-generieren)
79
+ * [Browser-Umleitung](#browser-umleitung)
80
+ * [Cache einsetzen](#cache-einsetzen)
81
+ * [Dateien versenden](#dateien-versenden)
82
+ * [Das Request-Objekt](#das-request-objekt)
83
+ * [Anhänge](#anhnge)
84
+ * [Umgang mit Datum und Zeit](#umgang-mit-datum-und-zeit)
85
+ * [Nachschlagen von Template-Dateien](#nachschlagen-von-template-dateien)
86
+ * [Konfiguration](#konfiguration)
87
+ * [Einstellung des Angriffsschutzes](#einstellung-des-angriffsschutzes)
88
+ * [Mögliche Einstellungen](#mgliche-einstellungen)
89
+ * [Umgebungen](#umgebungen)
90
+ * [Fehlerbehandlung](#fehlerbehandlung)
91
+ * [Nicht gefunden](#nicht-gefunden)
92
+ * [Fehler](#fehler)
93
+ * [Rack-Middleware](#rack-middleware)
94
+ * [Testen](#testen)
95
+ * [Sinatra::Base - Middleware, Bibliotheken und modulare Anwendungen](#sinatrabase---middleware-bibliotheken-und-modulare-anwendungen)
96
+ * [Modularer vs. klassischer Stil](#modularer-vs-klassischer-stil)
97
+ * [Eine modulare Applikation bereitstellen](#eine-modulare-applikation-bereitstellen)
98
+ * [Eine klassische Anwendung mit einer config.ru verwenden](#eine-klassische-anwendung-mit-einer-configru-verwenden)
99
+ * [Wann sollte eine config.ru-Datei verwendet werden?](#wann-sollte-eine-configru-datei-verwendet-werden)
100
+ * [Sinatra als Middleware nutzen](#sinatra-als-middleware-nutzen)
101
+ * [Dynamische Applikationserstellung](#dynamische-applikationserstellung)
102
+ * [Geltungsbereich und Bindung](#geltungsbereich-und-bindung)
103
+ * [Anwendungs- oder Klassen-Scope](#anwendungs--oder-klassen-scope)
104
+ * [Anfrage- oder Instanz-Scope](#anfrage--oder-instanz-scope)
105
+ * [Delegation-Scope](#delegation-scope)
106
+ * [Kommandozeile](#kommandozeile)
107
+ * [Systemanforderungen](#systemanforderungen)
108
+ * [Der neuste Stand (The Bleeding Edge)](#der-neuste-stand-the-bleeding-edge)
109
+ * [Mit Bundler](#mit-bundler)
110
+ * [Eigenes Repository](#eigenes-repository)
111
+ * [Gem erstellen](#gem-erstellen)
112
+ * [Versions-Verfahren](#versions-verfahren)
113
+ * [Mehr](#mehr)
114
+
31
115
  ## Routen
32
116
 
33
117
  In Sinatra wird eine Route durch eine HTTP-Methode und ein URL-Muster definiert.
34
118
  Jeder dieser Routen wird ein Ruby-Block zugeordnet:
35
119
 
36
120
  ```ruby
37
- get '/' do
38
- .. zeige etwas ..
39
- end
121
+ get '/' do
122
+ .. zeige etwas ..
123
+ end
40
124
 
41
- post '/' do
42
- .. erstelle etwas ..
43
- end
125
+ post '/' do
126
+ .. erstelle etwas ..
127
+ end
44
128
 
45
- put '/' do
46
- .. update etwas ..
47
- end
129
+ put '/' do
130
+ .. update etwas ..
131
+ end
48
132
 
49
- delete '/' do
50
- .. entferne etwas ..
51
- end
133
+ delete '/' do
134
+ .. entferne etwas ..
135
+ end
136
+
137
+ options '/' do
138
+ .. zeige, was wir können ..
139
+ end
140
+
141
+ link '/' do
142
+ .. verbinde etwas ..
143
+ end
144
+
145
+ unlink '/' do
146
+ .. trenne etwas ..
147
+ end
52
148
 
53
- options '/' do
54
- .. zeige, was wir können ..
55
- end
56
149
  ```
57
150
 
58
151
  Die Routen werden in der Reihenfolge durchlaufen, in der sie definiert wurden.
@@ -62,67 +155,67 @@ Die Muster der Routen können benannte Parameter beinhalten, die über den
62
155
  `params`-Hash zugänglich gemacht werden:
63
156
 
64
157
  ```ruby
65
- get '/hallo/:name' do
66
- # passt auf "GET /hallo/foo" und "GET /hallo/bar"
67
- # params[:name] ist 'foo' oder 'bar'
68
- "Hallo #{params[:name]}!"
69
- end
158
+ get '/hallo/:name' do
159
+ # passt auf "GET /hallo/foo" und "GET /hallo/bar"
160
+ # params[:name] ist 'foo' oder 'bar'
161
+ "Hallo #{params[:name]}!"
162
+ end
70
163
  ```
71
164
 
72
165
  Man kann auf diese auch mit Block-Parametern zugreifen:
73
166
 
74
167
  ```ruby
75
- get '/hallo/:name' do |n|
76
- "Hallo #{n}!"
77
- end
168
+ get '/hallo/:name' do |n|
169
+ "Hallo #{n}!"
170
+ end
78
171
  ```
79
172
 
80
173
  Routen-Muster können auch mit Splat- oder Wildcard-Parametern über das
81
174
  `params[:splat]`-Array angesprochen werden:
82
175
 
83
176
  ```ruby
84
- get '/sag/*/zu/*' do
85
- # passt auf /sag/hallo/zu/welt
86
- params[:splat] # => ["hallo", "welt"]
87
- end
177
+ get '/sag/*/zu/*' do
178
+ # passt auf /sag/hallo/zu/welt
179
+ params[:splat] # => ["hallo", "welt"]
180
+ end
88
181
 
89
- get '/download/*.*' do
90
- # passt auf /download/pfad/zu/datei.xml
91
- params[:splat] # => ["pfad/zu/datei", "xml"]
92
- end
182
+ get '/download/*.*' do
183
+ # passt auf /download/pfad/zu/datei.xml
184
+ params[:splat] # => ["pfad/zu/datei", "xml"]
185
+ end
93
186
  ```
94
187
 
95
188
  Oder mit Block-Parametern:
96
189
 
97
190
  ```ruby
98
- get '/download/*.*' do |pfad, endung|
99
- [pfad, endung] # => ["Pfad/zu/Datei", "xml"]
100
- end
191
+ get '/download/*.*' do |pfad, endung|
192
+ [pfad, endung] # => ["Pfad/zu/Datei", "xml"]
193
+ end
101
194
  ```
102
195
 
103
196
  Routen mit regulären Ausdrücken sind auch möglich:
104
197
 
105
198
  ```ruby
106
- get %r{/hallo/([\w]+)} do
107
- "Hallo, #{params[:captures].first}!"
108
- end
199
+ get %r{/hallo/([\w]+)} do
200
+ "Hallo, #{params[:captures].first}!"
201
+ end
109
202
  ```
110
203
 
111
204
  Und auch hier können Block-Parameter genutzt werden:
112
205
 
113
206
  ```ruby
114
- get %r{/hallo/([\w]+)} do |c|
115
- "Hallo, #{c}!"
116
- end
207
+ get %r{/hallo/([\w]+)} do |c|
208
+ "Hallo, #{c}!"
209
+ end
117
210
  ```
118
211
 
119
212
  Routen-Muster können auch mit optionalen Parametern ausgestattet werden:
120
213
 
121
214
  ```ruby
122
- get '/posts.?:format?' do
123
- # passt auf "GET /posts" sowie jegliche Erweiterung
124
- # wie "GET /posts.json", "GET /posts.xml" etc.
125
- end
215
+ get '/posts.?:format?' do
216
+ # passt auf "GET /posts" sowie jegliche Erweiterung
217
+ # wie "GET /posts.json", "GET /posts.xml" etc.
218
+ end
126
219
  ```
127
220
 
128
221
  Anmerkung: Solange man den sog. Path Traversal Attack-Schutz nicht deaktiviert
@@ -136,64 +229,64 @@ sein müssen, damit der Block ausgeführt wird. Möglich wäre etwa eine
136
229
  Einschränkung des User-Agents:
137
230
 
138
231
  ```ruby
139
- get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
140
- "Du verwendest Songbird Version #{params[:agent][0]}"
141
- end
232
+ get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
233
+ "Du verwendest Songbird Version #{params[:agent][0]}"
234
+ end
142
235
 
143
- get '/foo' do
144
- # passt auf andere Browser
145
- end
236
+ get '/foo' do
237
+ # passt auf andere Browser
238
+ end
146
239
  ```
147
240
 
148
241
  Andere mitgelieferte Bedingungen sind `host_name` und `provides`:
149
242
 
150
243
  ```ruby
151
- get '/', :host_name => /^admin\./ do
152
- "Adminbereich, Zugriff verweigert!"
153
- end
244
+ get '/', :host_name => /^admin\./ do
245
+ "Adminbereich, Zugriff verweigert!"
246
+ end
154
247
 
155
- get '/', :provides => 'html' do
156
- haml :index
157
- end
248
+ get '/', :provides => 'html' do
249
+ haml :index
250
+ end
158
251
 
159
- get '/', :provides => ['rss', 'atom', 'xml'] do
160
- builder :feed
161
- end
252
+ get '/', :provides => ['rss', 'atom', 'xml'] do
253
+ builder :feed
254
+ end
162
255
  ```
163
256
 
164
257
  Es können auch andere Bedingungen relativ einfach hinzugefügt werden:
165
258
 
166
259
  ```ruby
167
- set(:probability) { |value| condition { rand <= value } }
260
+ set(:probability) { |value| condition { rand <= value } }
168
261
 
169
- get '/auto_gewinnen', :probability => 0.1 do
170
- "Du hast gewonnen!"
171
- end
262
+ get '/auto_gewinnen', :probability => 0.1 do
263
+ "Du hast gewonnen!"
264
+ end
172
265
 
173
- get '/auto_gewinnen' do
174
- "Tut mir leid, verloren."
175
- end
266
+ get '/auto_gewinnen' do
267
+ "Tut mir leid, verloren."
268
+ end
176
269
  ```
177
270
 
178
271
  Bei Bedingungen, die mehrere Werte annehmen können, sollte ein Splat verwendet
179
272
  werden:
180
273
 
181
274
  ```ruby
182
- set(:auth) do |*roles| # <- hier kommt der Splat ins Spiel
183
- condition do
184
- unless logged_in? && roles.any? {|role| current_user.in_role? role }
185
- redirect "/login/", 303
186
- end
187
- end
275
+ set(:auth) do |*roles| # <- hier kommt der Splat ins Spiel
276
+ condition do
277
+ unless logged_in? && roles.any? {|role| current_user.in_role? role }
278
+ redirect "/login/", 303
188
279
  end
280
+ end
281
+ end
189
282
 
190
- get "/mein/account/", :auth => [:user, :admin] do
191
- "Mein Account"
192
- end
283
+ get "/mein/account/", :auth => [:user, :admin] do
284
+ "Mein Account"
285
+ end
193
286
 
194
- get "/nur/admin/", :auth => :admin do
195
- "Nur Admins dürfen hier rein!"
196
- end
287
+ get "/nur/admin/", :auth => :admin do
288
+ "Nur Admins dürfen hier rein!"
289
+ end
197
290
  ```
198
291
 
199
292
  ### Rückgabewerte
@@ -219,13 +312,13 @@ einen Rack-Rückgabewert, einen Rack-Body oder einen HTTP-Status-Code handelt:
219
312
  Damit lässt sich relativ einfach Streaming implementieren:
220
313
 
221
314
  ```ruby
222
- class Stream
223
- def each
224
- 100.times { |i| yield "#{i}\n" }
225
- end
226
- end
315
+ class Stream
316
+ def each
317
+ 100.times { |i| yield "#{i}\n" }
318
+ end
319
+ end
227
320
 
228
- get('/') { Stream.new }
321
+ get('/') { Stream.new }
229
322
  ```
230
323
 
231
324
  Ebenso kann die `stream`-Helfer-Methode (s.u.) verwendet werden, die Streaming
@@ -239,43 +332,43 @@ Das muss aber noch nicht alles sein, es können ohne großen Aufwand eigene
239
332
  Routen-Muster erstellt werden:
240
333
 
241
334
  ```ruby
242
- class AllButPattern
243
- Match = Struct.new(:captures)
335
+ class AllButPattern
336
+ Match = Struct.new(:captures)
244
337
 
245
- def initialize(except)
246
- @except = except
247
- @captures = Match.new([])
248
- end
338
+ def initialize(except)
339
+ @except = except
340
+ @captures = Match.new([])
341
+ end
249
342
 
250
- def match(str)
251
- @captures unless @except === str
252
- end
253
- end
343
+ def match(str)
344
+ @captures unless @except === str
345
+ end
346
+ end
254
347
 
255
- def all_but(pattern)
256
- AllButPattern.new(pattern)
257
- end
348
+ def all_but(pattern)
349
+ AllButPattern.new(pattern)
350
+ end
258
351
 
259
- get all_but("/index") do
260
- # ...
261
- end
352
+ get all_but("/index") do
353
+ # ...
354
+ end
262
355
  ```
263
356
 
264
357
  Beachte, dass das obige Beispiel etwas übertrieben wirkt. Es geht auch einfacher:
265
358
 
266
359
  ```ruby
267
- get // do
268
- pass if request.path_info == "/index"
269
- # ...
270
- end
360
+ get // do
361
+ pass if request.path_info == "/index"
362
+ # ...
363
+ end
271
364
  ```
272
365
 
273
366
  Oder unter Verwendung eines negativen look ahead:
274
367
 
275
368
  ```ruby
276
- get %r{^(?!/index$)} do
277
- # ...
278
- end
369
+ get %r{^(?!/index$)} do
370
+ # ...
371
+ end
279
372
  ```
280
373
  ## Statische Dateien
281
374
 
@@ -283,7 +376,7 @@ Statische Dateien werden aus dem `./public`-Ordner ausgeliefert. Es ist möglich
283
376
  einen anderen Ort zu definieren, indem man die `:public_folder`-Option setzt:
284
377
 
285
378
  ```ruby
286
- set :public_folder, File.dirname(__FILE__) + '/static'
379
+ set :public_folder, File.dirname(__FILE__) + '/static'
287
380
  ```
288
381
 
289
382
  Zu beachten ist, dass der Ordnername public nicht Teil der URL ist. Die Datei
@@ -298,9 +391,9 @@ Alle Templatesprachen verwenden ihre eigene Renderingmethode, die jeweils
298
391
  einen String zurückgibt:
299
392
 
300
393
  ```ruby
301
- get '/' do
302
- erb :index
303
- end
394
+ get '/' do
395
+ erb :index
396
+ end
304
397
  ```
305
398
 
306
399
  Dieses Beispiel rendert `views/index.erb`.
@@ -308,18 +401,18 @@ Dieses Beispiel rendert `views/index.erb`.
308
401
  Anstelle eines Templatenamens kann man auch direkt die Templatesprache verwenden:
309
402
 
310
403
  ```ruby
311
- get '/' do
312
- code = "<%= Time.now %>"
313
- erb code
314
- end
404
+ get '/' do
405
+ code = "<%= Time.now %>"
406
+ erb code
407
+ end
315
408
  ```
316
409
 
317
410
  Templates nehmen ein zweite Argument an, den Options-Hash:
318
411
 
319
412
  ```ruby
320
- get '/' do
321
- erb :index, :layout => :post
322
- end
413
+ get '/' do
414
+ erb :index, :layout => :post
415
+ end
323
416
  ```
324
417
 
325
418
  Dieses Beispiel rendert `views/index.erb` eingebettet in `views/post.erb`
@@ -328,19 +421,19 @@ Dieses Beispiel rendert `views/index.erb` eingebettet in `views/post.erb`
328
421
  Optionen, die Sinatra nicht versteht, werden an das Template weitergereicht:
329
422
 
330
423
  ```ruby
331
- get '/' do
332
- haml :index, :format => :html5
333
- end
424
+ get '/' do
425
+ haml :index, :format => :html5
426
+ end
334
427
  ```
335
428
 
336
429
  Für alle Templates können auch generelle Einstellungen festgelegt werden:
337
430
 
338
431
  ```ruby
339
- set :haml, :format => :html5
432
+ set :haml, :format => :html5
340
433
 
341
- get '/' do
342
- haml :index
343
- end
434
+ get '/' do
435
+ haml :index
436
+ end
344
437
  ```
345
438
 
346
439
  Optionen, die an die Rendermethode weitergegeben werden, überschreiben die
@@ -351,7 +444,8 @@ Einstellungen:
351
444
  <dl>
352
445
  <dt>locals</dt>
353
446
  <dd>Liste von lokalen Variablen, die and das Dokument weitergegeben werden.
354
- Praktisch für Partials. Beispiel:
447
+ Praktisch für Partials:
448
+
355
449
  <tt>erb "<%= foo %>", :locals => {:foo => "bar"}</tt></dd>
356
450
 
357
451
  <dt>default_encoding</dt>
@@ -364,9 +458,10 @@ Einstellungen:
364
458
 
365
459
  <dt>layout</dt>
366
460
  <dd>Legt fest, ob ein Layouttemplate verwendet werden soll oder nicht
367
- (<tt>true</tt> oder<tt>false</tt>). Ist es ein Symbol, dass legt es fest,
368
- welches Template als Layout verwendet wird. Beispiel:
369
- <tt><tt>erb :index, :layout => !request.xhr?</tt></tt></dd>
461
+ (<tt>true</tt> oder<tt>false</tt>). Ist es ein Symbol, dann legt es fest,
462
+ welches Template als Layout verwendet wird:
463
+
464
+ <tt>erb :index, :layout => !request.xhr?</tt></dd>
370
465
 
371
466
  <dt>content_type</dt>
372
467
  <dd>Content-Type den das Template ausgibt. Voreinstellung hängt von der
@@ -380,39 +475,53 @@ Einstellungen:
380
475
  <dt>layout_engine</dt>
381
476
  <dd>Legt fest, welcher Renderer für das Layout verantwortlich ist. Hilfreich
382
477
  für Sprachen, die sonst keine Templates unterstützen. Voreingestellt auf
383
- den Renderer, der für das Template verwendet wird. Beispiel:
478
+ den Renderer, der für das Template verwendet wird:
479
+
384
480
  <tt>set :rdoc, :layout_engine => :erb</tt></dd>
385
- </dl>
481
+ <dt>layout_options</dt>
482
+ <dd>Besondere Einstellungen, die nur für das Rendering verwendet werden:
386
483
 
484
+ <tt>set :rdoc, :layout_options => { :views => 'views/layouts' }</tt></dd>
485
+ </dl>
387
486
 
388
487
  Sinatra geht davon aus, dass die Templates sich im `./views` Verzeichnis
389
488
  befinden. Es kann jedoch ein anderer Ordner festgelegt werden:
390
489
 
391
490
  ```ruby
392
- set :views, settings.root + '/templates'
491
+ set :views, settings.root + '/templates'
393
492
  ```
394
493
 
395
494
  Es ist zu beachten, dass immer mit Symbolen auf Templates verwiesen werden muss,
396
495
  auch dann, wenn sie sich in einem Unterordner befinden:
397
496
 
398
497
  ```ruby
399
- haml :'unterverzeichnis/template'
498
+ haml :'unterverzeichnis/template'
400
499
  ```
401
500
 
402
501
  Rendering-Methoden rendern jeden String direkt.
403
502
 
503
+ ### Direkte Templates
504
+
505
+ ``` ruby
506
+ get '/' do
507
+ haml '%div.title Hallo Welt'
508
+ end
509
+ ```
510
+
511
+ Hier wird der String direkt gerendert.
512
+
404
513
  ### Verfügbare Templatesprachen
405
514
 
406
515
  Einige Sprachen haben mehrere Implementierungen. Um festzulegen, welche
407
516
  verwendet wird (und dann auch Thread-sicher ist), verwendet man am besten zu
408
- Beginn ein 'require':
517
+ Beginn ein `'require'`:
409
518
 
410
519
  ```ruby
411
- require 'rdiscount' # oder require 'bluecloth'
412
- get('/') { markdown :index }
520
+ require 'rdiscount' # oder require 'bluecloth'
521
+ get('/') { markdown :index }
413
522
  ```
414
523
 
415
- ### Haml Templates
524
+ #### Haml Templates
416
525
 
417
526
  <table>
418
527
  <tr>
@@ -430,7 +539,7 @@ Beginn ein 'require':
430
539
  </table>
431
540
 
432
541
 
433
- ### Erb Templates
542
+ #### Erb Templates
434
543
 
435
544
  <table>
436
545
  <tr>
@@ -449,7 +558,7 @@ Beginn ein 'require':
449
558
  </table>
450
559
 
451
560
 
452
- ### Builder Templates
561
+ #### Builder Templates
453
562
 
454
563
  <table>
455
564
  <tr>
@@ -468,7 +577,7 @@ Beginn ein 'require':
468
577
 
469
578
  Nimmt ebenso einen Block für Inline-Templates entgegen (siehe Beispiel).
470
579
 
471
- ### Nokogiri Templates
580
+ #### Nokogiri Templates
472
581
 
473
582
  <table>
474
583
  <tr>
@@ -487,7 +596,7 @@ Nimmt ebenso einen Block für Inline-Templates entgegen (siehe Beispiel).
487
596
 
488
597
  Nimmt ebenso einen Block für Inline-Templates entgegen (siehe Beispiel).
489
598
 
490
- ### Sass Templates
599
+ #### Sass Templates
491
600
 
492
601
  <table>
493
602
  <tr>
@@ -505,7 +614,7 @@ Nimmt ebenso einen Block für Inline-Templates entgegen (siehe Beispiel).
505
614
  </table>
506
615
 
507
616
 
508
- ### SCSS Templates
617
+ #### SCSS Templates
509
618
 
510
619
  <table>
511
620
  <tr>
@@ -523,7 +632,7 @@ Nimmt ebenso einen Block für Inline-Templates entgegen (siehe Beispiel).
523
632
  </table>
524
633
 
525
634
 
526
- ### Less Templates
635
+ #### Less Templates
527
636
 
528
637
  <table>
529
638
  <tr>
@@ -541,7 +650,7 @@ Nimmt ebenso einen Block für Inline-Templates entgegen (siehe Beispiel).
541
650
  </table>
542
651
 
543
652
 
544
- ### Liquid Templates
653
+ #### Liquid Templates
545
654
 
546
655
  <table>
547
656
  <tr>
@@ -562,7 +671,7 @@ Da man aus dem Liquid-Template heraus keine Ruby-Methoden aufrufen kann
562
671
  (ausgenommen `yield`), wird man üblicherweise locals verwenden wollen, mit
563
672
  denen man Variablen weitergibt.
564
673
 
565
- ### Markdown Templates
674
+ #### Markdown Templates
566
675
 
567
676
  <table>
568
677
  <tr>
@@ -590,15 +699,15 @@ keine locals verwenden kann, wird man Markdown üblicherweise in Kombination
590
699
  mit anderen Renderern verwenden wollen:
591
700
 
592
701
  ```ruby
593
- erb :overview, :locals => { :text => markdown(:einfuehrung) }
702
+ erb :overview, :locals => { :text => markdown(:einfuehrung) }
594
703
  ```
595
704
 
596
705
  Beachte, dass man die `markdown`-Methode auch aus anderen Templates heraus
597
706
  aufrufen kann:
598
707
 
599
708
  ```ruby
600
- %h1 Gruß von Haml!
601
- %p= markdown(:Grüße)
709
+ %h1 Gruß von Haml!
710
+ %p= markdown(:Grüße)
602
711
  ```
603
712
 
604
713
  Da man Ruby nicht von Markdown heraus aufrufen kann, können auch Layouts nicht
@@ -606,7 +715,7 @@ in Markdown geschrieben werden. Es ist aber möglich, einen Renderer für die
606
715
  Templates zu verwenden und einen anderen für das Layout, indem die
607
716
  `:layout_engine`-Option verwendet wird.
608
717
 
609
- ### Textile Templates
718
+ #### Textile Templates
610
719
 
611
720
  <table>
612
721
  <tr>
@@ -628,15 +737,15 @@ keine locals verwenden kann, wird man Textile üblicherweise in Kombination mit
628
737
  anderen Renderern verwenden wollen:
629
738
 
630
739
  ```ruby
631
- erb :overview, :locals => { :text => textile(:einfuehrung) }
740
+ erb :overview, :locals => { :text => textile(:einfuehrung) }
632
741
  ```
633
742
 
634
743
  Beachte, dass man die `textile`-Methode auch aus anderen Templates heraus
635
744
  aufrufen kann:
636
745
 
637
746
  ```ruby
638
- %h1 Gruß von Haml!
639
- %p= textile(:Grüße)
747
+ %h1 Gruß von Haml!
748
+ %p= textile(:Grüße)
640
749
  ```
641
750
 
642
751
  Da man Ruby nicht von Textile heraus aufrufen kann, können auch Layouts nicht
@@ -644,7 +753,7 @@ in Textile geschrieben werden. Es ist aber möglich, einen Renderer für die
644
753
  Templates zu verwenden und einen anderen für das Layout, indem die
645
754
  `:layout_engine`-Option verwendet wird.
646
755
 
647
- ### RDoc Templates
756
+ #### RDoc Templates
648
757
 
649
758
  <table>
650
759
  <tr>
@@ -666,15 +775,15 @@ keine locals verwenden kann, wird man RDoc üblicherweise in Kombination mit
666
775
  anderen Renderern verwenden wollen:
667
776
 
668
777
  ```ruby
669
- erb :overview, :locals => { :text => rdoc(:einfuehrung) }
778
+ erb :overview, :locals => { :text => rdoc(:einfuehrung) }
670
779
  ```
671
780
 
672
781
  Beachte, dass man die `rdoc`-Methode auch aus anderen Templates heraus
673
782
  aufrufen kann:
674
783
 
675
784
  ```ruby
676
- %h1 Gruß von Haml!
677
- %p= rdoc(:Grüße)
785
+ %h1 Gruß von Haml!
786
+ %p= rdoc(:Grüße)
678
787
  ```
679
788
 
680
789
  Da man Ruby nicht von RDoc heraus aufrufen kann, können auch Layouts nicht in
@@ -682,7 +791,7 @@ RDoc geschrieben werden. Es ist aber möglich, einen Renderer für die Templates
682
791
  zu verwenden und einen anderen für das Layout, indem die
683
792
  `:layout_engine`-Option verwendet wird.
684
793
 
685
- ### Radius Templates
794
+ #### Radius Templates
686
795
 
687
796
  <table>
688
797
  <tr>
@@ -702,7 +811,7 @@ zu verwenden und einen anderen für das Layout, indem die
702
811
  Da man aus dem Radius-Template heraus keine Ruby-Methoden aufrufen kann, wird
703
812
  man üblicherweise locals verwenden wollen, mit denen man Variablen weitergibt.
704
813
 
705
- ### Markaby Templates
814
+ #### Markaby Templates
706
815
 
707
816
  <table>
708
817
  <tr>
@@ -721,7 +830,7 @@ man üblicherweise locals verwenden wollen, mit denen man Variablen weitergibt.
721
830
 
722
831
  Nimmt ebenso einen Block für Inline-Templates entgegen (siehe Beispiel).
723
832
 
724
- ### RABL Templates
833
+ #### RABL Templates
725
834
 
726
835
  <table>
727
836
  <tr>
@@ -738,7 +847,7 @@ Nimmt ebenso einen Block für Inline-Templates entgegen (siehe Beispiel).
738
847
  </tr>
739
848
  </table>
740
849
 
741
- ### Slim Templates
850
+ #### Slim Templates
742
851
 
743
852
  <table>
744
853
  <tr>
@@ -755,7 +864,7 @@ Nimmt ebenso einen Block für Inline-Templates entgegen (siehe Beispiel).
755
864
  </tr>
756
865
  </table>
757
866
 
758
- ### Creole Templates
867
+ #### Creole Templates
759
868
 
760
869
  <table>
761
870
  <tr>
@@ -777,15 +886,15 @@ keine locals verwenden kann, wird man Creole üblicherweise in Kombination mit
777
886
  anderen Renderern verwenden wollen:
778
887
 
779
888
  ```ruby
780
- erb :overview, :locals => { :text => creole(:einfuehrung) }
889
+ erb :overview, :locals => { :text => creole(:einfuehrung) }
781
890
  ```
782
891
 
783
892
  Beachte, dass man die `creole`-Methode auch aus anderen Templates heraus
784
893
  aufrufen kann:
785
894
 
786
895
  ```ruby
787
- %h1 Gruß von Haml!
788
- %p= creole(:Grüße)
896
+ %h1 Gruß von Haml!
897
+ %p= creole(:Grüße)
789
898
  ```
790
899
 
791
900
  Da man Ruby nicht von Creole heraus aufrufen kann, können auch Layouts nicht in
@@ -793,13 +902,15 @@ Creole geschrieben werden. Es ist aber möglich, einen Renderer für die Templat
793
902
  zu verwenden und einen anderen für das Layout, indem die `:layout_engine`-Option
794
903
  verwendet wird.
795
904
 
796
- ### CoffeeScript Templates
905
+ #### CoffeeScript Templates
797
906
 
798
907
  <table>
799
908
  <tr>
800
909
  <td>Abhängigkeit</td>
801
- <td><a href="https://github.com/josh/ruby-coffee-script">coffee-script</a> und eine <a href="https://github.com/sstephenson/execjs/blob/master/README.md#readme">Möglichkeit JavaScript auszuführen</a>.</td>
802
- <tr>
910
+ <td><a href="https://github.com/josh/ruby-coffee-script">coffee-script</a>
911
+ und eine <a href="https://github.com/sstephenson/execjs/blob/master/README.md#readme">Möglichkeit JavaScript auszuführen</a>.
912
+ </td>
913
+ </tr>
803
914
  <td>Dateierweiterung</td>
804
915
  <td><tt>.coffee</tt></td>
805
916
  </tr>
@@ -809,7 +920,83 @@ verwendet wird.
809
920
  </tr>
810
921
  </table>
811
922
 
812
- ### WLang Templates
923
+ #### Stylus Templates
924
+
925
+ <table>
926
+ <tr>
927
+ <td>Abhängigkeit</td>
928
+ <td>
929
+ <a href="https://github.com/lucasmazza/ruby-stylus" title="Ruby Stylus">
930
+ Stylus
931
+ </a> und eine Möglichkeit
932
+ <a href="https://github.com/sstephenson/execjs/blob/master/README.md#readme" title="ExecJS">
933
+ JavaScript auszuführen
934
+ </a>.
935
+ </td>
936
+ </tr>
937
+ <tr>
938
+ <td>Dateierweiterung</td>
939
+ <td><tt>.styl</tt></td>
940
+ </tr>
941
+ <tr>
942
+ <td>Beispiel</td>
943
+ <td><tt>stylus :index</tt></td>
944
+ </tr>
945
+ </table>
946
+
947
+ Um Stylus-Templates ausführen zu können, müssen `stylus` und `stylus/tilt`
948
+ zuerst geladen werden:
949
+
950
+ ``` ruby
951
+ require 'sinatra'
952
+ require 'stylus'
953
+ require 'stylus/tilt'
954
+
955
+ get '/' do
956
+ stylus :example
957
+ end
958
+ ```
959
+
960
+ #### Yajl Templates
961
+
962
+ <table>
963
+ <tr>
964
+ <td>Abhängigkeit</td>
965
+ <td><a href="https://github.com/brianmario/yajl-ruby" title="yajl-ruby">yajl-ruby</a></td>
966
+ </tr>
967
+ <tr>
968
+ <td>Dateierweiterung</td>
969
+ <td><tt>.yajl</tt></td>
970
+ </tr>
971
+ <tr>
972
+ <td>Beispiel</td>
973
+ <td>
974
+ <tt>
975
+ yajl :index,
976
+ :locals => { :key => 'qux' },
977
+ :callback => 'present',
978
+ :variable => 'resource'
979
+ </tt>
980
+ </td>
981
+ </tr>
982
+ </table>
983
+
984
+ Die Template-Quelle wird als Ruby-String evaluiert. Die daraus resultierende
985
+ json Variable wird mit Hilfe von `#to_json` umgewandelt:
986
+
987
+ ``` ruby
988
+ json = { :foo => 'bar' }
989
+ json[:baz] = key
990
+ ```
991
+
992
+ Die `:callback` und `:variable` Optionen können mit dem gerenderten Objekt
993
+ verwendet werden:
994
+
995
+ ``` ruby
996
+ var resource = {"foo":"bar","baz":"qux"}; present(resource);
997
+ ```
998
+
999
+ #### WLang Templates
813
1000
 
814
1001
  <table>
815
1002
  <tr>
@@ -830,14 +1017,6 @@ Ruby-Methoden in wlang aufzurufen entspricht nicht den idiomatischen Vorgaben
830
1017
  von wlang, es bietet sich deshalb an, `:locals` zu verwenden. Layouts, die
831
1018
  wlang und `yield` verwenden, werden aber trotzdem unterstützt.
832
1019
 
833
- ### Eingebettete Templates
834
-
835
- ```ruby
836
- get '/' do
837
- haml '%div.title Hallo Welt'
838
- end
839
- ```
840
-
841
1020
  Rendert den eingebetteten Template-String.
842
1021
 
843
1022
  ### Auf Variablen in Templates zugreifen
@@ -846,43 +1025,81 @@ Templates werden in demselben Kontext ausgeführt wie Routen. Instanzvariablen
846
1025
  in Routen sind auch direkt im Template verfügbar:
847
1026
 
848
1027
  ```ruby
849
- get '/:id' do
850
- @foo = Foo.find(params[:id])
851
- haml '%h1= @foo.name'
852
- end
1028
+ get '/:id' do
1029
+ @foo = Foo.find(params[:id])
1030
+ haml '%h1= @foo.name'
1031
+ end
853
1032
  ```
854
1033
 
855
1034
  Oder durch einen expliziten Hash von lokalen Variablen:
856
1035
 
857
1036
  ```ruby
858
- get '/:id' do
859
- foo = Foo.find(params[:id])
860
- haml '%h1= bar.name', :locals => { :bar => foo }
861
- end
1037
+ get '/:id' do
1038
+ foo = Foo.find(params[:id])
1039
+ haml '%h1= bar.name', :locals => { :bar => foo }
1040
+ end
862
1041
  ```
863
1042
 
864
1043
  Dies wird typischerweise bei Verwendung von Subtemplates (partials) in anderen
865
1044
  Templates eingesetzt.
866
1045
 
1046
+ ### Templates mit `yield` und verschachtelte Layouts
1047
+
1048
+ Ein Layout ist üblicherweise ein Template, dass ein `yield` aufruft. Ein solches
1049
+ Template kann entweder wie oben beschrieben über die `:template` option
1050
+ verwendet werden oder mit einem Block gerendert werden:
1051
+
1052
+ ``` ruby
1053
+ erb :post, :layout => false do
1054
+ erb :index
1055
+ end
1056
+ ```
1057
+
1058
+ Dieser Code entspricht weitestgehend `erb :index, :layout => :post`.
1059
+
1060
+ Blöcke an Render-Methoden weiterzugeben ist besonders bei verschachtelten
1061
+ Layouts hilfreich:
1062
+
1063
+ ``` ruby
1064
+ erb :main_layout, :layout => false do
1065
+ erb :admin_layout do
1066
+ erb :user
1067
+ end
1068
+ end
1069
+ ```
1070
+
1071
+ Der gleiche Effekt kann auch mit weniger Code erreicht werden:
1072
+
1073
+ ``` ruby
1074
+ erb :admin_layout, :layout => :main_layout do
1075
+ erb :user
1076
+ end
1077
+ ```
1078
+
1079
+ Zur Zeit nehmen folgende Renderer Blöcke an: `erb`, `haml`, `liquid`, `slim `
1080
+ und `wlang`.
1081
+
1082
+ Das gleich gilt auch für die allgemeine `render` Methode.
1083
+
867
1084
  ### Inline-Templates
868
1085
 
869
1086
  Templates können auch am Ende der Datei definiert werden:
870
1087
 
871
1088
  ```ruby
872
- require 'sinatra'
1089
+ require 'sinatra'
873
1090
 
874
- get '/' do
875
- haml :index
876
- end
1091
+ get '/' do
1092
+ haml :index
1093
+ end
877
1094
 
878
- __END__
1095
+ __END__
879
1096
 
880
- @@ layout
881
- %html
882
- = yield
1097
+ @@ layout
1098
+ %html
1099
+ = yield
883
1100
 
884
- @@ index
885
- %div.title Hallo Welt!!!!!
1101
+ @@ index
1102
+ %div.title Hallo Welt!!!!!
886
1103
  ```
887
1104
 
888
1105
  Anmerkung: Inline-Templates, die in der Datei definiert sind, die `require
@@ -895,26 +1112,26 @@ werden.
895
1112
  Templates können auch mit der Top-Level `template`-Methode definiert werden:
896
1113
 
897
1114
  ```ruby
898
- template :layout do
899
- "%html\n =yield\n"
900
- end
1115
+ template :layout do
1116
+ "%html\n =yield\n"
1117
+ end
901
1118
 
902
- template :index do
903
- '%div.title Hallo Welt!'
904
- end
1119
+ template :index do
1120
+ '%div.title Hallo Welt!'
1121
+ end
905
1122
 
906
- get '/' do
907
- haml :index
908
- end
1123
+ get '/' do
1124
+ haml :index
1125
+ end
909
1126
  ```
910
1127
 
911
1128
  Wenn ein Template mit dem Namen "layout" existiert, wird es bei jedem Aufruf
912
1129
  verwendet. Durch `:layout => false` kann das Ausführen verhindert werden:
913
1130
 
914
1131
  ```ruby
915
- get '/' do
916
- haml :index, :layout => request.xhr?
917
- end
1132
+ get '/' do
1133
+ haml :index, :layout => request.xhr?
1134
+ end
918
1135
  ```
919
1136
 
920
1137
  ### Dateiendungen zuordnen
@@ -924,7 +1141,7 @@ genutzt werden. Wenn etwa die Dateiendung `tt` für Textile-Templates genutzt
924
1141
  werden soll, lässt sich dies wie folgt bewerkstelligen:
925
1142
 
926
1143
  ```ruby
927
- Tilt.register :tt, Tilt[:textile]
1144
+ Tilt.register :tt, Tilt[:textile]
928
1145
  ```
929
1146
 
930
1147
  ### Eine eigene Template-Engine hinzufügen
@@ -933,15 +1150,15 @@ Zu allererst muss die Engine bei Tilt registriert und danach eine
933
1150
  Rendering-Methode erstellt werden:
934
1151
 
935
1152
  ```ruby
936
- Tilt.register :mtt, MeineTolleTemplateEngine
1153
+ Tilt.register :mtt, MeineTolleTemplateEngine
937
1154
 
938
- helpers do
939
- def mtt(*args) render(:mtt, *args) end
940
- end
1155
+ helpers do
1156
+ def mtt(*args) render(:mtt, *args) end
1157
+ end
941
1158
 
942
- get '/' do
943
- mtt :index
944
- end
1159
+ get '/' do
1160
+ mtt :index
1161
+ end
945
1162
  ```
946
1163
 
947
1164
  Dieser Code rendert `./views/application.mtt`. Siehe
@@ -956,15 +1173,15 @@ Gesetzte Instanzvariablen in Filtern können in Routen und Templates verwendet
956
1173
  werden:
957
1174
 
958
1175
  ```ruby
959
- before do
960
- @note = 'Hi!'
961
- request.path_info = '/foo/bar/baz'
962
- end
1176
+ before do
1177
+ @note = 'Hi!'
1178
+ request.path_info = '/foo/bar/baz'
1179
+ end
963
1180
 
964
- get '/foo/*' do
965
- @note #=> 'Hi!'
966
- params[:splat] #=> 'bar/baz'
967
- end
1181
+ get '/foo/*' do
1182
+ @note #=> 'Hi!'
1183
+ params[:splat] #=> 'bar/baz'
1184
+ end
968
1185
  ```
969
1186
 
970
1187
  After-Filter werden nach jedem Request in demselben Kontext ausgeführt und
@@ -972,35 +1189,35 @@ können ebenfalls Request und Antwort ändern. In Before-Filtern gesetzte
972
1189
  Instanzvariablen können in After-Filtern verwendet werden:
973
1190
 
974
1191
  ```ruby
975
- after do
976
- puts response.status
977
- end
1192
+ after do
1193
+ puts response.status
1194
+ end
978
1195
  ```
979
1196
 
980
1197
  Filter können optional auch mit einem Muster ausgestattet werden, welches auf
981
1198
  den Request-Pfad passen muss, damit der Filter ausgeführt wird:
982
1199
 
983
1200
  ```ruby
984
- before '/protected/*' do
985
- authenticate!
986
- end
1201
+ before '/protected/*' do
1202
+ authenticate!
1203
+ end
987
1204
 
988
- after '/create/:slug' do |slug|
989
- session[:last_slug] = slug
990
- end
1205
+ after '/create/:slug' do |slug|
1206
+ session[:last_slug] = slug
1207
+ end
991
1208
  ```
992
1209
 
993
1210
  Ähnlich wie Routen können Filter auch mit weiteren Bedingungen eingeschränkt
994
1211
  werden:
995
1212
 
996
1213
  ```ruby
997
- before :agent => /Songbird/ do
998
- # ...
999
- end
1214
+ before :agent => /Songbird/ do
1215
+ # ...
1216
+ end
1000
1217
 
1001
- after '/blog/*', :host_name => 'example.com' do
1002
- # ...
1003
- end
1218
+ after '/blog/*', :host_name => 'example.com' do
1219
+ # ...
1220
+ end
1004
1221
  ```
1005
1222
 
1006
1223
  ## Helfer
@@ -1009,15 +1226,15 @@ Durch die Top-Level `helpers`-Methode werden sogenannte Helfer-Methoden
1009
1226
  definiert, die in Routen und Templates verwendet werden können:
1010
1227
 
1011
1228
  ```ruby
1012
- helpers do
1013
- def bar(name)
1014
- "#{name}bar"
1015
- end
1016
- end
1229
+ helpers do
1230
+ def bar(name)
1231
+ "#{name}bar"
1232
+ end
1233
+ end
1017
1234
 
1018
- get '/:name' do
1019
- bar(params[:name])
1020
- end
1235
+ get '/:name' do
1236
+ bar(params[:name])
1237
+ end
1021
1238
  ```
1022
1239
 
1023
1240
  ### Sessions verwenden
@@ -1025,15 +1242,15 @@ Sessions werden verwendet, um Zustände zwischen den Requests zu speichern. Sind
1025
1242
  sie aktiviert, kann ein Session-Hash je Benutzer-Session verwendet werden:
1026
1243
 
1027
1244
  ```ruby
1028
- enable :sessions
1245
+ enable :sessions
1029
1246
 
1030
- get '/' do
1031
- "value = " << session[:value].inspect
1032
- end
1247
+ get '/' do
1248
+ "value = " << session[:value].inspect
1249
+ end
1033
1250
 
1034
- get '/:value' do
1035
- session[:value] = params[:value]
1036
- end
1251
+ get '/:value' do
1252
+ session[:value] = params[:value]
1253
+ end
1037
1254
  ```
1038
1255
 
1039
1256
  Beachte, dass `enable :sessions` alle Daten in einem Cookie speichert. Unter
@@ -1043,15 +1260,15 @@ Session-Middleware verwendet werden. Dabei wird auf `enable :sessions`
1043
1260
  verzichtet und die Middleware wie üblich im Programm eingebunden:
1044
1261
 
1045
1262
  ```ruby
1046
- use Rack::Session::Pool, :expire_after => 2592000
1263
+ use Rack::Session::Pool, :expire_after => 2592000
1047
1264
 
1048
- get '/' do
1049
- "value = " << session[:value].inspect
1050
- end
1265
+ get '/' do
1266
+ "value = " << session[:value].inspect
1267
+ end
1051
1268
 
1052
- get '/:value' do
1053
- session[:value] = params[:value]
1054
- end
1269
+ get '/:value' do
1270
+ session[:value] = params[:value]
1271
+ end
1055
1272
  ```
1056
1273
 
1057
1274
  Um die Sicherheit zu erhöhen, werden Cookies, die Session-Daten führen, mit
@@ -1061,67 +1278,67 @@ wählen, damit sich alle Instanzen der Applikation dasselbe Session-Secret
1061
1278
  teilen:
1062
1279
 
1063
1280
  ```ruby
1064
- set :session_secret, 'super secret'
1281
+ set :session_secret, 'super secret'
1065
1282
  ```
1066
1283
 
1067
1284
  Zur weiteren Konfiguration kann man einen Hash mit Optionen in den `sessions`
1068
1285
  Einstellungen ablegen.
1069
1286
 
1070
1287
  ```ruby
1071
- set :sessions, :domain => 'foo.com'
1288
+ set :sessions, :domain => 'foo.com'
1072
1289
  ```
1073
1290
 
1074
- ## Anhalten
1291
+ ### Anhalten
1075
1292
 
1076
1293
  Zum sofortigen Stoppen eines Request in einem Filter oder einer Route:
1077
1294
 
1078
1295
  ```ruby
1079
- halt
1296
+ halt
1080
1297
  ```
1081
1298
 
1082
1299
  Der Status kann beim Stoppen auch angegeben werden:
1083
1300
 
1084
1301
  ```ruby
1085
- halt 410
1302
+ halt 410
1086
1303
  ```
1087
1304
 
1088
1305
  Oder auch den Response-Body:
1089
1306
 
1090
1307
  ```ruby
1091
- halt 'Hier steht der Body'
1308
+ halt 'Hier steht der Body'
1092
1309
  ```
1093
1310
 
1094
1311
  Oder beides:
1095
1312
 
1096
1313
  ```ruby
1097
- halt 401, 'verschwinde!'
1314
+ halt 401, 'verschwinde!'
1098
1315
  ```
1099
1316
 
1100
1317
  Sogar mit Headern:
1101
1318
 
1102
1319
  ```ruby
1103
- halt 402, {'Content-Type' => 'text/plain'}, 'Rache'
1320
+ halt 402, {'Content-Type' => 'text/plain'}, 'Rache'
1104
1321
  ```
1105
1322
 
1106
1323
  Natürlich ist es auch möglich, ein Template mit `halt` zu verwenden:
1107
1324
 
1108
1325
  ```ruby
1109
- halt erb(:error)
1326
+ halt erb(:error)
1110
1327
  ```
1111
1328
 
1112
- ## Weiterspringen
1329
+ ### Weiterspringen
1113
1330
 
1114
1331
  Eine Route kann mittels `pass` zu der nächsten passenden Route springen:
1115
1332
 
1116
1333
  ```ruby
1117
- get '/raten/:wer' do
1118
- pass unless params[:wer] == 'Frank'
1119
- 'Du hast mich!'
1120
- end
1334
+ get '/raten/:wer' do
1335
+ pass unless params[:wer] == 'Frank'
1336
+ 'Du hast mich!'
1337
+ end
1121
1338
 
1122
- get '/raten/*' do
1123
- 'Du hast mich nicht!'
1124
- end
1339
+ get '/raten/*' do
1340
+ 'Du hast mich nicht!'
1341
+ end
1125
1342
  ```
1126
1343
 
1127
1344
  Der Block wird sofort verlassen und es wird nach der nächsten treffenden Route
@@ -1134,14 +1351,14 @@ Manchmal entspricht `pass` nicht den Anforderungen, wenn das Ergebnis einer
1134
1351
  anderen Route gefordert wird. Um das zu erreichen, lässt sich `call` nutzen:
1135
1352
 
1136
1353
  ```ruby
1137
- get '/foo' do
1138
- status, headers, body = call env.merge("PATH_INFO" => '/bar')
1139
- [status, headers, body.map(&:upcase)]
1140
- end
1354
+ get '/foo' do
1355
+ status, headers, body = call env.merge("PATH_INFO" => '/bar')
1356
+ [status, headers, body.map(&:upcase)]
1357
+ end
1141
1358
 
1142
- get '/bar' do
1143
- "bar"
1144
- end
1359
+ get '/bar' do
1360
+ "bar"
1361
+ end
1145
1362
  ```
1146
1363
 
1147
1364
  Beachte, dass in dem oben angegeben Beispiel die Performance erheblich erhöht
@@ -1164,13 +1381,13 @@ Wird `body` verwendet, lässt sich der Body jederzeit über diese Methode
1164
1381
  aufrufen:
1165
1382
 
1166
1383
  ```ruby
1167
- get '/foo' do
1168
- body "bar"
1169
- end
1384
+ get '/foo' do
1385
+ body "bar"
1386
+ end
1170
1387
 
1171
- after do
1172
- puts body
1173
- end
1388
+ after do
1389
+ puts body
1390
+ end
1174
1391
  ```
1175
1392
 
1176
1393
  Ebenso ist es möglich, einen Block an `body` weiterzureichen, der dann vom
@@ -1180,13 +1397,13 @@ einsetzen, siehe auch "Rückgabewerte").
1180
1397
  Vergleichbar mit `body` lassen sich auch Status-Code und Header setzen:
1181
1398
 
1182
1399
  ```ruby
1183
- get '/foo' do
1184
- status 418
1185
- headers \
1186
- "Allow" => "BREW, POST, GET, PROPFIND, WHEN",
1187
- "Refresh" => "Refresh: 20; http://www.ietf.org/rfc/rfc2324.txt"
1188
- halt "Ich bin ein Teekesselchen"
1189
- end
1400
+ get '/foo' do
1401
+ status 418
1402
+ headers \
1403
+ "Allow" => "BREW, POST, GET, PROPFIND, WHEN",
1404
+ "Refresh" => "Refresh: 20; http://www.ietf.org/rfc/rfc2324.txt"
1405
+ halt "Ich bin ein Teekesselchen"
1406
+ end
1190
1407
  ```
1191
1408
 
1192
1409
  Genau wie bei `body` liest ein Aufrufen von `headers` oder `status` ohne
@@ -1201,15 +1418,15 @@ zurückschicken, bis er die Verbindung abbricht. Für diese Fälle gibt es die
1201
1418
  `stream`-Helfer-Methode, die es einem erspart eigene Lösungen zu schreiben:
1202
1419
 
1203
1420
  ```ruby
1204
- get '/' do
1205
- stream do |out|
1206
- out << "Das ist ja mal wieder fanta -\n"
1207
- sleep 0.5
1208
- out << " (bitte warten…) \n"
1209
- sleep 1
1210
- out << "- stisch!\n"
1211
- end
1212
- end
1421
+ get '/' do
1422
+ stream do |out|
1423
+ out << "Das ist ja mal wieder fanta -\n"
1424
+ sleep 0.5
1425
+ out << " (bitte warten…) \n"
1426
+ sleep 1
1427
+ out << "- stisch!\n"
1428
+ end
1429
+ end
1213
1430
  ```
1214
1431
 
1215
1432
  Damit lassen sich Streaming-APIs realisieren, sog.
@@ -1233,19 +1450,35 @@ Serven wie Thin oder Rainbows möglich, andere Server werden trotzdem den Stream
1233
1450
  beenden:
1234
1451
 
1235
1452
  ```ruby
1236
- set :server, :thin
1237
- connections = []
1453
+ # Durchgehende Anfrage (long polling)
1238
1454
 
1239
- get '/' do
1240
- # Den Stream offen halten
1241
- stream(:keep_open) { |out| connections << out }
1242
- end
1455
+ set :server, :thin
1456
+ connections = []
1243
1457
 
1244
- post '/' do
1245
- # In alle offenen Streams schreiben
1246
- connections.each { |out| out << params[:message] << "\n" }
1247
- "Nachricht verschickt"
1248
- end
1458
+ get '/subscribe' do
1459
+ # Client-Registrierung beim Server, damit Events mitgeteilt werden können
1460
+ stream(:keep_open) { |out| connections << out }
1461
+
1462
+ # tote Verbindungen entfernen
1463
+ connections.reject!(&:closed?)
1464
+
1465
+ # Rückmeldung
1466
+ "Angemeldet"
1467
+ end
1468
+
1469
+ post '/message' do
1470
+ connections.each do |out|
1471
+ # Den Client über eine neue Nachricht in Kenntnis setzen
1472
+ # notify client that a new message has arrived
1473
+ out << params[:message] << "\n"
1474
+
1475
+ # Den Client zur erneuten Verbindung auffordern
1476
+ out.close
1477
+ end
1478
+
1479
+ # Rückmeldung
1480
+ "Mitteiling erhalten"
1481
+ end
1249
1482
  ```
1250
1483
 
1251
1484
  ### Logger
@@ -1254,10 +1487,10 @@ Im Geltungsbereich eines Request stellt die `logger` Helfer-Methode eine `Logger
1254
1487
  Instanz zur Verfügung:
1255
1488
 
1256
1489
  ```ruby
1257
- get '/' do
1258
- logger.info "es passiert gerade etwas"
1259
- # ...
1260
- end
1490
+ get '/' do
1491
+ logger.info "es passiert gerade etwas"
1492
+ # ...
1493
+ end
1261
1494
  ```
1262
1495
 
1263
1496
  Der Logger übernimmt dabei automatisch alle im Rack-Handler eingestellten
@@ -1269,11 +1502,11 @@ voreingestellt ist. Wird über `Sinatra::Base` vererbt, muss es erst aktiviert
1269
1502
  werden:
1270
1503
 
1271
1504
  ```ruby
1272
- class MyApp < Sinatra::Base
1273
- configure :production, :development do
1274
- enable :logging
1275
- end
1276
- end
1505
+ class MyApp < Sinatra::Base
1506
+ configure :production, :development do
1507
+ enable :logging
1508
+ end
1509
+ end
1277
1510
  ```
1278
1511
 
1279
1512
  Damit auch keine Middleware das Logging aktivieren kann, muss die `logging`
@@ -1282,25 +1515,25 @@ diesem Fall `nil` zurückgeben wird. Üblicherweise wird das eingesetzt, wenn ei
1282
1515
  eigener Logger eingerichtet werden soll. Sinatra wird dann verwenden, was in
1283
1516
  `env['rack.logger']` eingetragen ist.
1284
1517
 
1285
- ## Mime-Types
1518
+ ### Mime-Types
1286
1519
 
1287
1520
  Wenn `send_file` oder statische Dateien verwendet werden, kann es vorkommen,
1288
1521
  dass Sinatra den Mime-Typ nicht kennt. Registriert wird dieser mit `mime_type`
1289
1522
  per Dateiendung:
1290
1523
 
1291
1524
  ```ruby
1292
- configure do
1293
- mime_type :foo, 'text/foo'
1294
- end
1525
+ configure do
1526
+ mime_type :foo, 'text/foo'
1527
+ end
1295
1528
  ```
1296
1529
 
1297
1530
  Es kann aber auch der `content_type`-Helfer verwendet werden:
1298
1531
 
1299
1532
  ```ruby
1300
- get '/' do
1301
- content_type :foo
1302
- "foo foo foo"
1303
- end
1533
+ get '/' do
1534
+ content_type :foo
1535
+ "foo foo foo"
1536
+ end
1304
1537
  ```
1305
1538
 
1306
1539
  ### URLs generieren
@@ -1309,7 +1542,7 @@ Zum Generieren von URLs sollte die `url`-Helfer-Methode genutzen werden, so z.B.
1309
1542
  beim Einsatz von Haml:
1310
1543
 
1311
1544
  ```ruby
1312
- %a{:href => url('/foo')} foo
1545
+ %a{:href => url('/foo')} foo
1313
1546
  ```
1314
1547
 
1315
1548
  Soweit vorhanden, wird Rücksicht auf Proxys und Rack-Router genommen.
@@ -1322,52 +1555,52 @@ Eine Browser-Umleitung kann mithilfe der `redirect`-Helfer-Methode erreicht
1322
1555
  werden:
1323
1556
 
1324
1557
  ```ruby
1325
- get '/foo' do
1326
- redirect to('/bar')
1327
- end
1558
+ get '/foo' do
1559
+ redirect to('/bar')
1560
+ end
1328
1561
  ```
1329
1562
 
1330
1563
  Weitere Parameter werden wie Argumente der `halt`-Methode behandelt:
1331
1564
 
1332
1565
  ```ruby
1333
- redirect to('/bar'), 303
1334
- redirect 'http://google.com', 'Hier bist du falsch'
1566
+ redirect to('/bar'), 303
1567
+ redirect 'http://google.com', 'Hier bist du falsch'
1335
1568
  ```
1336
1569
 
1337
1570
  Ebenso leicht lässt sich ein Schritt zurück mit dem Alias `redirect back`
1338
1571
  erreichen:
1339
1572
 
1340
1573
  ```ruby
1341
- get '/foo' do
1342
- "<a href='/bar'>mach was</a>"
1343
- end
1574
+ get '/foo' do
1575
+ "<a href='/bar'>mach was</a>"
1576
+ end
1344
1577
 
1345
- get '/bar' do
1346
- mach_was
1347
- redirect back
1348
- end
1578
+ get '/bar' do
1579
+ mach_was
1580
+ redirect back
1581
+ end
1349
1582
  ```
1350
1583
 
1351
1584
  Um Argumente an ein Redirect weiterzugeben, können sie entweder dem Query
1352
1585
  übergeben:
1353
1586
 
1354
1587
  ```ruby
1355
- redirect to('/bar?summe=42')
1588
+ redirect to('/bar?summe=42')
1356
1589
  ```
1357
1590
 
1358
1591
  oder eine Session verwendet werden:
1359
1592
 
1360
1593
  ```ruby
1361
- enable :sessions
1594
+ enable :sessions
1362
1595
 
1363
- get '/foo' do
1364
- session[:secret] = 'foo'
1365
- redirect to('/bar')
1366
- end
1596
+ get '/foo' do
1597
+ session[:secret] = 'foo'
1598
+ redirect to('/bar')
1599
+ end
1367
1600
 
1368
- get '/bar' do
1369
- session[:secret]
1370
- end
1601
+ get '/bar' do
1602
+ session[:secret]
1603
+ end
1371
1604
  ```
1372
1605
 
1373
1606
  ### Cache einsetzen
@@ -1378,27 +1611,27 @@ ordentliches HTTP-Caching.
1378
1611
  Der Cache-Control-Header lässt sich ganz einfach einstellen:
1379
1612
 
1380
1613
  ```ruby
1381
- get '/' do
1382
- cache_control :public
1383
- "schon gecached!"
1384
- end
1614
+ get '/' do
1615
+ cache_control :public
1616
+ "schon gecached!"
1617
+ end
1385
1618
  ```
1386
1619
 
1387
1620
  Profitipp: Caching im before-Filter aktivieren
1388
1621
 
1389
1622
  ```ruby
1390
- before do
1391
- cache_control :public, :must_revalidate, :max_age => 60
1392
- end
1623
+ before do
1624
+ cache_control :public, :must_revalidate, :max_age => 60
1625
+ end
1393
1626
  ```
1394
1627
 
1395
1628
  Bei Verwendung der `expires`-Helfermethode zum Setzen des gleichnamigen Headers,
1396
1629
  wird `Cache-Control` automatisch eigestellt:
1397
1630
 
1398
1631
  ```ruby
1399
- before do
1400
- expires 500, :public, :must_revalidate
1401
- end
1632
+ before do
1633
+ expires 500, :public, :must_revalidate
1634
+ end
1402
1635
  ```
1403
1636
 
1404
1637
  Um alles richtig zu machen, sollten auch `etag` oder `last_modified` verwendet
@@ -1407,19 +1640,19 @@ eigentliche Arbeit anfängt, da sie sofort eine Antwort senden, wenn der Client
1407
1640
  eine aktuelle Version im Cache vorhält:
1408
1641
 
1409
1642
  ```ruby
1410
- get '/article/:id' do
1411
- @article = Article.find params[:id]
1412
- last_modified @article.updated_at
1413
- etag @article.sha1
1414
- erb :article
1415
- end
1643
+ get '/article/:id' do
1644
+ @article = Article.find params[:id]
1645
+ last_modified @article.updated_at
1646
+ etag @article.sha1
1647
+ erb :article
1648
+ end
1416
1649
  ```
1417
1650
 
1418
1651
  ebenso ist es möglich einen
1419
1652
  [schwachen ETag](http://de.wikipedia.org/wiki/HTTP_ETag) zu verwenden:
1420
1653
 
1421
1654
  ```ruby
1422
- etag @article.sha1, :weak
1655
+ etag @article.sha1, :weak
1423
1656
  ```
1424
1657
 
1425
1658
  Diese Helfer führen nicht das eigentliche Caching aus, sondern geben die dafür
@@ -1428,16 +1661,16 @@ Cache-Lösungen bietet sich z.B.
1428
1661
  [rack-cache](https://github.com/rtomayko/rack-cache) an:
1429
1662
 
1430
1663
  ```ruby
1431
- require "rack/cache"
1432
- require "sinatra"
1664
+ require "rack/cache"
1665
+ require "sinatra"
1433
1666
 
1434
- use Rack::Cache
1667
+ use Rack::Cache
1435
1668
 
1436
- get '/' do
1437
- cache_control :public, :max_age => 36000
1438
- sleep 5
1439
- "hello"
1440
- end
1669
+ get '/' do
1670
+ cache_control :public, :max_age => 36000
1671
+ sleep 5
1672
+ "hello"
1673
+ end
1441
1674
  ```
1442
1675
 
1443
1676
  Um den `Cache-Control`-Header mit Informationen zu versorgen, verwendet man die
@@ -1452,18 +1685,18 @@ behandelt werden. Dieses Verhalten lässt sich mit der `:new_resource` Option
1452
1685
  ändern:
1453
1686
 
1454
1687
  ```ruby
1455
- get '/create' do
1456
- etag '', :new_resource => true
1457
- Article.create
1458
- erb :new_article
1459
- end
1688
+ get '/create' do
1689
+ etag '', :new_resource => true
1690
+ Article.create
1691
+ erb :new_article
1692
+ end
1460
1693
  ```
1461
1694
 
1462
1695
  Soll das schwache ETag trotzdem verwendet werden, verwendet man die `:kind`
1463
1696
  Option:
1464
1697
 
1465
1698
  ```ruby
1466
- etag '', :new_resource => true, :kind => :weak
1699
+ etag '', :new_resource => true, :kind => :weak
1467
1700
  ```
1468
1701
 
1469
1702
  ### Dateien versenden
@@ -1471,15 +1704,15 @@ Option:
1471
1704
  Zum Versenden von Dateien kann die `send_file`-Helfer-Methode verwendet werden:
1472
1705
 
1473
1706
  ```ruby
1474
- get '/' do
1475
- send_file 'foo.png'
1476
- end
1707
+ get '/' do
1708
+ send_file 'foo.png'
1709
+ end
1477
1710
  ```
1478
1711
 
1479
1712
  Für `send_file` stehen einige Hash-Optionen zur Verfügung:
1480
1713
 
1481
1714
  ```ruby
1482
- send_file 'foo.png', :type => :jpg
1715
+ send_file 'foo.png', :type => :jpg
1483
1716
  ```
1484
1717
 
1485
1718
  <dl>
@@ -1507,63 +1740,63 @@ Ruby-Prozess auch andere Möglichkeiten genutzt. Bei Verwendung der
1507
1740
  `send_file`-Helfer-Methode kümmert sich Sinatra selbstständig um die
1508
1741
  Range-Requests.
1509
1742
 
1510
- ## Das Request-Objekt
1743
+ ### Das Request-Objekt
1511
1744
 
1512
1745
  Auf das `request`-Objekt der eigehenden Anfrage kann vom Anfrage-Scope aus
1513
1746
  zugegriffen werden:
1514
1747
 
1515
1748
  ```ruby
1516
- # App läuft unter http://example.com/example
1517
- get '/foo' do
1518
- t = %w[text/css text/html application/javascript]
1519
- request.accept # ['text/html', '*/*']
1520
- request.accept? 'text/xml' # true
1521
- request.preferred_type(t) # 'text/html'
1522
- request.body # Request-Body des Client (siehe unten)
1523
- request.scheme # "http"
1524
- request.script_name # "/example"
1525
- request.path_info # "/foo"
1526
- request.port # 80
1527
- request.request_method # "GET"
1528
- request.query_string # ""
1529
- request.content_length # Länge des request.body
1530
- request.media_type # Medientypus von request.body
1531
- request.host # "example.com"
1532
- request.get? # true (ähnliche Methoden für andere Verben)
1533
- request.form_data? # false
1534
- request["IRGENDEIN_HEADER"] # Wert von IRGENDEIN_HEADER header
1535
- request.referrer # Der Referrer des Clients oder '/'
1536
- request.user_agent # User-Agent (verwendet in der :agent Bedingung)
1537
- request.cookies # Hash des Browser-Cookies
1538
- request.xhr? # Ist das hier ein Ajax-Request?
1539
- request.url # "http://example.com/example/foo"
1540
- request.path # "/example/foo"
1541
- request.ip # IP-Adresse des Clients
1542
- request.secure? # false (true wenn SSL)
1543
- request.forwarded? # true (Wenn es hinter einem Reverse-Proxy verwendet wird)
1544
- request.env # vollständiger env-Hash von Rack übergeben
1545
- end
1749
+ # App läuft unter http://example.com/example
1750
+ get '/foo' do
1751
+ t = %w[text/css text/html application/javascript]
1752
+ request.accept # ['text/html', '*/*']
1753
+ request.accept? 'text/xml' # true
1754
+ request.preferred_type(t) # 'text/html'
1755
+ request.body # Request-Body des Client (siehe unten)
1756
+ request.scheme # "http"
1757
+ request.script_name # "/example"
1758
+ request.path_info # "/foo"
1759
+ request.port # 80
1760
+ request.request_method # "GET"
1761
+ request.query_string # ""
1762
+ request.content_length # Länge des request.body
1763
+ request.media_type # Medientypus von request.body
1764
+ request.host # "example.com"
1765
+ request.get? # true (ähnliche Methoden für andere Verben)
1766
+ request.form_data? # false
1767
+ request["irgendein_param"] # Wert von einem Parameter; [] ist die Kurzform für den params Hash
1768
+ request.referrer # Der Referrer des Clients oder '/'
1769
+ request.user_agent # User-Agent (verwendet in der :agent Bedingung)
1770
+ request.cookies # Hash des Browser-Cookies
1771
+ request.xhr? # Ist das hier ein Ajax-Request?
1772
+ request.url # "http://example.com/example/foo"
1773
+ request.path # "/example/foo"
1774
+ request.ip # IP-Adresse des Clients
1775
+ request.secure? # false (true wenn SSL)
1776
+ request.forwarded? # true (Wenn es hinter einem Reverse-Proxy verwendet wird)
1777
+ request.env # vollständiger env-Hash von Rack übergeben
1778
+ end
1546
1779
  ```
1547
1780
 
1548
1781
  Manche Optionen, wie etwa `script_name` oder `path_info`, sind auch
1549
1782
  schreibbar:
1550
1783
 
1551
1784
  ```ruby
1552
- before { request.path_info = "/" }
1785
+ before { request.path_info = "/" }
1553
1786
 
1554
- get "/" do
1555
- "Alle Anfragen kommen hier an!"
1556
- end
1787
+ get "/" do
1788
+ "Alle Anfragen kommen hier an!"
1789
+ end
1557
1790
  ```
1558
1791
 
1559
1792
  Der `request.body` ist ein IO- oder StringIO-Objekt:
1560
1793
 
1561
1794
  ```ruby
1562
- post "/api" do
1563
- request.body.rewind # falls schon jemand davon gelesen hat
1564
- daten = JSON.parse request.body.read
1565
- "Hallo #{daten['name']}!"
1566
- end
1795
+ post "/api" do
1796
+ request.body.rewind # falls schon jemand davon gelesen hat
1797
+ daten = JSON.parse request.body.read
1798
+ "Hallo #{daten['name']}!"
1799
+ end
1567
1800
  ```
1568
1801
 
1569
1802
  ### Anhänge
@@ -1572,19 +1805,19 @@ Damit der Browser erkennt, dass ein Response gespeichert und nicht im Browser
1572
1805
  angezeigt werden soll, kann der `attachment`-Helfer verwendet werden:
1573
1806
 
1574
1807
  ```ruby
1575
- get '/' do
1576
- attachment
1577
- "Speichern!"
1578
- end
1808
+ get '/' do
1809
+ attachment
1810
+ "Speichern!"
1811
+ end
1579
1812
  ```
1580
1813
 
1581
1814
  Ebenso kann eine Dateiname als Parameter hinzugefügt werden:
1582
1815
 
1583
1816
  ```ruby
1584
- get '/' do
1585
- attachment "info.txt"
1586
- "Speichern!"
1587
- end
1817
+ get '/' do
1818
+ attachment "info.txt"
1819
+ "Speichern!"
1820
+ end
1588
1821
  ```
1589
1822
 
1590
1823
  ### Umgang mit Datum und Zeit
@@ -1594,10 +1827,10 @@ Time-Objekt generiert. Ebenso kann sie nach `DateTime`, `Date` und ähnliche
1594
1827
  Klassen konvertieren:
1595
1828
 
1596
1829
  ```ruby
1597
- get '/' do
1598
- pass if Time.now > time_for('Dec 23, 2012')
1599
- "noch Zeit"
1600
- end
1830
+ get '/' do
1831
+ pass if Time.now > time_for('Dec 23, 2012')
1832
+ "noch Zeit"
1833
+ end
1601
1834
  ```
1602
1835
 
1603
1836
  Diese Methode wird intern für +expires, `last_modiefied` und ihresgleichen
@@ -1606,21 +1839,21 @@ Verhalten erweitern, indem man `time_for` in der eigenen Applikation
1606
1839
  überschreibt:
1607
1840
 
1608
1841
  ```ruby
1609
- helpers do
1610
- def time_for(value)
1611
- case value
1612
- when :yesterday then Time.now - 24*60*60
1613
- when :tomorrow then Time.now + 24*60*60
1614
- else super
1615
- end
1616
- end
1842
+ helpers do
1843
+ def time_for(value)
1844
+ case value
1845
+ when :yesterday then Time.now - 24*60*60
1846
+ when :tomorrow then Time.now + 24*60*60
1847
+ else super
1617
1848
  end
1849
+ end
1850
+ end
1618
1851
 
1619
- get '/' do
1620
- last_modified :yesterday
1621
- expires :tomorrow
1622
- "Hallo"
1623
- end
1852
+ get '/' do
1853
+ last_modified :yesterday
1854
+ expires :tomorrow
1855
+ "Hallo"
1856
+ end
1624
1857
  ```
1625
1858
 
1626
1859
  ### Nachschlagen von Template-Dateien
@@ -1629,9 +1862,9 @@ Die `find_template`-Helfer-Methode wird genutzt, um Template-Dateien zum Rendern
1629
1862
  aufzufinden:
1630
1863
 
1631
1864
  ```ruby
1632
- find_template settings.views, 'foo', Tilt[:haml] do |file|
1633
- puts "könnte diese hier sein: #{file}"
1634
- end
1865
+ find_template settings.views, 'foo', Tilt[:haml] do |file|
1866
+ puts "könnte diese hier sein: #{file}"
1867
+ end
1635
1868
  ```
1636
1869
 
1637
1870
  Das ist zwar nicht wirklich brauchbar, aber wenn man sie überschreibt, kann sie
@@ -1639,28 +1872,28 @@ nützlich werden, um eigene Nachschlage-Mechanismen einzubauen. Zum Beispiel
1639
1872
  dann, wenn mehr als nur ein view-Verzeichnis verwendet werden soll:
1640
1873
 
1641
1874
  ```ruby
1642
- set :views, ['views', 'templates']
1875
+ set :views, ['views', 'templates']
1643
1876
 
1644
- helpers do
1645
- def find_template(views, name, engine, &block)
1646
- Array(views).each { |v| super(v, name, engine, &block) }
1647
- end
1648
- end
1877
+ helpers do
1878
+ def find_template(views, name, engine, &block)
1879
+ Array(views).each { |v| super(v, name, engine, &block) }
1880
+ end
1881
+ end
1649
1882
  ```
1650
1883
 
1651
1884
  Ein anderes Beispiel wäre, verschiedene Vereichnisse für verschiedene Engines
1652
1885
  zu verwenden:
1653
1886
 
1654
1887
  ```ruby
1655
- set :views, :sass => 'views/sass', :haml => 'templates', :default => 'views'
1888
+ set :views, :sass => 'views/sass', :haml => 'templates', :default => 'views'
1656
1889
 
1657
- helpers do
1658
- def find_template(views, name, engine, &block)
1659
- _, folder = views.detect { |k,v| engine == Tilt[k] }
1660
- folder ||= views[:default]
1661
- super(folder, name, engine, &block)
1662
- end
1663
- end
1890
+ helpers do
1891
+ def find_template(views, name, engine, &block)
1892
+ _, folder = views.detect { |k,v| engine == Tilt[k] }
1893
+ folder ||= views[:default]
1894
+ super(folder, name, engine, &block)
1895
+ end
1896
+ end
1664
1897
  ```
1665
1898
 
1666
1899
  Ebensogut könnte eine Extension aber auch geschrieben und mit anderen geteilt
@@ -1674,61 +1907,61 @@ Inhalt gecached, solange nicht im Entwicklungsmodus gearbeitet wird. Das sollte
1674
1907
  im Hinterkopf behalten werden, wenn irgendwelche verrückten Methoden
1675
1908
  zusammenbastelt werden.
1676
1909
 
1677
- ## Konfiguration
1910
+ ### Konfiguration
1678
1911
 
1679
1912
  Wird einmal beim Starten in jedweder Umgebung ausgeführt:
1680
1913
 
1681
1914
  ```ruby
1682
- configure do
1683
- # setze eine Option
1684
- set :option, 'wert'
1915
+ configure do
1916
+ # setze eine Option
1917
+ set :option, 'wert'
1685
1918
 
1686
- # setze mehrere Optionen
1687
- set :a => 1, :b => 2
1919
+ # setze mehrere Optionen
1920
+ set :a => 1, :b => 2
1688
1921
 
1689
- # das gleiche wie `set :option, true`
1690
- enable :option
1922
+ # das gleiche wie `set :option, true`
1923
+ enable :option
1691
1924
 
1692
- # das gleiche wie `set :option, false`
1693
- disable :option
1925
+ # das gleiche wie `set :option, false`
1926
+ disable :option
1694
1927
 
1695
- # dynamische Einstellungen mit Blöcken
1696
- set(:css_dir) { File.join(views, 'css') }
1697
- end
1928
+ # dynamische Einstellungen mit Blöcken
1929
+ set(:css_dir) { File.join(views, 'css') }
1930
+ end
1698
1931
  ```
1699
1932
 
1700
1933
  Läuft nur, wenn die Umgebung (RACK_ENV-Umgebungsvariable) auf `:production`
1701
1934
  gesetzt ist:
1702
1935
 
1703
1936
  ```ruby
1704
- configure :production do
1705
- ...
1706
- end
1937
+ configure :production do
1938
+ ...
1939
+ end
1707
1940
  ```
1708
1941
 
1709
1942
  Läuft nur, wenn die Umgebung auf `:production` oder auf `:test` gesetzt ist:
1710
1943
 
1711
1944
  ```ruby
1712
- configure :production, :test do
1713
- ...
1714
- end
1945
+ configure :production, :test do
1946
+ ...
1947
+ end
1715
1948
  ```
1716
1949
 
1717
1950
  Diese Einstellungen sind über `settings` erreichbar:
1718
1951
 
1719
1952
  ```ruby
1720
- configure do
1721
- set :foo, 'bar'
1722
- end
1953
+ configure do
1954
+ set :foo, 'bar'
1955
+ end
1723
1956
 
1724
- get '/' do
1725
- settings.foo? # => true
1726
- settings.foo # => 'bar'
1727
- ...
1728
- end
1957
+ get '/' do
1958
+ settings.foo? # => true
1959
+ settings.foo # => 'bar'
1960
+ ...
1961
+ end
1729
1962
  ```
1730
1963
 
1731
- ### Einstellung des Angriffsschutzes
1964
+ #### Einstellung des Angriffsschutzes
1732
1965
 
1733
1966
  Sinatra verwendet
1734
1967
  [Rack::Protection](https://github.com/rkh/rack-protection#readme), um die
@@ -1738,23 +1971,23 @@ Geschwindigkeitszuwachs steht aber in keinem Verhätnis zu den möglichen
1738
1971
  Risiken.
1739
1972
 
1740
1973
  ```ruby
1741
- disable :protection
1974
+ disable :protection
1742
1975
  ```
1743
1976
 
1744
1977
  Um einen bestimmten Schutzmechanismus zu deaktivieren, fügt man `protection`
1745
1978
  einen Hash mit Optionen hinzu:
1746
1979
 
1747
1980
  ```ruby
1748
- set :protection, :except => :path_traversal
1981
+ set :protection, :except => :path_traversal
1749
1982
  ```
1750
1983
 
1751
1984
  Neben Strings akzeptiert `:except` auch Arrays, um gleich mehrere
1752
1985
  Schutzmechanismen zu deaktivieren:
1753
1986
 
1754
1987
  ```ruby
1755
- set :protection, :except => [:path_traversal, :session_hijacking]
1988
+ set :protection, :except => [:path_traversal, :session_hijacking]
1756
1989
  ```
1757
- ## Möglichee Einstellungen
1990
+ #### Mögliche Einstellungen
1758
1991
 
1759
1992
  <dl>
1760
1993
  <dt>absolute_redirects</dt>
@@ -1767,10 +2000,9 @@ Schutzmechanismen zu deaktivieren:
1767
2000
  Standardmäßig nicht aktiviert.</dd>
1768
2001
 
1769
2002
  <dt>add_charsets</dt>
1770
- <dd>
1771
- Mime-Types werden hier automatisch der Helfer-Methode <tt>content_type</tt>
1772
- zugeordnet. Es empfielt sich, Werte hinzuzufügen statt sie zu
1773
- überschreiben: <tt>settings.add_charsets << "application/foobar"</tt>
2003
+ <dd>Mime-Types werden hier automatisch der Helfer-Methode
2004
+ <tt>content_type</tt> zugeordnet. Es empfielt sich, Werte hinzuzufügen statt
2005
+ sie zu überschreiben: <tt>settings.add_charsets << "application/foobar"</tt>
1774
2006
  </dd>
1775
2007
 
1776
2008
  <dt>app_file</dt>
@@ -1778,8 +2010,8 @@ Schutzmechanismen zu deaktivieren:
1778
2010
  Inline-, View- und öffentliche Verzeichnis des Projekts festzustellen.</dd>
1779
2011
 
1780
2012
  <dt>bind</dt>
1781
- <dd>IP-Address, an die gebunden wird (Standardwert: 0.0.0.0). Wird nur für
1782
- den eingebauten Server verwendet.</dd>
2013
+ <dd>IP-Address, an die gebunden wird (Standardwert: <tt>0.0.0.0</tt>). Wird
2014
+ nur für den eingebauten Server verwendet.</dd>
1783
2015
 
1784
2016
  <dt>default_encoding</dt>
1785
2017
  <dd>Das Encoding, falls keines angegeben wurde. Standardwert ist
@@ -1848,9 +2080,8 @@ Schutzmechanismen zu deaktivieren:
1848
2080
 
1849
2081
  <dt>server</dt>
1850
2082
  <dd>Server oder Liste von Servern, die als eingebaute Server zur Verfügung
1851
- stehen. Standardmäßig auf [‘thin’, ‘mongrel’, ‘webrick’] voreingestellt. Die
1852
- Anordnung gibt die Priorität
1853
- vor.</dd>
2083
+ stehen. Standardmäßig auf <tt>[‘thin’, ‘mongrel’, ‘webrick’]</tt>
2084
+ voreingestellt. Die Anordnung gibt die Priorität vor.</dd>
1854
2085
 
1855
2086
  <dt>sessions</dt>
1856
2087
  <dd>Sessions auf Cookiebasis mittels
@@ -1878,9 +2109,17 @@ Schutzmechanismen zu deaktivieren:
1878
2109
  mehrere Werte gleichzeitig zu übergeben: <tt>set :static_cache_control,
1879
2110
  [:public, :max_age => 300]</tt></dd>
1880
2111
 
2112
+ <dt>threaded</dt>
2113
+ <dd>Wird es auf <tt>true</tt> gesetzt, wird Thin aufgefordert
2114
+ <tt>EventMachine.defer</tt> zur Verarbeitung des Requests einzusetzen.</dd>
2115
+
1881
2116
  <dt>views</dt>
1882
2117
  <dd>Verzeichnis der Views. Leitet sich von der <tt>app_file</tt> Einstellung
1883
2118
  ab, wenn nicht gesetzt.</dd>
2119
+
2120
+ <dt>x_cascade</dt>
2121
+ <dd>Einstellung, ob der X-Cascade Header bei fehlender Route gesetzt wird oder
2122
+ nicht. Standardeinstellung ist <tt>true</tt>.</dd>
1884
2123
  </dl>
1885
2124
 
1886
2125
  ## Umgebungen
@@ -1896,7 +2135,7 @@ Um die Anwendung in einer anderen Umgebung auszuführen kann man die `-e`
1896
2135
  Option verwenden:
1897
2136
 
1898
2137
  ```
1899
- ruby my_app.rb -e [ENVIRONMENT]
2138
+ ruby my_app.rb -e [ENVIRONMENT]
1900
2139
  ```
1901
2140
 
1902
2141
  In der Anwendung kann man die die Methoden `development?`, `test?` und
@@ -1913,9 +2152,9 @@ Wenn eine `Sinatra::NotFound`-Exception geworfen wird oder der Statuscode 404
1913
2152
  ist, wird der `not_found`-Handler ausgeführt:
1914
2153
 
1915
2154
  ```ruby
1916
- not_found do
1917
- 'Seite kann nirgendwo gefunden werden.'
1918
- end
2155
+ not_found do
2156
+ 'Seite kann nirgendwo gefunden werden.'
2157
+ end
1919
2158
  ```
1920
2159
 
1921
2160
  ### Fehler
@@ -1925,55 +2164,56 @@ Routen-Block oder in einem Filter geworfen wurde. Die Exception kann über die
1925
2164
  `sinatra.error`-Rack-Variable angesprochen werden:
1926
2165
 
1927
2166
  ```ruby
1928
- error do
1929
- 'Entschuldige, es gab einen hässlichen Fehler - ' + env['sinatra.error'].name
1930
- end
2167
+ error do
2168
+ 'Entschuldige, es gab einen hässlichen Fehler - ' + env['sinatra.error'].name
2169
+ end
1931
2170
  ```
1932
2171
 
1933
2172
  Benutzerdefinierte Fehler:
1934
2173
 
1935
2174
  ```ruby
1936
- error MeinFehler do
1937
- 'Au weia, ' + env['sinatra.error'].message
1938
- end
2175
+ error MeinFehler do
2176
+ 'Au weia, ' + env['sinatra.error'].message
2177
+ end
1939
2178
  ```
1940
2179
 
1941
2180
  Dann, wenn das passiert:
1942
2181
 
1943
2182
  ```ruby
1944
- get '/' do
1945
- raise MeinFehler, 'etwas Schlimmes ist passiert'
1946
- end
2183
+ get '/' do
2184
+ raise MeinFehler, 'etwas Schlimmes ist passiert'
2185
+ end
1947
2186
  ```
1948
2187
 
1949
2188
  bekommt man dieses:
1950
2189
 
1951
2190
  ```
1952
- Au weia, etwas Schlimmes ist passiert
2191
+ Au weia, etwas Schlimmes ist passiert
1953
2192
  ```
1954
2193
 
1955
2194
  Alternativ kann ein Error-Handler auch für einen Status-Code definiert werden:
1956
2195
 
1957
2196
  ```ruby
1958
- error 403 do
1959
- 'Zugriff verboten'
1960
- end
2197
+ error 403 do
2198
+ 'Zugriff verboten'
2199
+ end
1961
2200
 
1962
- get '/geheim' do
1963
- 403
1964
- end
2201
+ get '/geheim' do
2202
+ 403
2203
+ end
1965
2204
  ```
1966
2205
 
1967
2206
  Oder ein Status-Code-Bereich:
1968
2207
 
1969
2208
  ```ruby
1970
- error 400..510 do
1971
- 'Hallo?'
1972
- end
2209
+ error 400..510 do
2210
+ 'Hallo?'
2211
+ end
1973
2212
  ```
1974
2213
 
1975
2214
  Sinatra setzt verschiedene `not_found`- und `error`-Handler in der
1976
- Development-Umgebung.
2215
+ Development-Umgebung ein, um hilfreiche Debugging Informationen und Stack Traces
2216
+ anzuzeigen.
1977
2217
 
1978
2218
  ## Rack-Middleware
1979
2219
 
@@ -1987,15 +2227,15 @@ Sinatra macht das Erstellen von Middleware-Verkettungen mit der
1987
2227
  Top-Level-Methode `use` zu einem Kinderspiel:
1988
2228
 
1989
2229
  ```ruby
1990
- require 'sinatra'
1991
- require 'meine_middleware'
2230
+ require 'sinatra'
2231
+ require 'meine_middleware'
1992
2232
 
1993
- use Rack::Lint
1994
- use MeineMiddleware
2233
+ use Rack::Lint
2234
+ use MeineMiddleware
1995
2235
 
1996
- get '/hallo' do
1997
- 'Hallo Welt'
1998
- end
2236
+ get '/hallo' do
2237
+ 'Hallo Welt'
2238
+ end
1999
2239
  ```
2000
2240
 
2001
2241
  Die Semantik von `use` entspricht der gleichnamigen Methode der
@@ -2004,9 +2244,9 @@ Die Semantik von `use` entspricht der gleichnamigen Methode der
2004
2244
  `use`-Methode mehrere/verschiedene Argumente und auch Blöcke entgegennimmt:
2005
2245
 
2006
2246
  ```ruby
2007
- use Rack::Auth::Basic do |username, password|
2008
- username == 'admin' && password == 'geheim'
2009
- end
2247
+ use Rack::Auth::Basic do |username, password|
2248
+ username == 'admin' && password == 'geheim'
2249
+ end
2010
2250
  ```
2011
2251
 
2012
2252
  Rack bietet eine Vielzahl von Standard-Middlewares für Logging, Debugging,
@@ -2027,34 +2267,37 @@ werden. [Rack::Test](http://rdoc.info/github/brynary/rack-test/master/frames)
2027
2267
  wird empfohlen:
2028
2268
 
2029
2269
  ```ruby
2030
- require 'my_sinatra_app'
2031
- require 'test/unit'
2032
- require 'rack/test'
2270
+ require 'my_sinatra_app'
2271
+ require 'test/unit'
2272
+ require 'rack/test'
2033
2273
 
2034
- class MyAppTest < Test::Unit::TestCase
2035
- include Rack::Test::Methods
2274
+ class MyAppTest < Test::Unit::TestCase
2275
+ include Rack::Test::Methods
2036
2276
 
2037
- def app
2038
- Sinatra::Application
2039
- end
2277
+ def app
2278
+ Sinatra::Application
2279
+ end
2040
2280
 
2041
- def test_my_default
2042
- get '/'
2043
- assert_equal 'Hallo Welt!', last_response.body
2044
- end
2281
+ def test_my_default
2282
+ get '/'
2283
+ assert_equal 'Hallo Welt!', last_response.body
2284
+ end
2045
2285
 
2046
- def test_with_params
2047
- get '/meet', :name => 'Frank'
2048
- assert_equal 'Hallo Frank!', last_response.body
2049
- end
2286
+ def test_with_params
2287
+ get '/meet', :name => 'Frank'
2288
+ assert_equal 'Hallo Frank!', last_response.body
2289
+ end
2050
2290
 
2051
- def test_with_rack_env
2052
- get '/', {}, 'HTTP_USER_AGENT' => 'Songbird'
2053
- assert_equal "Du verwendest Songbird!", last_response.body
2054
- end
2055
- end
2291
+ def test_with_rack_env
2292
+ get '/', {}, 'HTTP_USER_AGENT' => 'Songbird'
2293
+ assert_equal "Du verwendest Songbird!", last_response.body
2294
+ end
2295
+ end
2056
2296
  ```
2057
2297
 
2298
+ Hinweis: Wird Sinatra modular verwendet, muss <tt>Sinatra::Application</tt> mit
2299
+ dem Namen der Applikations-Klasse ersetzt werden.
2300
+
2058
2301
  ## Sinatra::Base - Middleware, Bibliotheken und modulare Anwendungen
2059
2302
 
2060
2303
  Das Definieren einer Top-Level-Anwendung funktioniert gut für
@@ -2068,16 +2311,16 @@ Logging, Exception-Detail-Seite, usw.). Genau hier kommt `Sinatra::Base` ins
2068
2311
  Spiel:
2069
2312
 
2070
2313
  ```ruby
2071
- require 'sinatra/base'
2314
+ require 'sinatra/base'
2072
2315
 
2073
- class MyApp < Sinatra::Base
2074
- set :sessions, true
2075
- set :foo, 'bar'
2316
+ class MyApp < Sinatra::Base
2317
+ set :sessions, true
2318
+ set :foo, 'bar'
2076
2319
 
2077
- get '/' do
2078
- 'Hallo Welt!'
2079
- end
2080
- end
2320
+ get '/' do
2321
+ 'Hallo Welt!'
2322
+ end
2323
+ end
2081
2324
  ```
2082
2325
 
2083
2326
  Die MyApp-Klasse ist eine unabhängige Rack-Komponente, die als Middleware,
@@ -2086,7 +2329,7 @@ Endpunkt oder via Rails Metal verwendet werden kann. Verwendet wird sie durch
2086
2329
  einer Bibliothek:
2087
2330
 
2088
2331
  ```ruby
2089
- MyApp.run! :host => 'localhost', :port => 9090
2332
+ MyApp.run! :host => 'localhost', :port => 9090
2090
2333
  ```
2091
2334
 
2092
2335
  Die Methoden der `Sinatra::Base`-Subklasse sind genau dieselben wie die der
@@ -2120,16 +2363,49 @@ miteinander zu vermischen.
2120
2363
  Bei einem Umstieg, sollten einige Unterschiede in den Einstellungen beachtet
2121
2364
  werden:
2122
2365
 
2123
- ```
2124
- Szenario Classic Modular
2125
- ---------------------------------------------------
2126
-
2127
- app_file sinatra ladende Datei Sinatra::Base subklassierende Datei
2128
- run $0 == app_file false
2129
- logging true false
2130
- method_override true false
2131
- inline_templates true false
2132
- ```
2366
+ <table>
2367
+ <tr>
2368
+ <th>Szenario</th>
2369
+ <th>Classic</th>
2370
+ <th>Modular</th>
2371
+ </tr>
2372
+
2373
+ <tr>
2374
+ <td>app_file</td>
2375
+ <td>Sinatra ladende Datei</td>
2376
+ <td>Sinatra::Base subklassierende Datei</td>
2377
+ </tr>
2378
+
2379
+ <tr>
2380
+ <td>run</td>
2381
+ <td>$0 == app_file</td>
2382
+ <td>false</td>
2383
+ </tr>
2384
+
2385
+ <tr>
2386
+ <td>logging</td>
2387
+ <td>true</td>
2388
+ <td>false</td>
2389
+ </tr>
2390
+
2391
+ <tr>
2392
+ <td>method_override</td>
2393
+ <td>true</td>
2394
+ <td>false</td>
2395
+ </tr>
2396
+
2397
+ <tr>
2398
+ <td>inline_templates</td>
2399
+ <td>true</td>
2400
+ <td>false</td>
2401
+ </tr>
2402
+
2403
+ <tr>
2404
+ <td>static</td>
2405
+ <td>true</td>
2406
+ <td>false</td>
2407
+ </tr>
2408
+ </table>
2133
2409
 
2134
2410
  ### Eine modulare Applikation bereitstellen
2135
2411
 
@@ -2137,36 +2413,36 @@ Es gibt zwei übliche Wege, eine modulare Anwendung zu starten. Zum einen über
2137
2413
  `run!`:
2138
2414
 
2139
2415
  ```ruby
2140
- # mein_app.rb
2141
- require 'sinatra/base'
2416
+ # mein_app.rb
2417
+ require 'sinatra/base'
2142
2418
 
2143
- class MeinApp < Sinatra::Base
2144
- # ... Anwendungscode hierhin ...
2419
+ class MeinApp < Sinatra::Base
2420
+ # ... Anwendungscode hierhin ...
2145
2421
 
2146
- # starte den Server, wenn die Ruby-Datei direkt ausgeführt wird
2147
- run! if app_file == $0
2148
- end
2422
+ # starte den Server, wenn die Ruby-Datei direkt ausgeführt wird
2423
+ run! if app_file == $0
2424
+ end
2149
2425
  ```
2150
2426
 
2151
2427
  Starte mit:
2152
2428
 
2153
2429
  ```
2154
- ruby mein_app.rb
2430
+ ruby mein_app.rb
2155
2431
  ```
2156
2432
 
2157
2433
  Oder über eine `config.ru`-Datei, die es erlaubt, einen beliebigen
2158
2434
  Rack-Handler zu verwenden:
2159
2435
 
2160
2436
  ```ruby
2161
- # config.ru
2162
- require './mein_app'
2163
- run MeineApp
2437
+ # config.ru (mit rackup starten)
2438
+ require './mein_app'
2439
+ run MeineApp
2164
2440
  ```
2165
2441
 
2166
2442
  Starte:
2167
2443
 
2168
2444
  ```
2169
- rackup -p 4567
2445
+ rackup -p 4567
2170
2446
  ```
2171
2447
 
2172
2448
  ### Eine klassische Anwendung mit einer config.ru verwenden
@@ -2174,19 +2450,19 @@ Starte:
2174
2450
  Schreibe eine Anwendungsdatei:
2175
2451
 
2176
2452
  ```ruby
2177
- # app.rb
2178
- require 'sinatra'
2453
+ # app.rb
2454
+ require 'sinatra'
2179
2455
 
2180
- get '/' do
2181
- 'Hallo Welt!'
2182
- end
2456
+ get '/' do
2457
+ 'Hallo Welt!'
2458
+ end
2183
2459
  ```
2184
2460
 
2185
2461
  sowie eine dazugehörige `config.ru`-Datei:
2186
2462
 
2187
2463
  ```ruby
2188
- require './app'
2189
- run Sinatra::Application
2464
+ require './app'
2465
+ run Sinatra::Application
2190
2466
  ```
2191
2467
 
2192
2468
  ### Wann sollte eine config.ru-Datei verwendet werden?
@@ -2212,34 +2488,34 @@ nicht um eine andere Sinatra-Anwendung handeln, es kann jede andere
2212
2488
  Rack-Anwendung sein (Rails/Ramaze/Camping/...):
2213
2489
 
2214
2490
  ```ruby
2215
- require 'sinatra/base'
2491
+ require 'sinatra/base'
2216
2492
 
2217
- class LoginScreen < Sinatra::Base
2218
- enable :sessions
2493
+ class LoginScreen < Sinatra::Base
2494
+ enable :sessions
2219
2495
 
2220
- get('/login') { haml :login }
2496
+ get('/login') { haml :login }
2221
2497
 
2222
- post('/login') do
2223
- if params[:name] == 'admin' && params[:password] == 'admin'
2224
- session['user_name'] = params[:name]
2225
- else
2226
- redirect '/login'
2227
- end
2228
- end
2498
+ post('/login') do
2499
+ if params[:name] == 'admin' && params[:password] == 'admin'
2500
+ session['user_name'] = params[:name]
2501
+ else
2502
+ redirect '/login'
2229
2503
  end
2504
+ end
2505
+ end
2230
2506
 
2231
- class MyApp < Sinatra::Base
2232
- # Middleware wird vor Filtern ausgeführt
2233
- use LoginScreen
2507
+ class MyApp < Sinatra::Base
2508
+ # Middleware wird vor Filtern ausgeführt
2509
+ use LoginScreen
2234
2510
 
2235
- before do
2236
- unless session['user_name']
2237
- halt "Zugriff verweigert, bitte <a href='/login'>einloggen</a>."
2238
- end
2239
- end
2240
-
2241
- get('/') { "Hallo #{session['user_name']}." }
2511
+ before do
2512
+ unless session['user_name']
2513
+ halt "Zugriff verweigert, bitte <a href='/login'>einloggen</a>."
2242
2514
  end
2515
+ end
2516
+
2517
+ get('/') { "Hallo #{session['user_name']}." }
2518
+ end
2243
2519
  ```
2244
2520
 
2245
2521
  ### Dynamische Applikationserstellung
@@ -2249,29 +2525,29 @@ ohne dass sie einer Konstanten zugeordnet werden. Dies lässt sich mit
2249
2525
  `Sinatra.new` erreichen:
2250
2526
 
2251
2527
  ```ruby
2252
- require 'sinatra/base'
2253
- my_app = Sinatra.new { get('/') { "hallo" } }
2254
- my_app.run!
2528
+ require 'sinatra/base'
2529
+ my_app = Sinatra.new { get('/') { "hallo" } }
2530
+ my_app.run!
2255
2531
  ```
2256
2532
 
2257
2533
  Die Applikation kann mit Hilfe eines optionalen Parameters erstellt werden:
2258
2534
 
2259
2535
  ```ruby
2260
- # config.ru
2261
- require 'sinatra/base'
2536
+ # config.ru
2537
+ require 'sinatra/base'
2262
2538
 
2263
- controller = Sinatra.new do
2264
- enable :logging
2265
- helpers MyHelpers
2266
- end
2539
+ controller = Sinatra.new do
2540
+ enable :logging
2541
+ helpers MyHelpers
2542
+ end
2267
2543
 
2268
- map('/a') do
2269
- run Sinatra.new(controller) { get('/') { 'a' } }
2270
- end
2544
+ map('/a') do
2545
+ run Sinatra.new(controller) { get('/') { 'a' } }
2546
+ end
2271
2547
 
2272
- map('/b') do
2273
- run Sinatra.new(controller) { get('/') { 'b' } }
2274
- end
2548
+ map('/b') do
2549
+ run Sinatra.new(controller) { get('/') { 'b' } }
2550
+ end
2275
2551
  ```
2276
2552
 
2277
2553
  Das ist besonders dann interessant, wenn Sinatra-Erweiterungen getestet werden
@@ -2280,13 +2556,13 @@ oder Sinatra in einer Bibliothek Verwendung findet.
2280
2556
  Ebenso lassen sich damit hervorragend Sinatra-Middlewares erstellen:
2281
2557
 
2282
2558
  ```ruby
2283
- require 'sinatra/base'
2559
+ require 'sinatra/base'
2284
2560
 
2285
- use Sinatra do
2286
- get('/') { ... }
2287
- end
2561
+ use Sinatra do
2562
+ get('/') { ... }
2563
+ end
2288
2564
 
2289
- run RailsProject::Application
2565
+ run RailsProject::Application
2290
2566
  ```
2291
2567
 
2292
2568
  ## Geltungsbereich und Bindung
@@ -2307,15 +2583,15 @@ wird.
2307
2583
  Optionen, die via `set` gesetzt werden, sind Methoden auf Klassenebene:
2308
2584
 
2309
2585
  ```ruby
2310
- class MyApp < Sinatra::Base
2311
- # Hey, ich bin im Anwendungsscope!
2312
- set :foo, 42
2313
- foo # => 42
2586
+ class MyApp < Sinatra::Base
2587
+ # Hey, ich bin im Anwendungsscope!
2588
+ set :foo, 42
2589
+ foo # => 42
2314
2590
 
2315
- get '/foo' do
2316
- # Hey, ich bin nicht mehr im Anwendungs-Scope!
2317
- end
2318
- end
2591
+ get '/foo' do
2592
+ # Hey, ich bin nicht mehr im Anwendungs-Scope!
2593
+ end
2594
+ end
2319
2595
  ```
2320
2596
 
2321
2597
  Im Anwendungs-Scope befindet man sich:
@@ -2343,20 +2619,20 @@ kann auf `request` oder `session` zugegriffen und Methoden wie `erb` oder
2343
2619
  Anwendungs-Scope zugegriffen werden:
2344
2620
 
2345
2621
  ```ruby
2346
- class MyApp < Sinatra::Base
2347
- # Hey, ich bin im Anwendungs-Scope!
2348
- get '/neue_route/:name' do
2349
- # Anfrage-Scope für '/neue_route/:name'
2350
- @value = 42
2622
+ class MyApp < Sinatra::Base
2623
+ # Hey, ich bin im Anwendungs-Scope!
2624
+ get '/neue_route/:name' do
2625
+ # Anfrage-Scope für '/neue_route/:name'
2626
+ @value = 42
2351
2627
 
2352
- settings.get "/#{params[:name]}" do
2353
- # Anfrage-Scope für "/#{params[:name]}"
2354
- @value # => nil (nicht dieselbe Anfrage)
2355
- end
2356
-
2357
- "Route definiert!"
2358
- end
2628
+ settings.get "/#{params[:name]}" do
2629
+ # Anfrage-Scope für "/#{params[:name]}"
2630
+ @value # => nil (nicht dieselbe Anfrage)
2359
2631
  end
2632
+
2633
+ "Route definiert!"
2634
+ end
2635
+ end
2360
2636
  ```
2361
2637
 
2362
2638
  Im Anfrage-Scope befindet man sich:
@@ -2393,18 +2669,18 @@ eingebunden](http://github.com/sinatra/sinatra/blob/master/lib/sinatra/main.rb
2393
2669
  Sinatra-Anwendungen können direkt von der Kommandozeile aus gestartet werden:
2394
2670
 
2395
2671
  ```
2396
- ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-h HOST] [-s HANDLER]
2672
+ ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-h HOST] [-s HANDLER]
2397
2673
  ```
2398
2674
 
2399
2675
  Die Optionen sind:
2400
2676
 
2401
2677
  ```
2402
- -h # Hilfe
2403
- -p # Port setzen (Standard ist 4567)
2404
- -h # Host setzen (Standard ist 0.0.0.0)
2405
- -e # Umgebung setzen (Standard ist development)
2406
- -s # Rack-Server/Handler setzen (Standard ist thin)
2407
- -x # Mutex-Lock einschalten (Standard ist off)
2678
+ -h # Hilfe
2679
+ -p # Port setzen (Standard ist 4567)
2680
+ -h # Host setzen (Standard ist 0.0.0.0)
2681
+ -e # Umgebung setzen (Standard ist development)
2682
+ -s # Rack-Server/Handler setzen (Standard ist thin)
2683
+ -x # Mutex-Lock einschalten (Standard ist off)
2408
2684
  ```
2409
2685
 
2410
2686
  ## Systemanforderungen
@@ -2445,7 +2721,7 @@ Die folgenden Versionen werden offiziell unterstützt:
2445
2721
  Einsatz kommt – die Thin und Mongrel Web-Server werden bisher nicht
2446
2722
  unterstütz. JRubys Unterstützung für C-Erweiterungen sind zur Zeit ebenfalls
2447
2723
  experimenteller Natur, betrifft im Moment aber nur die RDiscount, Redcarpet,
2448
- RedCloth und Yajl Templates.</dd>
2724
+ RedCloth und [[Yajl]] Templates.</dd>
2449
2725
  </dl>
2450
2726
 
2451
2727
  Weiterhin werden wir die kommende Ruby-Versionen im Auge behalten.
@@ -2481,7 +2757,7 @@ Er sollte recht stabil sein. Ebenso gibt es von Zeit zu Zeit prerelease Gems,
2481
2757
  die so installiert werden:
2482
2758
 
2483
2759
  ```
2484
- gem install sinatra --pre
2760
+ gem install sinatra --pre
2485
2761
  ```
2486
2762
 
2487
2763
  ### Mit Bundler
@@ -2493,19 +2769,19 @@ nachfolgenden Weg.
2493
2769
  Soweit Bundler noch nicht installiert ist:
2494
2770
 
2495
2771
  ```
2496
- gem install bundler
2772
+ gem install bundler
2497
2773
  ```
2498
2774
 
2499
2775
  Anschließend wird eine `Gemfile`-Datei im Projektverzeichnis mit folgendem
2500
2776
  Inhalt erstellt:
2501
2777
 
2502
2778
  ```ruby
2503
- source :rubygems
2504
- gem 'sinatra', :git => "git://github.com/sinatra/sinatra.git"
2779
+ source :rubygems
2780
+ gem 'sinatra', :git => "git://github.com/sinatra/sinatra.git"
2505
2781
 
2506
- # evtl. andere Abhängigkeiten
2507
- gem 'haml' # z.B. wenn du Haml verwendest...
2508
- gem 'activerecord', '~> 3.0' # ...oder ActiveRecord 3.x
2782
+ # evtl. andere Abhängigkeiten
2783
+ gem 'haml' # z.B. wenn du Haml verwendest...
2784
+ gem 'activerecord', '~> 3.0' # ...oder ActiveRecord 3.x
2509
2785
  ```
2510
2786
 
2511
2787
  Beachte: Hier sollten alle Abhängigkeiten eingetragen werden. Sinatras eigene,
@@ -2515,7 +2791,7 @@ Gemfile von Sinatra hinzugefügt.
2515
2791
  Jetzt kannst du deine Applikation starten:
2516
2792
 
2517
2793
  ```
2518
- bundle exec ruby myapp.rb
2794
+ bundle exec ruby myapp.rb
2519
2795
  ```
2520
2796
 
2521
2797
  ### Eigenes Repository
@@ -2524,29 +2800,29 @@ angelegt werden. Gestartet wird in der Anwendung mit dem `sinatra/lib`- Ordner
2524
2800
  im `LOAD_PATH`:
2525
2801
 
2526
2802
  ```
2527
- cd myapp
2528
- git clone git://github.com/sinatra/sinatra.git
2529
- ruby -Isinatra/lib myapp.rb
2803
+ cd myapp
2804
+ git clone git://github.com/sinatra/sinatra.git
2805
+ ruby -Isinatra/lib myapp.rb
2530
2806
  ```
2531
2807
 
2532
2808
  Alternativ kann der `sinatra/lib`-Ordner zum `LOAD_PATH` in der Anwendung
2533
2809
  hinzugefügt werden:
2534
2810
 
2535
2811
  ```ruby
2536
- $LOAD_PATH.unshift File.dirname(__FILE__) + '/sinatra/lib'
2537
- require 'rubygems'
2538
- require 'sinatra'
2812
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/sinatra/lib'
2813
+ require 'rubygems'
2814
+ require 'sinatra'
2539
2815
 
2540
- get '/ueber' do
2541
- "Ich laufe auf Version " + Sinatra::VERSION
2542
- end
2816
+ get '/ueber' do
2817
+ "Ich laufe auf Version " + Sinatra::VERSION
2818
+ end
2543
2819
  ```
2544
2820
 
2545
2821
  Um Sinatra-Code von Zeit zu Zeit zu aktualisieren:
2546
2822
 
2547
2823
  ```
2548
- cd myproject/sinatra
2549
- git pull
2824
+ cd myproject/sinatra
2825
+ git pull
2550
2826
  ```
2551
2827
 
2552
2828
  ### Gem erstellen
@@ -2554,17 +2830,17 @@ Um Sinatra-Code von Zeit zu Zeit zu aktualisieren:
2554
2830
  Aus der eigenen lokalen Kopie kann nun auch ein globales Gem gebaut werden:
2555
2831
 
2556
2832
  ```
2557
- git clone git://github.com/sinatra/sinatra.git
2558
- cd sinatra
2559
- rake sinatra.gemspec
2560
- rake install
2833
+ git clone git://github.com/sinatra/sinatra.git
2834
+ cd sinatra
2835
+ rake sinatra.gemspec
2836
+ rake install
2561
2837
  ```
2562
2838
 
2563
2839
  Falls Gems als Root installiert werden sollen, sollte die letzte Zeile
2564
2840
  folgendermaßen lauten:
2565
2841
 
2566
2842
  ```
2567
- sudo rake install
2843
+ sudo rake install
2568
2844
  ```
2569
2845
 
2570
2846
  ## Versions-Verfahren