sinatra 1.1.4 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/AUTHORS +5 -1
- data/CHANGES +47 -2
- data/Gemfile +53 -0
- data/README.de.rdoc +732 -85
- data/README.es.rdoc +725 -75
- data/README.fr.rdoc +29 -16
- data/README.hu.rdoc +4 -4
- data/README.jp.rdoc +29 -16
- data/README.pt-br.rdoc +6 -6
- data/README.rdoc +664 -91
- data/README.ru.rdoc +257 -75
- data/README.zh.rdoc +889 -111
- data/Rakefile +7 -32
- data/lib/sinatra/base.rb +133 -66
- data/lib/sinatra/showexceptions.rb +25 -0
- data/sinatra.gemspec +10 -18
- data/test/builder_test.rb +6 -0
- data/test/coffee_test.rb +1 -1
- data/test/encoding_test.rb +4 -3
- data/test/erubis_test.rb +6 -0
- data/test/filter_test.rb +105 -1
- data/test/haml_test.rb +2 -1
- data/test/helper.rb +2 -0
- data/test/helpers_test.rb +105 -13
- data/test/less_test.rb +6 -0
- data/test/liquid_test.rb +2 -1
- data/test/markaby_test.rb +23 -1
- data/test/markdown_test.rb +3 -2
- data/test/nokogiri_test.rb +2 -1
- data/test/radius_test.rb +3 -2
- data/test/rdoc_test.rb +3 -2
- data/test/routing_test.rb +38 -1
- data/test/sass_test.rb +1 -1
- data/test/scss_test.rb +1 -1
- data/test/slim_test.rb +98 -0
- data/test/templates_test.rb +53 -0
- data/test/textile_test.rb +2 -1
- data/test/views/a/in_a.str +1 -0
- data/test/views/{ascii.haml → ascii.erb} +1 -1
- data/test/views/b/in_b.str +1 -0
- data/test/views/hello.slim +1 -0
- data/test/views/layout2.slim +3 -0
- data/test/views/{utf8.haml → utf8.erb} +1 -1
- metadata +42 -161
data/README.de.rdoc
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
= Sinatra
|
|
2
|
-
<i>Wichtig: Dieses Dokument ist eine Übersetzung aus dem Englischen und unter
|
|
2
|
+
<i>Wichtig: Dieses Dokument ist eine Übersetzung aus dem Englischen und unter
|
|
3
|
+
Umständen nicht auf dem aktuellsten Stand.</i>
|
|
3
4
|
|
|
4
5
|
Sinatra ist eine DSL, die das schnelle Erstellen von Webanwendungen in Ruby
|
|
5
6
|
mit minimalen Aufwand ermöglicht:
|
|
@@ -10,7 +11,7 @@ mit minimalen Aufwand ermöglicht:
|
|
|
10
11
|
'Hallo Welt!'
|
|
11
12
|
end
|
|
12
13
|
|
|
13
|
-
Einfach via rubygems installieren und starten:
|
|
14
|
+
Einfach via +rubygems+ installieren und starten:
|
|
14
15
|
|
|
15
16
|
gem install sinatra
|
|
16
17
|
ruby -rubygems myapp.rb
|
|
@@ -19,8 +20,8 @@ Die Seite kann nun unter http://localhost:4567 betrachtet werden.
|
|
|
19
20
|
|
|
20
21
|
== Routen
|
|
21
22
|
|
|
22
|
-
In Sinatra wird eine Route durch eine HTTP-Methode und ein URL-Muster
|
|
23
|
-
Ruby-Block zugeordnet.
|
|
23
|
+
In Sinatra wird eine Route durch eine HTTP-Methode und ein URL-Muster
|
|
24
|
+
definiert. Jeder dieser Routen wird ein Ruby-Block zugeordnet.
|
|
24
25
|
|
|
25
26
|
get '/' do
|
|
26
27
|
.. zeige etwas ..
|
|
@@ -37,6 +38,10 @@ Ruby-Block zugeordnet.
|
|
|
37
38
|
delete '/' do
|
|
38
39
|
.. entferne etwas ..
|
|
39
40
|
end
|
|
41
|
+
|
|
42
|
+
options '/' do
|
|
43
|
+
.. lege etwas fest ..
|
|
44
|
+
end
|
|
40
45
|
|
|
41
46
|
Die Routen werden in der Reihenfolge durchlaufen, in der sie definiert wurden.
|
|
42
47
|
Das erste Routemuster, das mit dem Request übereinstimmt, wird ausgeführt.
|
|
@@ -126,16 +131,19 @@ Man kann auch relativ einfach eigene Bedingungen hinzufügen:
|
|
|
126
131
|
Durch den Rückgabewert eines Routenblocks wird mindestens der Response Body
|
|
127
132
|
festgelegt, der an den HTTP Client, bzw die nächste Rack Middleware
|
|
128
133
|
weitergegeben wird. Im Normalfall handelt es sich hierbei, wie
|
|
129
|
-
in den vorangehenden Beispielen zu sehen war, um einen String. Es werden
|
|
130
|
-
Werte akzeptiert.
|
|
134
|
+
in den vorangehenden Beispielen zu sehen war, um einen String. Es werden
|
|
135
|
+
allerdings auch andere Werte akzeptiert.
|
|
131
136
|
|
|
132
137
|
Man kann jedes Objekt zurückgeben, bei dem es sich entweder um einenen validen
|
|
133
138
|
Rack-Rückgabewert, einen validen Rack-Body oder einen HTTP Status Code
|
|
134
139
|
handelt:
|
|
135
140
|
|
|
136
|
-
* Ein Array mit drei Elementen: <tt>[Status (Fixnum), Headers (Hash), Response
|
|
137
|
-
|
|
138
|
-
* Ein
|
|
141
|
+
* Ein Array mit drei Elementen: <tt>[Status (Fixnum), Headers (Hash), Response
|
|
142
|
+
Body (hört auf #each)]</tt>
|
|
143
|
+
* Ein Array mit zwei Elementen: <tt>[Status (Fixnum), Response Body (hört auf
|
|
144
|
+
#each)]</tt>
|
|
145
|
+
* Ein Objekt, das auf <tt>#each</tt> hört und den an diese Methode übergebenen
|
|
146
|
+
Block nur mit Strings als Übergabewerte aufruft.
|
|
139
147
|
* Ein Fixnum, das den Status Code festlegt.
|
|
140
148
|
|
|
141
149
|
Damit lässt sich relativ einfach Streaming implementieren:
|
|
@@ -175,9 +183,9 @@ Renderingmethoden rendern jeden String direkt.
|
|
|
175
183
|
|
|
176
184
|
=== Haml-Templates
|
|
177
185
|
|
|
178
|
-
Das haml gem wird benötigt, um Haml-Templates rendern zu können:
|
|
186
|
+
Das +haml+ gem wird benötigt, um Haml-Templates rendern zu können:
|
|
179
187
|
|
|
180
|
-
|
|
188
|
+
# haml muss eingebunden werden
|
|
181
189
|
require 'haml'
|
|
182
190
|
|
|
183
191
|
get '/' do
|
|
@@ -199,7 +207,7 @@ und individuell überschrieben werden.
|
|
|
199
207
|
|
|
200
208
|
=== Erb-Templates
|
|
201
209
|
|
|
202
|
-
|
|
210
|
+
# erb muss eingebunden werden
|
|
203
211
|
require 'erb'
|
|
204
212
|
|
|
205
213
|
get '/' do
|
|
@@ -210,9 +218,9 @@ Dieser Code rendert <tt>./views/index.erb</tt>.
|
|
|
210
218
|
|
|
211
219
|
=== Erubis
|
|
212
220
|
|
|
213
|
-
Das erubis gem wird benötigt, um Erubis-Templates rendern zu können:
|
|
221
|
+
Das +erubis+ gem wird benötigt, um Erubis-Templates rendern zu können:
|
|
214
222
|
|
|
215
|
-
|
|
223
|
+
# erbubis muss eingebunden werden
|
|
216
224
|
require 'erubis'
|
|
217
225
|
|
|
218
226
|
get '/' do
|
|
@@ -221,11 +229,22 @@ Das erubis gem wird benötigt, um Erubis-Templates rendern zu können:
|
|
|
221
229
|
|
|
222
230
|
Dieser Code rendert <tt>./views/index.erubis</tt>.
|
|
223
231
|
|
|
232
|
+
Es ist auch möglich Erb mit Erubis zu ersetzen:
|
|
233
|
+
|
|
234
|
+
require 'erubis'
|
|
235
|
+
Tilt.register :erb, Tilt[:erubis]
|
|
236
|
+
|
|
237
|
+
get '/' do
|
|
238
|
+
erb :index
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
Dieser Code rendert ebenfalls <tt>./views/index.erb</tt>.
|
|
242
|
+
|
|
224
243
|
=== Builder-Templates
|
|
225
244
|
|
|
226
|
-
Das
|
|
245
|
+
Das +builder+ gem wird benötigt, um Builder-Templates rendern zu können:
|
|
227
246
|
|
|
228
|
-
|
|
247
|
+
# builder muss eingebunden werden
|
|
229
248
|
require 'builder'
|
|
230
249
|
|
|
231
250
|
get '/' do
|
|
@@ -236,9 +255,9 @@ Dieser Code rendert <tt>./views/index.builder</tt>.
|
|
|
236
255
|
|
|
237
256
|
=== Nokogiri-Templates
|
|
238
257
|
|
|
239
|
-
Das nokogiri gem wird benötigt, um Nokogiri-Templates rendern zu können:
|
|
258
|
+
Das +nokogiri+ gem wird benötigt, um Nokogiri-Templates rendern zu können:
|
|
240
259
|
|
|
241
|
-
|
|
260
|
+
# nokogiri muss eingebunden werden
|
|
242
261
|
require 'nokogiri'
|
|
243
262
|
|
|
244
263
|
get '/' do
|
|
@@ -249,9 +268,9 @@ Dieser Code rendert <tt>./views/index.nokogiri</tt>.
|
|
|
249
268
|
|
|
250
269
|
=== Sass-Templates
|
|
251
270
|
|
|
252
|
-
Das haml gem wird benötigt, um
|
|
271
|
+
Das +haml+ oder +sass+ gem wird benötigt, um Sass-Templates rendern zu können:
|
|
253
272
|
|
|
254
|
-
|
|
273
|
+
# sass muss eingebunden werden
|
|
255
274
|
require 'sass'
|
|
256
275
|
|
|
257
276
|
get '/stylesheet.css' do
|
|
@@ -273,9 +292,9 @@ und individuell überschrieben werden.
|
|
|
273
292
|
|
|
274
293
|
=== Scss-Templates
|
|
275
294
|
|
|
276
|
-
Das haml gem wird benötigt, um SCSS-Templates rendern zu können:
|
|
295
|
+
Das +haml+ oder +sass+ gem wird benötigt, um SCSS-Templates rendern zu können:
|
|
277
296
|
|
|
278
|
-
|
|
297
|
+
# sass muss eingebunden werden
|
|
279
298
|
require 'sass'
|
|
280
299
|
|
|
281
300
|
get '/stylesheet.css' do
|
|
@@ -297,9 +316,9 @@ und individuell überschrieben werden.
|
|
|
297
316
|
|
|
298
317
|
=== Less-Templates
|
|
299
318
|
|
|
300
|
-
Das less gem wird benötigt, um Less-Templates rendern zu können:
|
|
319
|
+
Das +less+ gem wird benötigt, um Less-Templates rendern zu können:
|
|
301
320
|
|
|
302
|
-
|
|
321
|
+
# less muss eingebunden werden
|
|
303
322
|
require 'less'
|
|
304
323
|
|
|
305
324
|
get '/stylesheet.css' do
|
|
@@ -310,9 +329,9 @@ Dieser Code rendert <tt>./views/stylesheet.less</tt>.
|
|
|
310
329
|
|
|
311
330
|
=== Liquid-Templates
|
|
312
331
|
|
|
313
|
-
Das liquid gem wird benötigt, um Liquid-Templates rendern zu können:
|
|
332
|
+
Das +liquid+ gem wird benötigt, um Liquid-Templates rendern zu können:
|
|
314
333
|
|
|
315
|
-
|
|
334
|
+
# liquid muss eingebunden werden
|
|
316
335
|
require 'liquid'
|
|
317
336
|
|
|
318
337
|
get '/' do
|
|
@@ -328,9 +347,9 @@ aufrufen kann, will man nahezu in allen Fällen +locals+ übergeben:
|
|
|
328
347
|
|
|
329
348
|
=== Markdown-Templates
|
|
330
349
|
|
|
331
|
-
Das rdiscount gem wird benötigt, um Markdown-Templates rendern zu können:
|
|
350
|
+
Das +rdiscount+ gem wird benötigt, um Markdown-Templates rendern zu können:
|
|
332
351
|
|
|
333
|
-
|
|
352
|
+
# rdiscount muss eingebunden werden
|
|
334
353
|
require "rdiscount"
|
|
335
354
|
|
|
336
355
|
get '/' do
|
|
@@ -352,11 +371,47 @@ aufzurufen:
|
|
|
352
371
|
%h1 Hallo von Haml!
|
|
353
372
|
%p= markdown(:greetings)
|
|
354
373
|
|
|
374
|
+
Da man Ruby aus Markdown heraus nicht aufrufen kann, ist es nicht
|
|
375
|
+
möglich Layouts zu verwenden, die in Markdown geschrieben sind. Es ist aber
|
|
376
|
+
möglich einen anderen Renderer für das Template zu verwenden als für das
|
|
377
|
+
Layout, indem man die <tt>:layout_engine</tt> option angibt:
|
|
378
|
+
|
|
379
|
+
get '/' do
|
|
380
|
+
markdown :index, :layout_engine => :erb
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
Das wird <tt>./views/index.md</tt> mit <tt>./views/layout.erb</tt> als Layout
|
|
384
|
+
rendern.
|
|
385
|
+
|
|
386
|
+
Denk dran, dass man solche Einstellungen auch global setzen kann:
|
|
387
|
+
|
|
388
|
+
set :markdown, :layout_engine => :haml, :layout => :post
|
|
389
|
+
|
|
390
|
+
get '/' do
|
|
391
|
+
markdown :index
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
Das wird <tt>./views/index.md</tt> (und jedes andere Markdown Template) mit
|
|
395
|
+
<tt>./views/post.haml</tt> als Layout rendern.
|
|
396
|
+
|
|
397
|
+
Ebenso ist es möglich Markdown mit BlueCloth anstelle von RDiscount zu parsen:
|
|
398
|
+
|
|
399
|
+
require 'bluecloth'
|
|
400
|
+
|
|
401
|
+
Tilt.register 'markdown', BlueClothTemplate
|
|
402
|
+
Tilt.register 'mkd', BlueClothTemplate
|
|
403
|
+
Tilt.register 'md', BlueClothTemplate
|
|
404
|
+
|
|
405
|
+
get '/' do
|
|
406
|
+
markdown :index
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
Das sollte <tt>./views/index.md</tt> mit BlueCloth rendern.
|
|
355
410
|
=== Textile-Templates
|
|
356
411
|
|
|
357
|
-
Das
|
|
412
|
+
Das +redcloth+ gem wird benötigt, um Textile-Templates rendern zu können:
|
|
358
413
|
|
|
359
|
-
|
|
414
|
+
# redcloth muss eingebunden werden
|
|
360
415
|
require "redcloth"
|
|
361
416
|
|
|
362
417
|
get '/' do
|
|
@@ -377,12 +432,36 @@ aufzurufen:
|
|
|
377
432
|
%h1 Hallo von Haml!
|
|
378
433
|
%p= textile(:greetings)
|
|
379
434
|
|
|
435
|
+
Da man Ruby aus Textile heraus nicht aufrufen kann, ist es nicht
|
|
436
|
+
möglich Layouts zu verwenden, die in Textile geschrieben sind. Es ist aber
|
|
437
|
+
möglich einen anderen Renderer für das Template zu verwenden als für das
|
|
438
|
+
Layout, indem man die <tt>:layout_engine</tt> option angibt:
|
|
439
|
+
|
|
440
|
+
get '/' do
|
|
441
|
+
textile :index, :layout_engine => :erb
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
Das wird <tt>./views/index.textile</tt> mit
|
|
445
|
+
<tt>./views/layout.erb</tt> als Layout
|
|
446
|
+
rendern.
|
|
447
|
+
|
|
448
|
+
Denk dran, dass man solche Einstellungen auch global setzen kann:
|
|
449
|
+
|
|
450
|
+
set :textile, :layout_engine => :haml, :layout => :post
|
|
451
|
+
|
|
452
|
+
get '/' do
|
|
453
|
+
textile :index
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
Das wird <tt>./views/index.textile</tt> (und jedes andere Markdown Template)
|
|
457
|
+
mit <tt>./views/post.haml</tt> als Layout rendern.
|
|
458
|
+
|
|
380
459
|
=== RDoc-Templates
|
|
381
460
|
|
|
382
|
-
Das rdoc gem wird benötigt, um RDoc-Templates rendern zu können:
|
|
461
|
+
Das +rdoc+ gem wird benötigt, um RDoc-Templates rendern zu können:
|
|
383
462
|
|
|
384
|
-
|
|
385
|
-
require "rdoc"
|
|
463
|
+
# RDoc muss eingebunden werden
|
|
464
|
+
require "rdoc/markup/to_html"
|
|
386
465
|
|
|
387
466
|
get '/' do
|
|
388
467
|
rdoc :index
|
|
@@ -402,11 +481,36 @@ aufzurufen:
|
|
|
402
481
|
%h1 Hallo von Haml!
|
|
403
482
|
%p= rdoc(:greetings)
|
|
404
483
|
|
|
484
|
+
Da man Ruby aus RDoc heraus nicht aufrufen kann, ist es nicht
|
|
485
|
+
möglich Layouts zu verwenden, die in RDoc geschrieben sind. Es ist aber
|
|
486
|
+
möglich einen anderen Renderer für das Template zu verwenden als für das
|
|
487
|
+
Layout, indem man die <tt>:layout_engine</tt> option angibt:
|
|
488
|
+
|
|
489
|
+
get '/' do
|
|
490
|
+
rdoc :index, :layout_engine => :erb
|
|
491
|
+
end
|
|
492
|
+
|
|
493
|
+
Das wird <tt>./views/index.rdoc</tt> mit
|
|
494
|
+
<tt>./views/layout.erb</tt> als Layout
|
|
495
|
+
rendern.
|
|
496
|
+
|
|
497
|
+
Denk dran, dass man solche Einstellungen auch global setzen kann:
|
|
498
|
+
|
|
499
|
+
set :rdoc, :layout_engine => :haml, :layout => :post
|
|
500
|
+
|
|
501
|
+
get '/' do
|
|
502
|
+
rdoc :index
|
|
503
|
+
end
|
|
504
|
+
|
|
505
|
+
Das wird <tt>./views/index.rdoc</tt> (und jedes andere Markdown Template) mit
|
|
506
|
+
<tt>./views/post.haml</tt> als Layout rendern.
|
|
507
|
+
|
|
508
|
+
|
|
405
509
|
=== Radius-Templates
|
|
406
510
|
|
|
407
|
-
Das radius gem wird benötigt, um Radius-Templates rendern zu können:
|
|
511
|
+
Das +radius+ gem wird benötigt, um Radius-Templates rendern zu können:
|
|
408
512
|
|
|
409
|
-
|
|
513
|
+
# radius muss eingebunden werden
|
|
410
514
|
require 'radius'
|
|
411
515
|
|
|
412
516
|
get '/' do
|
|
@@ -422,9 +526,9 @@ aufrufen kann, will man nahezu in allen Fällen +locals+ übergeben:
|
|
|
422
526
|
|
|
423
527
|
=== Markaby-Templates
|
|
424
528
|
|
|
425
|
-
Das markaby gem wird benötigt, um Markaby-Templates rendern zu können:
|
|
529
|
+
Das +markaby+ gem wird benötigt, um Markaby-Templates rendern zu können:
|
|
426
530
|
|
|
427
|
-
|
|
531
|
+
# markaby muss eingebunden werden
|
|
428
532
|
require 'markaby'
|
|
429
533
|
|
|
430
534
|
get '/' do
|
|
@@ -433,11 +537,34 @@ Das markaby gem wird benötigt, um Markaby-Templates rendern zu können:
|
|
|
433
537
|
|
|
434
538
|
Dieser Code rendert <tt>./views/index.mab</tt>.
|
|
435
539
|
|
|
540
|
+
=== Slim-Templates
|
|
541
|
+
|
|
542
|
+
Das +slim+ gem wird benötigt, um Slim-Templates rendern zu können:
|
|
543
|
+
|
|
544
|
+
# slim muss eingebunden werden
|
|
545
|
+
require 'slim'
|
|
546
|
+
|
|
547
|
+
get '/' do
|
|
548
|
+
slim :index
|
|
549
|
+
end
|
|
550
|
+
|
|
551
|
+
Dieser Code rendert <tt>./views/index.slim</tt>.
|
|
552
|
+
|
|
436
553
|
=== CoffeeScript-Templates
|
|
437
554
|
|
|
438
|
-
Das coffee
|
|
555
|
+
Das +coffee+-script gem und mindestens eine der folgenden Optionen werden
|
|
556
|
+
benötigt, um JavaScript auf dem Server ausführen zu können:
|
|
557
|
+
|
|
558
|
+
* +node+ (von Node.js) befindet sich im Pfad
|
|
559
|
+
* du bist unter OS X
|
|
560
|
+
* +therubyracer+ gem/library
|
|
439
561
|
|
|
440
|
-
|
|
562
|
+
Siehe auch http://github.com/josh/ruby-coffee-script für eine vollständige
|
|
563
|
+
Liste aller Optionen.
|
|
564
|
+
|
|
565
|
+
Nun kannst Du CoffeeScript Templates in Deiner App rendern:
|
|
566
|
+
|
|
567
|
+
# coffee-script muss eingebunden werden
|
|
441
568
|
require 'coffee-script'
|
|
442
569
|
|
|
443
570
|
get '/application.js' do
|
|
@@ -522,21 +649,32 @@ verwendet. Durch <tt>:layout => false</tt> kann das Ausführen verhindert werden
|
|
|
522
649
|
haml :index, :layout => !request.xhr?
|
|
523
650
|
end
|
|
524
651
|
|
|
525
|
-
|
|
652
|
+
=== Datieendungen zuordnen
|
|
526
653
|
|
|
527
|
-
|
|
528
|
-
|
|
654
|
+
Um eine Dateiendung einer Template Engine zuzuordnen, benutzt man am besten
|
|
655
|
+
<tt>Tilt.register</tt>. Wenn man zum Beispiel die Dateiendung +tt+ für Textile
|
|
656
|
+
Templates nutzen möchte, so lässt sich das wie folgt bewerkstelligen:
|
|
657
|
+
|
|
658
|
+
Tilt.register :tt, Tilt[:textile]
|
|
659
|
+
|
|
660
|
+
=== Eine eigene Template Engine hinzufügen
|
|
661
|
+
|
|
662
|
+
Zu allererst muss man die Engine bei Tilt registrieren und danach eine
|
|
663
|
+
Rendering-Methode erstellen:
|
|
664
|
+
|
|
665
|
+
Tilt.register :mtt, MeineTolleTemplateEngine
|
|
529
666
|
|
|
530
667
|
helpers do
|
|
531
|
-
def
|
|
532
|
-
"#{name}bar"
|
|
533
|
-
end
|
|
668
|
+
def mtt(*args) render(:mtt, *args) end
|
|
534
669
|
end
|
|
535
670
|
|
|
536
|
-
get '
|
|
537
|
-
|
|
671
|
+
get '/' do
|
|
672
|
+
mtt :index
|
|
538
673
|
end
|
|
539
674
|
|
|
675
|
+
Dieser Code rendert <tt>./views/application.mtt</tt>. Siehe
|
|
676
|
+
https://github.com/rtomayko/tilt um mehr über Tilt zu lernen.
|
|
677
|
+
|
|
540
678
|
== Filter
|
|
541
679
|
|
|
542
680
|
Before-Filter werden immer vor jedem Request in dem selben Kontext wie danach
|
|
@@ -561,7 +699,8 @@ Instanzvariablen können in After-Filterm verwendet werden:
|
|
|
561
699
|
puts response.status
|
|
562
700
|
end
|
|
563
701
|
|
|
564
|
-
Filter können optional auch mit einem Pattern ausgestattet werden, welche auf
|
|
702
|
+
Filter können optional auch mit einem Pattern ausgestattet werden, welche auf
|
|
703
|
+
den Request-Pfad passen müssen, damit der Filter ausgeführt wird:
|
|
565
704
|
|
|
566
705
|
before '/protected/*' do
|
|
567
706
|
authenticate!
|
|
@@ -571,6 +710,32 @@ Filter können optional auch mit einem Pattern ausgestattet werden, welche auf d
|
|
|
571
710
|
session[:last_slug] = slug
|
|
572
711
|
end
|
|
573
712
|
|
|
713
|
+
Ähnlich wie Routen können Filter auch mit weiteren Bedingungen eingeschränkt
|
|
714
|
+
werden:
|
|
715
|
+
|
|
716
|
+
before :agent => /Songbird/ do
|
|
717
|
+
# ...
|
|
718
|
+
end
|
|
719
|
+
|
|
720
|
+
after '/blog/*', :host_name => 'example.com' do
|
|
721
|
+
# ...
|
|
722
|
+
end
|
|
723
|
+
|
|
724
|
+
== Helfer
|
|
725
|
+
|
|
726
|
+
Durch die Top-Level <tt>helpers</tt>-Methode, werden sogenannte Helfer-Methoden
|
|
727
|
+
definiert, die in Routen und Templates verwendet werden können:
|
|
728
|
+
|
|
729
|
+
helpers do
|
|
730
|
+
def bar(name)
|
|
731
|
+
"#{name}bar"
|
|
732
|
+
end
|
|
733
|
+
end
|
|
734
|
+
|
|
735
|
+
get '/:name' do
|
|
736
|
+
bar(params[:name])
|
|
737
|
+
end
|
|
738
|
+
|
|
574
739
|
== Anhalten
|
|
575
740
|
|
|
576
741
|
Zum sofortigen stoppen eines Request in einem Filter oder einer Route:
|
|
@@ -610,9 +775,173 @@ Der Block wird sofort verlassen und es wird nach der nächsten treffenden Route
|
|
|
610
775
|
gesucht. Ein 404 Fehler wird zurückgegeben, wenn kein treffendes Routen-Muster
|
|
611
776
|
gefunden wird.
|
|
612
777
|
|
|
778
|
+
=== Eine andere Route ansteuern
|
|
779
|
+
|
|
780
|
+
Manchmal entspricht +pass+ nicht den Anforderungen, wenn das Ergebnis einer
|
|
781
|
+
anderen Route gefordert wird. Um das zu erreichen, lässt sich +call+ nutzen:
|
|
782
|
+
|
|
783
|
+
get '/foo' do
|
|
784
|
+
status, headers, body = call request.env.merge("PATH_INFO" => '/bar')
|
|
785
|
+
[status, body.upcase]
|
|
786
|
+
end
|
|
787
|
+
|
|
788
|
+
get '/bar' do
|
|
789
|
+
"bar"
|
|
790
|
+
end
|
|
791
|
+
|
|
792
|
+
Beachte, dass in dem oben angegeben Beispiel die Performance erheblich erhöht
|
|
793
|
+
werden kann, wenn man +"bar"+ in eine Helfermethode umwandelt, auf die +/foo+
|
|
794
|
+
und +/bar+ zugreifen können.
|
|
795
|
+
|
|
796
|
+
Wenn der Request innerhalb der gleichen App-Instanz aufgerufen und keine
|
|
797
|
+
Kopie der Instanz erzeugt werden soll, dann verwende +call!+ anstelle von
|
|
798
|
+
+call+.
|
|
799
|
+
|
|
800
|
+
Die Rack Spezifikationen enthalten weitere Informationen zu +call+.
|
|
801
|
+
|
|
802
|
+
=== Body, Status Code und Header setzen
|
|
803
|
+
|
|
804
|
+
Es ist möglich und empfohlen den Status Code sowie den Response Body mit einem
|
|
805
|
+
Returnwert in der Route zu setzen. In manchen Situationen kann es jedoch sein,
|
|
806
|
+
dass der Body an irgendeiner anderen Stelle während der Ausführung gesetzt
|
|
807
|
+
wird. Das lässt sich mit der Helfermethode +body+ bewerkstelligen. Wird +body+
|
|
808
|
+
verwendet, dann lässt sich der Body jederzeit über diese Methode aufrufen:
|
|
809
|
+
|
|
810
|
+
get '/foo' do
|
|
811
|
+
body "bar"
|
|
812
|
+
end
|
|
813
|
+
|
|
814
|
+
after do
|
|
815
|
+
puts body
|
|
816
|
+
end
|
|
817
|
+
|
|
818
|
+
Ebenso ist es möglich einen Block an +body+ weiterzureichen, der dann vom Rack
|
|
819
|
+
Handler ausgeführt wird (lässt sich z.B. zur Umsetzung von Streaming einsetzen,
|
|
820
|
+
siehe auch "Rückgabewerte").
|
|
821
|
+
|
|
822
|
+
Vergleichbar mit +body+ lassen sich auch Status Code und Header setzen:
|
|
823
|
+
|
|
824
|
+
get '/foo' do
|
|
825
|
+
status 418
|
|
826
|
+
headers \
|
|
827
|
+
"Allow" => "BREW, POST, GET, PROPFIND, WHEN"
|
|
828
|
+
"Refresh" => "Refresh: 20; http://www.ietf.org/rfc/rfc2324.txt"
|
|
829
|
+
halt "Ich bin ein Teekesselchen"
|
|
830
|
+
end
|
|
831
|
+
|
|
832
|
+
Genau wie bei +body+, liest ein Aufrufen von +headers+ oder +status+ ohne
|
|
833
|
+
Argumente den aktuellen Wert aus.
|
|
834
|
+
|
|
835
|
+
== Mime-Types
|
|
836
|
+
|
|
837
|
+
Wenn <tt>send_file</tt> oder statische Dateien verwendet werden, kann es
|
|
838
|
+
vorkommen, dass Sinatra den Mime-Typ nicht kennt. Registriert wird dieser mit
|
|
839
|
+
+mime_type+ per Dateiendung:
|
|
840
|
+
|
|
841
|
+
mime_type :foo, 'text/foo'
|
|
842
|
+
|
|
843
|
+
Es kann aber auch der +content_type+ Helfer verwendet werden:
|
|
844
|
+
|
|
845
|
+
get '/' do
|
|
846
|
+
content_type :foo
|
|
847
|
+
"foo foo foo"
|
|
848
|
+
end
|
|
849
|
+
|
|
850
|
+
=== URLs generieren
|
|
851
|
+
|
|
852
|
+
Zum Generieren von URLs sollte man die +url+ Helfermethode nutzen, so z.B.
|
|
853
|
+
beim Einsatz von Haml:
|
|
854
|
+
|
|
855
|
+
%a{:href => url('/foo')} foo
|
|
856
|
+
|
|
857
|
+
Soweit vorhanden, wird Rücksicht auf Proxies und Rack Router genommen.
|
|
858
|
+
|
|
859
|
+
Diese Methode ist ebenso über den Alias +to+ zu erreichen (siehe Beispiel
|
|
860
|
+
unten).
|
|
861
|
+
|
|
862
|
+
=== Browserumleitung
|
|
863
|
+
|
|
864
|
+
Eine Browserumleitung kann mit Hilfe der +redirect+ Hilfsmethode erreicht
|
|
865
|
+
werden:
|
|
866
|
+
|
|
867
|
+
get '/foo' do
|
|
868
|
+
redirect to('/bar')
|
|
869
|
+
end
|
|
870
|
+
|
|
871
|
+
Weitere Parameter werden wie Argumente der +halt+ Methode behandelt:+:
|
|
872
|
+
|
|
873
|
+
redirect to('/bar'), 303
|
|
874
|
+
redirect 'http://google.com', 'Hier bist Du falsch'
|
|
875
|
+
|
|
876
|
+
Ebenso leicht lässt sich ein Schritt zurück mit dem Alias
|
|
877
|
+
<tt>redirect back</tt> erreichen:
|
|
878
|
+
|
|
879
|
+
get '/foo' do
|
|
880
|
+
"<a href='/bar'>mach was</a>"
|
|
881
|
+
end
|
|
882
|
+
|
|
883
|
+
get '/bar' do
|
|
884
|
+
mach_was
|
|
885
|
+
redirect back
|
|
886
|
+
end
|
|
887
|
+
|
|
888
|
+
Um Argumente an ein Redirect weiterzugeben, fügt man sie entweder dem Query
|
|
889
|
+
hinzu:
|
|
890
|
+
|
|
891
|
+
redirect to('/bar?summe=42')
|
|
892
|
+
|
|
893
|
+
Oder man verwendet eine Session:
|
|
894
|
+
|
|
895
|
+
enable :session
|
|
896
|
+
|
|
897
|
+
get '/foo' do
|
|
898
|
+
session[:secret] = 'foo'
|
|
899
|
+
redirect to('/bar')
|
|
900
|
+
end
|
|
901
|
+
|
|
902
|
+
get '/bar' do
|
|
903
|
+
session[:secret]
|
|
904
|
+
end
|
|
905
|
+
|
|
906
|
+
=== Dateien versenden
|
|
907
|
+
|
|
908
|
+
Zum versenden von Dateien kann die <tt>send_file</tt> Helfermethode verwende
|
|
909
|
+
werden:
|
|
910
|
+
|
|
911
|
+
get '/' do
|
|
912
|
+
send_file 'foo.png'
|
|
913
|
+
end
|
|
914
|
+
|
|
915
|
+
Für <tt>send_file</tt> stehen einige Hash-Optionen zur Verfügung:
|
|
916
|
+
|
|
917
|
+
send_file 'foo.png', :type => :jpg
|
|
918
|
+
|
|
919
|
+
[filename]
|
|
920
|
+
Dateiname als Response. Standartwert ist der eigentliche Dateiname
|
|
921
|
+
|
|
922
|
+
[last_modified]
|
|
923
|
+
Wert für den Last-Modified Header, Standardwert ist +mtime+ der Datei.
|
|
924
|
+
|
|
925
|
+
[type]
|
|
926
|
+
content type der verwendet werden soll. Wird, wenn nicht angegeben, von der
|
|
927
|
+
Dateiendung abgeleitet.
|
|
928
|
+
|
|
929
|
+
[disposition]
|
|
930
|
+
Verwendet für Content-Disposition. Mögliche Werte sind: +nil+ (Standard),
|
|
931
|
+
<tt>:attachment</tt> und <tt>:inline</tt>
|
|
932
|
+
|
|
933
|
+
[length]
|
|
934
|
+
Content-Length Header. Standardwert ist die Dateigröße
|
|
935
|
+
|
|
936
|
+
Soweit vom Rack Handler unterstützt, werden neben der Übertragung über den Ruby
|
|
937
|
+
Prozess auch andere Möglichkeiten genutzt. Bei Verwendung der
|
|
938
|
+
<tt>send_file</tt> Helfermethode kümmert sich Sinatra selbständig um die
|
|
939
|
+
Range Requests.
|
|
940
|
+
|
|
613
941
|
== Das Request-Objekt
|
|
614
942
|
|
|
615
|
-
Auf das
|
|
943
|
+
Auf das +request+-Objeket der eigehenden Anfrage kann man vom Anfragescope aus
|
|
944
|
+
zugreifen:
|
|
616
945
|
|
|
617
946
|
# App läuft unter http://example.com/example
|
|
618
947
|
get '/foo' do
|
|
@@ -629,14 +958,15 @@ Auf das `request`-Objeket der eigehenden Anfrage kann man vom Anfragescope aus z
|
|
|
629
958
|
request.get? # true (ähnliche Methoden für andere Verben)
|
|
630
959
|
request.form_data? # false
|
|
631
960
|
request["SOME_HEADER"] # Wert des SOME_HEADER-headers
|
|
632
|
-
request.
|
|
961
|
+
request.referrer # der Referrer des Clients oder '/'
|
|
633
962
|
request.user_agent # User Agent (genutzt von :agent-Bedingung)
|
|
634
963
|
request.cookies # Hash der Cookies
|
|
635
964
|
request.xhr? # Ist dies eine Ajax-Anfrage?
|
|
636
965
|
request.url # "http://example.com/example/foo"
|
|
637
966
|
request.path # "/example/foo"
|
|
638
967
|
request.ip # Client IP-Addresse
|
|
639
|
-
request.secure? # false
|
|
968
|
+
request.secure? # false (wäre true bei SSL)
|
|
969
|
+
request.forwarded? # true (wenn hinter Reverse Proxy)
|
|
640
970
|
requuest.env # env-Hash den Rack durchreicht
|
|
641
971
|
end
|
|
642
972
|
|
|
@@ -657,12 +987,71 @@ Der <tt>request.body</tt> ist einn IO- oder StringIO-Objekt:
|
|
|
657
987
|
"Hallo #{daten['name']}!"
|
|
658
988
|
end
|
|
659
989
|
|
|
990
|
+
|
|
991
|
+
=== Nachschlagen von Template Dateien
|
|
992
|
+
|
|
993
|
+
Die <tt>find_template</tt> Helfermethode wird genutzt, um Template Dateien zum
|
|
994
|
+
Rendern aufzufinden:
|
|
995
|
+
|
|
996
|
+
find_template settings.views, 'foo', Tilt[:haml] do |file|
|
|
997
|
+
puts "könnte diese hier sein: #{file}"
|
|
998
|
+
end
|
|
999
|
+
|
|
1000
|
+
Das ist zwar nicht wirklich brauchbar, aber wenn man sie überschreibt, kann sie
|
|
1001
|
+
nützlich werden, um eigene Nachschlagemechanismen einzubauen. Zum Beispiel
|
|
1002
|
+
dann, wenn man mehr als nur ein view-Verzeichnis verwenden möchte:
|
|
1003
|
+
|
|
1004
|
+
set :views, ['views', 'templates']
|
|
1005
|
+
|
|
1006
|
+
helpers do
|
|
1007
|
+
def find_template(views, name, engine, &block)
|
|
1008
|
+
Array(views).each { |v| super(v, name, engine, &block) }
|
|
1009
|
+
end
|
|
1010
|
+
end
|
|
1011
|
+
|
|
1012
|
+
Ein anderes Beispiel wäre es verschiedene Vereichnisse für verschiedene Engines
|
|
1013
|
+
zu verwenden:
|
|
1014
|
+
|
|
1015
|
+
set :views, :sass => 'views/sass', :haml => 'templates', :default => 'views'
|
|
1016
|
+
|
|
1017
|
+
helpers do
|
|
1018
|
+
def find_template(views, name, engine, &block)
|
|
1019
|
+
_, folder = views.detect { |k,v| engine == Tilt[k] }
|
|
1020
|
+
folder ||= views[:default]
|
|
1021
|
+
super(folder, name, engine, &block)
|
|
1022
|
+
end
|
|
1023
|
+
end
|
|
1024
|
+
|
|
1025
|
+
Ebensogut könnte man eine Extension schreiben und diese dann mit anderen
|
|
1026
|
+
teilen!
|
|
1027
|
+
|
|
1028
|
+
Beachte, dass <tt>find_template</tt> nicht prüft, ob eine Datei tatsächlich
|
|
1029
|
+
existiert. Es wird lediglich der angegebene Block aufgerufen und nach allen
|
|
1030
|
+
möglichen Pfaden gesucht. Das ergibt kein Performanceproblem, da +render+
|
|
1031
|
+
+block+ verwendet, sobald eine Datei gefunden wurde. Ebenso werden
|
|
1032
|
+
Templatepfade samt Inhalt gecached, solange man nicht im Entwicklungsmodus ist.
|
|
1033
|
+
Das sollte man im Hinterkopf behalten, wenn man irgendwelche verrückten
|
|
1034
|
+
Methoden zusammenbastelt.
|
|
1035
|
+
|
|
660
1036
|
== Konfiguration
|
|
661
1037
|
|
|
662
1038
|
Wird einmal beim Starten in jedweder Umgebung ausgeführt:
|
|
663
1039
|
|
|
664
1040
|
configure do
|
|
665
|
-
|
|
1041
|
+
# setze eine Option
|
|
1042
|
+
set :option, 'wert'
|
|
1043
|
+
|
|
1044
|
+
# setze mehrere Optionen
|
|
1045
|
+
set :a => 1, :b => 2
|
|
1046
|
+
|
|
1047
|
+
# das gleiche wie `set :option, true`
|
|
1048
|
+
enable :option
|
|
1049
|
+
|
|
1050
|
+
# das gleiche wie `set :option, false`
|
|
1051
|
+
disable :option
|
|
1052
|
+
|
|
1053
|
+
# Dynamische Einstellungen mit Blöcken
|
|
1054
|
+
set(:css_dir) { File.join(views, 'css') }
|
|
666
1055
|
end
|
|
667
1056
|
|
|
668
1057
|
Läuft nur, wenn die Umgebung (RACK_ENV Umgebungsvariable) auf
|
|
@@ -679,6 +1068,116 @@ gesetzt ist:
|
|
|
679
1068
|
...
|
|
680
1069
|
end
|
|
681
1070
|
|
|
1071
|
+
Zugang zu diesen Einstellungen bekommt man über +settings+:
|
|
1072
|
+
|
|
1073
|
+
configure do
|
|
1074
|
+
set :foo, 'bar'
|
|
1075
|
+
end
|
|
1076
|
+
|
|
1077
|
+
get '/' do
|
|
1078
|
+
settings.foo? # => true
|
|
1079
|
+
settings.foo # => 'bar'
|
|
1080
|
+
...
|
|
1081
|
+
end
|
|
1082
|
+
|
|
1083
|
+
=== Mögliche Einstellungen
|
|
1084
|
+
|
|
1085
|
+
[absolute_redirects] Wenn ausgeschaltet wird Sinatra relative Redirects
|
|
1086
|
+
zulassen. Jedoch ist Sinatra dann nicht mehr mit RFC 2616
|
|
1087
|
+
(HTTP 1.1) konform, das nur absolute Redirects zulässt.
|
|
1088
|
+
|
|
1089
|
+
Sollte eingeschaltet werden, wenn man hinter einem
|
|
1090
|
+
Reverse Proxy ist, der nicht ordentlich eingerichtet ist.
|
|
1091
|
+
Beachte, dass die +url+ Helfermethode nach wie vor
|
|
1092
|
+
absolute URLs erstellen wird, es sei denn man gibt als
|
|
1093
|
+
zweiten Parameter +false+ an.
|
|
1094
|
+
|
|
1095
|
+
Standardmäßig nicht aktiviert.
|
|
1096
|
+
|
|
1097
|
+
|
|
1098
|
+
[add_charsets] Mime Types werden hier automatisch der Helfermethode
|
|
1099
|
+
<tt>content_type</tt> zugeordnet.
|
|
1100
|
+
|
|
1101
|
+
Es empfielt sich Werte hinzuzufügen anstellen von
|
|
1102
|
+
überschreiben:
|
|
1103
|
+
|
|
1104
|
+
settings.add_charsets << "application/foobar"
|
|
1105
|
+
|
|
1106
|
+
[app_file] Hauptdatei der Applikation. Wird verwendet, um das
|
|
1107
|
+
Wurzel-, Inline-, View- und öffentliche Verzeichnis des
|
|
1108
|
+
Projekts festzustellen.
|
|
1109
|
+
|
|
1110
|
+
[bind] IP Address an die gebunden wird (Standardwert: 0.0.0.0).
|
|
1111
|
+
Wird nur für den eingebauten Server verwendet.
|
|
1112
|
+
|
|
1113
|
+
[default_encoding] Das Encoding, falls keines angegeben wurde.
|
|
1114
|
+
Standardwert ist <tt>"utf-8"</tt>.
|
|
1115
|
+
|
|
1116
|
+
[dump_errors] Fehler im Log anzeigen.
|
|
1117
|
+
|
|
1118
|
+
[environment] Momentane Umgebung. Standardmäßig auf
|
|
1119
|
+
<tt>content_type</tt> eingestellt oder
|
|
1120
|
+
<tt>"development"</tt> soweit ersteres nicht vorhanden.
|
|
1121
|
+
|
|
1122
|
+
[logging] Den Logger verwenden.
|
|
1123
|
+
|
|
1124
|
+
[lock] Jeder Request wird gelocked. Es kann nur ein Request pro
|
|
1125
|
+
Ruby Prozess gleichzeitig verarbeitet werden.
|
|
1126
|
+
|
|
1127
|
+
Eingeschaltet wenn die Application Thread-Safe ist.
|
|
1128
|
+
Standardmäßig nicht aktiviert.
|
|
1129
|
+
|
|
1130
|
+
[method_override] Verwende <tt>_method</tt>, um put/delete Formulardaten in
|
|
1131
|
+
Browsern zu verwenden, die dies normalerweise nicht
|
|
1132
|
+
unterstützen.
|
|
1133
|
+
|
|
1134
|
+
[port] Port für die Applikation. Wird nur im internen Server
|
|
1135
|
+
verwendet.
|
|
1136
|
+
|
|
1137
|
+
[prefixed_redirects] Entscheidet, ob <tt>request.script_name</tt> in Redirects
|
|
1138
|
+
eingefügt wird oder nicht, wenn kein absoluter Pfad
|
|
1139
|
+
angegeben ist. Auf diese Art und Weise verhält sich
|
|
1140
|
+
<tt>redirect '/foo'</tt> so als ob es ein
|
|
1141
|
+
<tt>redirect to('/foo')</tt> wäre.
|
|
1142
|
+
Standardmäßig nicht aktiviert.
|
|
1143
|
+
|
|
1144
|
+
[public] Das öffentliche Verzeichnis aus dem Daten zur Verfügung
|
|
1145
|
+
gestellt werden können.
|
|
1146
|
+
|
|
1147
|
+
[reload_templates] Entscheidet, ob Templates zwischen Anfragen neu geladen
|
|
1148
|
+
werden sollen oder nicht. Unter Ruby 1.8.6 ist es im
|
|
1149
|
+
Entwicklungsmodus eingeschaltet (um einen Fehler in Ruby
|
|
1150
|
+
auszugleichen, der ein Speicherleck verursacht).
|
|
1151
|
+
|
|
1152
|
+
[root] Wurzelverzeichnis des Projekts.
|
|
1153
|
+
|
|
1154
|
+
[raise_errors] Einen Ausnahmezustand aufrufen. Beendet die Applikation.
|
|
1155
|
+
|
|
1156
|
+
[run] Wenn aktiviert, wird Sinatra versuchen den Webserver zu
|
|
1157
|
+
starten. Nicht verwenden, wenn Rackup oder anderes
|
|
1158
|
+
verwendet werden soll.
|
|
1159
|
+
|
|
1160
|
+
[running] Läuft der eingebaute Server? Diese Einstellung nicht
|
|
1161
|
+
ändern!
|
|
1162
|
+
|
|
1163
|
+
[server] Server oder Liste von Servern die als eingebaute Server
|
|
1164
|
+
zur Verfügung stehen.
|
|
1165
|
+
Standardmäßig auf ['thin', 'mongrel', 'webrick']
|
|
1166
|
+
voreingestellt. Die Anordnung gibt die Priorität vor.
|
|
1167
|
+
|
|
1168
|
+
[sessions] Sessions auf Cookiebasis aktivieren.
|
|
1169
|
+
|
|
1170
|
+
[show_exceptions] Stacktrace im Browser bei Fehlern anzeigen.
|
|
1171
|
+
|
|
1172
|
+
[static] Entscheidet, ob Sinatra statische Dateien zur Verfügung
|
|
1173
|
+
stellen soll oder nicht.
|
|
1174
|
+
Sollte nicht aktiviert werden, wenn ein Server verwendet
|
|
1175
|
+
wird, der dies auch selbständig erledigen kann.
|
|
1176
|
+
Deaktivieren wird die Performance erhöhen.
|
|
1177
|
+
Standardmäßig aktiviert.
|
|
1178
|
+
|
|
1179
|
+
[views] Verzeichnis der Views.
|
|
1180
|
+
|
|
682
1181
|
== Fehlerbehandlung
|
|
683
1182
|
|
|
684
1183
|
Error Handler laufen im selben Kontext wie Routen und Filter, was bedeutet,
|
|
@@ -687,7 +1186,8 @@ verwendet werden können.
|
|
|
687
1186
|
|
|
688
1187
|
=== Nicht gefunden
|
|
689
1188
|
|
|
690
|
-
Wenn eine <tt>Sinatra::NotFound</tt> Exception geworfen wird oder der
|
|
1189
|
+
Wenn eine <tt>Sinatra::NotFound</tt> Exception geworfen wird oder der
|
|
1190
|
+
Statuscode 404 ist, wird der <tt>not_found</tt> Handler ausgeführt:
|
|
691
1191
|
|
|
692
1192
|
not_found do
|
|
693
1193
|
'Seite kann nirgendwo gefunden werden.'
|
|
@@ -695,8 +1195,8 @@ Wenn eine <tt>Sinatra::NotFound</tt> Exception geworfen wird oder der Statuscode
|
|
|
695
1195
|
|
|
696
1196
|
=== Fehler
|
|
697
1197
|
|
|
698
|
-
Der +error+ Handler wird immer ausgeführt, wenn eine Exception in einem
|
|
699
|
-
oder in einen Filter geworfen wurde. Die Exception kann über die
|
|
1198
|
+
Der +error+ Handler wird immer ausgeführt, wenn eine Exception in einem
|
|
1199
|
+
Routenblock oder in einen Filter geworfen wurde. Die Exception kann über die
|
|
700
1200
|
<tt>sinatra.error</tt> Rack-Variable angesprochen werden:
|
|
701
1201
|
|
|
702
1202
|
error do
|
|
@@ -738,21 +1238,10 @@ Oder ein Statuscode-Bereich:
|
|
|
738
1238
|
Sinatra setzt verschiedene <tt>not_found</tt> und <tt>error</tt>
|
|
739
1239
|
Handler in der Development Umgebung.
|
|
740
1240
|
|
|
741
|
-
== Mime-Types
|
|
742
|
-
|
|
743
|
-
Wenn <tt>send_file</tt> oder statische Dateien verwendet werden, kann es
|
|
744
|
-
vorkommen, dass Sinatra den Mime-Typ nicht kennt. Registriert wird dieser mit
|
|
745
|
-
+mime_type+ per Dateiendung:
|
|
746
|
-
|
|
747
|
-
mime_type :foo, 'text/foo'
|
|
748
|
-
|
|
749
|
-
Es kann aber auch der +content_type+ Helfer verwendet werden:
|
|
750
|
-
|
|
751
|
-
content_type :foo
|
|
752
|
-
|
|
753
1241
|
== Rack Middleware
|
|
754
1242
|
|
|
755
|
-
Sinatra baut auf Rack[http://rack.rubyforge.org/], einem minimalen
|
|
1243
|
+
Sinatra baut auf Rack[http://rack.rubyforge.org/], einem minimalen
|
|
1244
|
+
Standardinterface für Ruby Webframeworks. Eines der interessantesten
|
|
756
1245
|
Features für Entwickler ist der Support von Middleware, die
|
|
757
1246
|
zwischen den Server und die Anwendung geschaltet wird und so HTTP
|
|
758
1247
|
Request und/oder Antwort überwachen und/oder manipulieren kann.
|
|
@@ -825,7 +1314,8 @@ Das Definitieren einer Top-Level Anwendung funktioniert gut für
|
|
|
825
1314
|
Microanwendungen, hat aber Nachteile, wenn man wiederverwendbare Komponenten
|
|
826
1315
|
wie Middleware, Rails Metal, einfache Bibliotheken mit Server Komponenten
|
|
827
1316
|
oder auch Sinatra Erweiterungen bauen will.
|
|
828
|
-
Die Top-Level DSL belastet den Objekt-Namespace und setzt einen
|
|
1317
|
+
Die Top-Level DSL belastet den Objekt-Namespace und setzt einen
|
|
1318
|
+
Microanwendungsstil voraus (eine einzelne Anwendungsdatei, ./public und ./views
|
|
829
1319
|
Ordner, Logging, Exception-Detail-Seite, usw.). Genau hier kommt Sinatra::Base
|
|
830
1320
|
ins Spiel:
|
|
831
1321
|
|
|
@@ -848,7 +1338,8 @@ einer Bibliothek:
|
|
|
848
1338
|
MyApp.run! :host => 'localhost', :port => 9090
|
|
849
1339
|
|
|
850
1340
|
Die Methoden der Sinatra::Base-Subklasse sind genau die selben wie die
|
|
851
|
-
der Top-Level DSL. Die meisten Top-Level Anwendungen können mit nur zwei
|
|
1341
|
+
der Top-Level DSL. Die meisten Top-Level Anwendungen können mit nur zwei
|
|
1342
|
+
Veränderungen zu Sinatra::Base-Komponenten konvertiert werden:
|
|
852
1343
|
|
|
853
1344
|
* Die Datei sollte <tt>require 'sinatra/base'</tt> anstelle von
|
|
854
1345
|
<tt>require 'sinatra/base'</tt> aufrufen, ansonsten werden alle von
|
|
@@ -856,7 +1347,100 @@ der Top-Level DSL. Die meisten Top-Level Anwendungen können mit nur zwei Verän
|
|
|
856
1347
|
* Alle Routen, Error Handler, Filter und Optionen der Applikation müssen in
|
|
857
1348
|
einer Subklasse von Sinatra::Base definiert werden.
|
|
858
1349
|
|
|
859
|
-
<tt>Sinatra::Base</tt> ist ein unbeschriebenes Blatt. Die meisten Optionen sind
|
|
1350
|
+
<tt>Sinatra::Base</tt> ist ein unbeschriebenes Blatt. Die meisten Optionen sind
|
|
1351
|
+
per default deaktiviert. Das betrifft auch den eingebauten Server. Siehe
|
|
1352
|
+
{Optionen und Konfiguration}[http://sinatra.github.com/configuration.html] für
|
|
1353
|
+
Details über mögliche Optionen.
|
|
1354
|
+
|
|
1355
|
+
=== Modularer vs. klassischer Stil
|
|
1356
|
+
|
|
1357
|
+
Entgegen häufiger Meinungen gibt es nichts gegen den klassischen Stil
|
|
1358
|
+
einzuwenden. Solange es die Applikation nicht beeinträchtigt, besteht kein
|
|
1359
|
+
Grund eine modulare Applikation zu erstellen.
|
|
1360
|
+
|
|
1361
|
+
Lediglich zwei Nachteile gegenüber dem modularen Stil sollten beachtet werden:
|
|
1362
|
+
|
|
1363
|
+
* Es kann nur eine Sinatra Applikation pro Ruby Prozess laufen. Sollten mehrere
|
|
1364
|
+
zum Einsatz kommen, muss auf modular umgestiegen werden.
|
|
1365
|
+
|
|
1366
|
+
* Der klassische Stil füllt Object mit Delegationsmethoden. Sollte die
|
|
1367
|
+
Applikation als gem/Bibliothek zum Einsatz kommen, sollte auf modular
|
|
1368
|
+
umgestiegen werden.
|
|
1369
|
+
|
|
1370
|
+
Es gibt keinen Grund, warum man modulare und klassische Elemente nicht
|
|
1371
|
+
vermischen sollte.
|
|
1372
|
+
|
|
1373
|
+
Will man jedoch von einem Stil auf den anderen umsteigen, sollten einige
|
|
1374
|
+
Unterschiede beachtet werden:
|
|
1375
|
+
|
|
1376
|
+
Szenario Classic Modular
|
|
1377
|
+
|
|
1378
|
+
app_file file loading sinatra nil
|
|
1379
|
+
run $0 == app_file false
|
|
1380
|
+
logging true false
|
|
1381
|
+
method_override true false
|
|
1382
|
+
inline_templates true false
|
|
1383
|
+
|
|
1384
|
+
|
|
1385
|
+
=== Eine modulare Applikation bereitstellen
|
|
1386
|
+
|
|
1387
|
+
Es gibt zwei übliche Wege eine modulare Anwendung zu starten. Zum einen über
|
|
1388
|
+
<tt>run!</tt>:
|
|
1389
|
+
|
|
1390
|
+
# mein_app.rb
|
|
1391
|
+
require 'sinatra/base'
|
|
1392
|
+
|
|
1393
|
+
class MeinApp < Sinatra::Base
|
|
1394
|
+
# ... Anwendungscode hierhin ...
|
|
1395
|
+
|
|
1396
|
+
# starte den Server, wenn die Ruby Datei direkt ausgeführt wird
|
|
1397
|
+
run! if app_file == $0
|
|
1398
|
+
end
|
|
1399
|
+
|
|
1400
|
+
Starte mit:
|
|
1401
|
+
|
|
1402
|
+
ruby mein_app.rb
|
|
1403
|
+
|
|
1404
|
+
Oder über eine <tt>config.ru</tt>, die es erlaubt irgendeinen Rack Handler zu
|
|
1405
|
+
verwenden:
|
|
1406
|
+
|
|
1407
|
+
# config.ru
|
|
1408
|
+
require 'mein_app'
|
|
1409
|
+
run MeineApp
|
|
1410
|
+
|
|
1411
|
+
Starte:
|
|
1412
|
+
|
|
1413
|
+
rackup -p 4567
|
|
1414
|
+
|
|
1415
|
+
=== Eine klassische Anwendung mit einer config.ru verwenden
|
|
1416
|
+
|
|
1417
|
+
Schreibe eine Anwendungsdatei:
|
|
1418
|
+
|
|
1419
|
+
# app.rb
|
|
1420
|
+
require 'sinatra'
|
|
1421
|
+
|
|
1422
|
+
get '/' do
|
|
1423
|
+
'Hallo Welt!'
|
|
1424
|
+
end
|
|
1425
|
+
|
|
1426
|
+
Sowie eine dazugehörige <tt>config.ru</tt>:
|
|
1427
|
+
|
|
1428
|
+
require 'app'
|
|
1429
|
+
run Sinatra::Application
|
|
1430
|
+
|
|
1431
|
+
=== Wann verwendet man eine config.ru?
|
|
1432
|
+
|
|
1433
|
+
Anzeichen dafür, dass man eine <tt>config.ru</tt> braucht:
|
|
1434
|
+
|
|
1435
|
+
* Man möchte einen anderen Rack Handler verwenden (Passenger, Unicorn,
|
|
1436
|
+
Heroku, ...).
|
|
1437
|
+
* Man möchte mehr als eine Subklasse von <tt>Sinatra::Base</tt>.
|
|
1438
|
+
* Man möchte Sinatra als Middleware verwenden, nicht als Endpoint.
|
|
1439
|
+
|
|
1440
|
+
<b>Es gibt keinen Grund eine <tt>config.ru</tt> zu verwenden, nur weil man eine
|
|
1441
|
+
Anwendung im modularen Stil betreiben möchte. Ebenso braucht man keine
|
|
1442
|
+
Anwendung im modularen Stil, um eine <tt>config.ru</tt> verwenden zu können.
|
|
1443
|
+
</b>
|
|
860
1444
|
|
|
861
1445
|
=== Sinatra als Middleware nutzen
|
|
862
1446
|
|
|
@@ -895,16 +1479,22 @@ Sinatra-Anwendung handen, es kann jede andere Rack-Anwendung sein
|
|
|
895
1479
|
get('/') { "Hallo #{session['user_name']}." }
|
|
896
1480
|
end
|
|
897
1481
|
|
|
898
|
-
==
|
|
1482
|
+
== Geltungsbereich und Bindung
|
|
899
1483
|
|
|
900
|
-
|
|
901
|
-
|
|
1484
|
+
Der Geltungsbereich (scope) legt fest, welche Methoden und Variablen zur
|
|
1485
|
+
Verfügung stehen.
|
|
902
1486
|
|
|
903
1487
|
=== Anwendungs- oder Klassenscope
|
|
904
1488
|
|
|
905
|
-
Jede Sinatra-Anwendung entspricht einer Sinatra::Base-Subklasse. Falls man die
|
|
1489
|
+
Jede Sinatra-Anwendung entspricht einer Sinatra::Base-Subklasse. Falls man die
|
|
1490
|
+
Top-Level-DSL verwendet (<tt>require 'sinatra'</tt>), so handelt es sich
|
|
1491
|
+
hierbei um Sinatra::Application, andernfalls is es jene Subklasse, die man
|
|
1492
|
+
explizit angelegt hat. Auf Klassenebene stehen Methoden wie +get+ oder +before+
|
|
1493
|
+
zur Verfügung, man hat aber keinen Zugriff auf das +request+-Object oder die
|
|
1494
|
+
+session+, da nur eine einzige Klasse für alle eingehenden Anfragen genutzt
|
|
1495
|
+
wird.
|
|
906
1496
|
|
|
907
|
-
Optionen die via
|
|
1497
|
+
Optionen die via +set+ gesetzt werden, sind Methoden auf Klassenebene:
|
|
908
1498
|
|
|
909
1499
|
class MyApp < Sinatra::Base
|
|
910
1500
|
# Hey, ich bin im Anwendungsscope!
|
|
@@ -920,18 +1510,22 @@ Im Anwendungsscope befindet man sich:
|
|
|
920
1510
|
|
|
921
1511
|
* In der Anwendungsklasse.
|
|
922
1512
|
* In Methoden die von Erweiterungen definiert werden.
|
|
923
|
-
* Im Block, der an
|
|
924
|
-
* In Procs und Blöcken die an
|
|
1513
|
+
* Im Block, der an +helpers+ übergeben wird.
|
|
1514
|
+
* In Procs und Blöcken die an +set+ übergeben werden.
|
|
925
1515
|
|
|
926
1516
|
Man kann auf das Scope-Object (die Klasse) wie folgt zugreifen:
|
|
927
1517
|
|
|
928
|
-
* Über das Objekt, dass an den
|
|
1518
|
+
* Über das Objekt, dass an den +configure+-Block übergeben wird (<tt>configure
|
|
929
1519
|
{ |c| ... }</tt>).
|
|
930
|
-
*
|
|
1520
|
+
* +settings+ aus den anderen Scopes heraus.
|
|
931
1521
|
|
|
932
1522
|
=== Anfrage- oder Instanzscope
|
|
933
1523
|
|
|
934
|
-
Für jede eingehende Anfrage wird eine neue Instanz der Anwendungsklasse
|
|
1524
|
+
Für jede eingehende Anfrage wird eine neue Instanz der Anwendungsklasse
|
|
1525
|
+
erstellt und alle Handlers werden in diesem Scope ausgeführt. Aus diesem Scope
|
|
1526
|
+
heraus kann man auf +request+ oder +session+ zugreifen und Methoden wie +erb+
|
|
1527
|
+
oder +haml+ aufrufen. Man kann mit der +settings+ Methode außerdem auf den
|
|
1528
|
+
Anwengungsscope zugreifen.
|
|
935
1529
|
|
|
936
1530
|
class MyApp < Sinatra::Base
|
|
937
1531
|
# Hey, ich bin im Anwendungsscope!
|
|
@@ -962,15 +1556,18 @@ weitergeleitet. Dieser verhält sich jedoch nicht 100%ig wie der Klassenscope,
|
|
|
962
1556
|
da man nicht die Bindung der Klasse besitzt: Nur Methoden, die explizit als
|
|
963
1557
|
delegierbar markiert wurden stehen hier zur Verfügung und man kann nicht auf
|
|
964
1558
|
die Variablen des Klassenscopes zugreifen (mit anderen Worten: man hat ein
|
|
965
|
-
anderes
|
|
1559
|
+
anderes +self+). Man kann mit <tt>Sinatra::Delegator.delegate
|
|
966
1560
|
:methoden_name</tt> auch weitere Delegationen hinzufügen.
|
|
967
1561
|
|
|
968
1562
|
Im Delegation-Scop befindet man sich:
|
|
969
1563
|
|
|
970
1564
|
* Im Top-Level, wenn man <tt>require 'sinatra'</tt> aufgerufen hat.
|
|
971
|
-
* In einem Objekt, dass mit dem
|
|
1565
|
+
* In einem Objekt, dass mit dem <tt>Sinatra::Delegator</tt> mixin erweitert wurde.
|
|
972
1566
|
|
|
973
|
-
Schau am besten im Code nach: Hier ist
|
|
1567
|
+
Schau am besten im Code nach: Hier ist
|
|
1568
|
+
{Sinatra::Delegator mixin}[http://github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb#L1064]
|
|
1569
|
+
definiert und wird in den
|
|
1570
|
+
{globalen Namespace eingebunden}[http://github.com/sinatra/sinatra/blob/master/lib/sinatra/main.rb#L25].
|
|
974
1571
|
|
|
975
1572
|
== Kommandozeile
|
|
976
1573
|
|
|
@@ -988,7 +1585,40 @@ Die Optionen sind:
|
|
|
988
1585
|
-x # Mutex lock einschalten (Standard ist off)
|
|
989
1586
|
|
|
990
1587
|
== Der neueste Stand (The Bleeding Edge)
|
|
1588
|
+
Um auf dem neusten Stand zu bleiben, kannst Du den Master Branch verwenden. Er
|
|
1589
|
+
sollte recht stabil sein. Ebenso gibt es von Zeit zu Zeit prerelease Gems, die
|
|
1590
|
+
du so installierst:
|
|
1591
|
+
|
|
1592
|
+
gem install sinatra --pre
|
|
1593
|
+
|
|
1594
|
+
=== Mit Bundler
|
|
1595
|
+
Wenn du deine App mit der neusten Version von Sinatra mit
|
|
1596
|
+
{Bundler}[http://gembundler.com/] nutzen willst, dann ist dies der
|
|
1597
|
+
vorgeschlagene Weg:
|
|
1598
|
+
|
|
1599
|
+
Soweit du Bundler noch nicht installiert hast, folgendes:
|
|
1600
|
+
|
|
1601
|
+
gem install bundler
|
|
1602
|
+
|
|
1603
|
+
Dann erstellst Du in deinem Projektverzeichnis eine sog. +Gemfile+ Datei mit
|
|
1604
|
+
folgendem Inhalt:
|
|
1605
|
+
|
|
1606
|
+
source :rubygems
|
|
1607
|
+
gem 'sinatra', :git => "git://github.com/sinatra/sinatra.git"
|
|
1608
|
+
|
|
1609
|
+
# evtl. andere Abhängigkeiten
|
|
1610
|
+
gem 'haml' # z.B. wenn du haml verwendest...
|
|
1611
|
+
gem 'activerecord', '~> 3.0' # ...oder ActiveRecord 3.x
|
|
1612
|
+
|
|
1613
|
+
Beachte: Du solltest hier alle Abhängigkeiten eintragen. Sinatras eigenen,
|
|
1614
|
+
direkten Abhängigkeiten (Tilt und Rack) werden von Bundler automatisch aus dem
|
|
1615
|
+
Gemfile von Sinatra hinzugefügt.
|
|
1616
|
+
|
|
1617
|
+
Jetzt kannst du deine App starten:
|
|
991
1618
|
|
|
1619
|
+
bundle exec ruby myapp.rb
|
|
1620
|
+
|
|
1621
|
+
=== Eigenes Repository
|
|
992
1622
|
Um auf den neuesten Stand von Sinatras Code zu sein, kann eine lokale Kopie
|
|
993
1623
|
angelegt werden. Gestartet wird in der Anwendung mit dem <tt>sinatra/lib</tt>
|
|
994
1624
|
Ordner im <tt>LOAD_PATH</tt>:
|
|
@@ -1013,11 +1643,28 @@ Um Sinatra Code von Zeit zu Zeit zu aktualisieren:
|
|
|
1013
1643
|
cd myproject/sinatra
|
|
1014
1644
|
git pull
|
|
1015
1645
|
|
|
1646
|
+
=== Gem erstellen
|
|
1647
|
+
|
|
1648
|
+
Aus der eigenen lokalen Kopie kann nun auch ein globales gem gebaut werden:
|
|
1649
|
+
|
|
1650
|
+
git clone git://github.com/sinatra/sinatra.git
|
|
1651
|
+
cd sinatra
|
|
1652
|
+
rake sinatra.gemspec
|
|
1653
|
+
rake install
|
|
1654
|
+
|
|
1655
|
+
Falls du normalerweise gems als root installierst, sollte die letzte Zeile
|
|
1656
|
+
so lauten:
|
|
1657
|
+
|
|
1658
|
+
sudo rake install
|
|
1659
|
+
|
|
1660
|
+
|
|
1661
|
+
|
|
1016
1662
|
== Mehr
|
|
1017
1663
|
|
|
1018
1664
|
* {Projekt Website}[http://sinatra.github.com/] - Ergänzende Dokumentation,
|
|
1019
1665
|
News und Links zu anderen Ressourcen.
|
|
1020
|
-
* {Hilfe beisteuern}[http://sinatra.github.com/contributing.html] - Einen
|
|
1666
|
+
* {Hilfe beisteuern}[http://sinatra.github.com/contributing.html] - Einen
|
|
1667
|
+
Fehler gefunden? Brauchst du Hilfe? Hast du einen Patch?
|
|
1021
1668
|
* {Issue Tracker}[http://github.com/sinatra/sinatra/issues]
|
|
1022
1669
|
* {Twitter}[http://twitter.com/sinatra]
|
|
1023
1670
|
* {Mailingliste}[http://groups.google.com/group/sinatrarb]
|