sinatra 2.2.0 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.de.md DELETED
@@ -1,3239 +0,0 @@
1
- # Sinatra
2
-
3
- [![Build Status](https://secure.travis-ci.org/sinatra/sinatra.svg)](http://travis-ci.org/sinatra/sinatra)
4
-
5
- *Wichtig: Dieses Dokument ist eine Übersetzung aus dem Englischen und unter
6
- Umständen nicht auf dem aktuellen Stand (aktuell Sinatra 2.0
7
- Vorabausgabe).*
8
-
9
- Sinatra ist eine
10
- [DSL](https://de.wikipedia.org/wiki/Domänenspezifische_Sprache), die das
11
- schnelle Erstellen von Webanwendungen in Ruby mit minimalem Aufwand
12
- ermöglicht:
13
-
14
- ```ruby
15
- # myapp.rb
16
- require 'sinatra'
17
-
18
- get '/' do
19
- 'Hallo Welt!'
20
- end
21
- ```
22
-
23
- Sinatra-Gem installieren:
24
-
25
- ```shell
26
- gem install sinatra
27
- ```
28
-
29
- und im gleichen Verzeichnis ausführen:
30
-
31
- ```shell
32
- ruby myapp.rb
33
- ```
34
-
35
- Die Seite kann nun unter [http://localhost:4567](http://localhost:4567)
36
- aufgerufen werden.
37
-
38
- Es wird empfohlen `gem install thin` auszuführen, Sinatra wird dann
39
- diesen Server verwenden.
40
-
41
- ## Inhalt
42
-
43
- - [Sinatra](#sinatra)
44
- * [Inhalt](#inhalt)
45
- * [Routen](#routen)
46
- + [Bedingungen](#bedingungen)
47
- + [Rückgabewerte](#rückgabewerte)
48
- + [Eigene Routen-Muster](#eigene-routen-muster)
49
- * [Statische Dateien](#statische-dateien)
50
- * [Views/Templates](#views-templates)
51
- + [Direkte Templates](#direkte-templates)
52
- + [Verfügbare Templatesprachen](#verfügbare-templatesprachen)
53
- - [Haml Templates](#haml-templates)
54
- - [Erb Templates](#erb-templates)
55
- - [Builder Templates](#builder-templates)
56
- - [Nokogiri Templates](#nokogiri-templates)
57
- - [Sass Templates](#sass-templates)
58
- - [SCSS Templates](#scss-templates)
59
- - [Less Templates](#less-templates)
60
- - [Liquid Templates](#liquid-templates)
61
- - [Markdown Templates](#markdown-templates)
62
- - [Textile Templates](#textile-templates)
63
- - [RDoc Templates](#rdoc-templates)
64
- - [AsciiDoc Templates](#asciidoc-templates)
65
- - [Radius Templates](#radius-templates)
66
- - [Markaby Templates](#markaby-templates)
67
- - [RABL Templates](#rabl-templates)
68
- - [Slim Templates](#slim-templates)
69
- - [Creole Templates](#creole-templates)
70
- - [MediaWiki Templates](#mediawiki-templates)
71
- - [CoffeeScript Templates](#coffeescript-templates)
72
- - [Stylus Templates](#stylus-templates)
73
- - [Yajl Templates](#yajl-templates)
74
- - [WLang Templates](#wlang-templates)
75
- + [Auf Variablen in Templates zugreifen](#auf-variablen-in-templates-zugreifen)
76
- + [Templates mit `yield` und verschachtelte Layouts](#templates-mit--yield--und-verschachtelte-layouts)
77
- + [Inline-Templates](#inline-templates)
78
- + [Benannte Templates](#benannte-templates)
79
- + [Dateiendungen zuordnen](#dateiendungen-zuordnen)
80
- + [Eine eigene Template-Engine hinzufügen](#eine-eigene-template-engine-hinzuf-gen)
81
- + [Eigene Methoden zum Aufsuchen von Templates verwenden](#eigene-methoden-zum-aufsuchen-von-templates-verwenden)
82
- * [Filter](#filter)
83
- * [Helfer](#helfer)
84
- + [Sessions verwenden](#sessions-verwenden)
85
- - [Sitzungseinstellungen](#sitzungseinstellungen)
86
- - [Eigene Sitzungs-Middleware auswählen](#eigene-sitzungs-middleware-ausw-hlen)
87
- + [Anhalten](#anhalten)
88
- + [Weiterspringen](#weiterspringen)
89
- + [Eine andere Route ansteuern](#eine-andere-route-ansteuern)
90
- + [Body, Status-Code und Header setzen](#body--status-code-und-header-setzen)
91
- + [Response-Streams](#response-streams)
92
- + [Logger](#logger)
93
- + [Mime-Types](#mime-types)
94
- + [URLs generieren](#urls-generieren)
95
- + [Browser-Umleitung](#browser-umleitung)
96
- + [Cache einsetzen](#cache-einsetzen)
97
- + [Dateien versenden](#dateien-versenden)
98
- + [Das Request-Objekt](#das-request-objekt)
99
- + [Anhänge](#anhänge)
100
- + [Umgang mit Datum und Zeit](#umgang-mit-datum-und-zeit)
101
- + [Nachschlagen von Template-Dateien](#nachschlagen-von-template-dateien)
102
- + [Konfiguration](#konfiguration)
103
- - [Einstellung des Angriffsschutzes](#einstellung-des-angriffsschutzes)
104
- - [Mögliche Einstellungen](#m-gliche-einstellungen)
105
- * [Umgebungen](#umgebungen)
106
- * [Fehlerbehandlung](#fehlerbehandlung)
107
- + [Nicht gefunden](#nicht-gefunden)
108
- + [Fehler](#fehler)
109
- * [Rack-Middleware](#rack-middleware)
110
- * [Testen](#testen)
111
- * [Sinatra::Base - Middleware, Bibliotheken und modulare Anwendungen](#sinatra--base---middleware--bibliotheken-und-modulare-anwendungen)
112
- + [Modularer vs. klassischer Stil](#modularer-vs-klassischer-stil)
113
- + [Eine modulare Applikation bereitstellen](#eine-modulare-applikation-bereitstellen)
114
- + [Eine klassische Anwendung mit einer config.ru verwenden](#eine-klassische-anwendung-mit-einer-configru-verwenden)
115
- + [Wann sollte eine config.ru-Datei verwendet werden?](#wann-sollte-eine-configru-datei-verwendet-werden-)
116
- + [Sinatra als Middleware nutzen](#sinatra-als-middleware-nutzen)
117
- + [Dynamische Applikationserstellung](#dynamische-applikationserstellung)
118
- * [Geltungsbereich und Bindung](#geltungsbereich-und-bindung)
119
- + [Anwendungs- oder Klassen-Scope](#anwendungs--oder-klassen-scope)
120
- + [Anfrage- oder Instanz-Scope](#anfrage--oder-instanz-scope)
121
- + [Delegation-Scope](#delegation-scope)
122
- * [Kommandozeile](#kommandozeile)
123
- + [Multi-threading](#multi-threading)
124
- * [Systemanforderungen](#systemanforderungen)
125
- * [Der neuste Stand (The Bleeding Edge)](#der-neuste-stand--the-bleeding-edge-)
126
- + [Mit Bundler](#mit-bundler)
127
- + [Eigenes Repository](#eigenes-repository)
128
- + [Gem erstellen](#gem-erstellen)
129
- * [Versions-Verfahren](#versions-verfahren)
130
- * [Mehr](#mehr)
131
-
132
- ## Routen
133
-
134
- In Sinatra wird eine Route durch eine HTTP-Methode und ein URL-Muster
135
- definiert. Jeder dieser Routen wird ein Ruby-Block zugeordnet:
136
-
137
- ```ruby
138
- get '/' do
139
- .. zeige etwas ..
140
- end
141
-
142
- post '/' do
143
- .. erstelle etwas ..
144
- end
145
-
146
- put '/' do
147
- .. update etwas ..
148
- end
149
-
150
- delete '/' do
151
- .. entferne etwas ..
152
- end
153
-
154
- options '/' do
155
- .. zeige, was wir können ..
156
- end
157
-
158
- link '/' do
159
- .. verbinde etwas ..
160
- end
161
-
162
- unlink '/' do
163
- .. trenne etwas ..
164
- end
165
- ```
166
-
167
- Die Routen werden in der Reihenfolge durchlaufen, in der sie definiert wurden.
168
- Das erste Routen-Muster, das mit dem Request übereinstimmt, wird ausgeführt.
169
-
170
- Routen mit angehängtem Schrägstrich unterscheiden sich von Routen ohne:
171
-
172
- ```ruby
173
- get '/foo' do
174
- # wird nicht bei "GET /foo/" aufgerufen
175
- end
176
- ```
177
-
178
- Die Muster der Routen können benannte Parameter beinhalten, die über den
179
- `params`-Hash zugänglich gemacht werden:
180
-
181
- ```ruby
182
- get '/hallo/:name' do
183
- # passt auf "GET /hallo/foo" und "GET /hallo/bar"
184
- # params['name'] ist dann 'foo' oder 'bar'
185
- "Hallo #{params['name']}!"
186
- end
187
- ```
188
-
189
- Man kann auf diese auch mit Block-Parametern zugreifen:
190
-
191
- ```ruby
192
- get '/hallo/:name' do |n|
193
- # n entspricht hier params['name']
194
- "Hallo #{n}!"
195
- end
196
- ```
197
-
198
- Routen-Muster können auch mit sog. Splat- oder Wildcard-Parametern über das
199
- `params['splat']`-Array angesprochen werden:
200
-
201
- ```ruby
202
- get '/sag/*/zu/*' do
203
- # passt z.B. auf /sag/hallo/zu/welt
204
- params['splat'] # => ["hallo", "welt"]
205
- end
206
-
207
- get '/download/*.*' do
208
- # passt auf /download/pfad/zu/datei.xml
209
- params['splat'] # => ["pfad/zu/datei", "xml"]
210
- end
211
- ```
212
-
213
- Oder mit Block-Parametern:
214
-
215
- ```ruby
216
- get '/download/*.*' do |pfad, endung|
217
- [pfad, endung] # => ["Pfad/zu/Datei", "xml"]
218
- end
219
- ```
220
-
221
- Routen mit regulären Ausdrücken sind auch möglich:
222
-
223
- ```ruby
224
- get /\/hallo\/([\w]+)/ do
225
- "Hallo, #{params['captures'].first}!"
226
- end
227
- ```
228
-
229
- Und auch hier können Block-Parameter genutzt werden:
230
-
231
- ```ruby
232
- get %r{/hallo/([\w]+)} do |c|
233
- # erkennt "GET /hallo/frank" oder "GET /sag/hallo/frank" usw.
234
- "Hallo, #{c}!"
235
- end
236
- ```
237
-
238
- Routen-Muster können auch mit optionalen Parametern ausgestattet werden:
239
-
240
- ```ruby
241
- get '/posts/:format?' do
242
- # passt auf "GET /posts/" sowie jegliche Erweiterung
243
- # wie "GET /posts/json", "GET /posts/xml" etc.
244
- end
245
- ```
246
-
247
- Routen können auch den query-Parameter verwenden:
248
-
249
- ```ruby
250
- get '/posts' do
251
- # passt zu "GET /posts?title=foo&author=bar"
252
- title = params['title']
253
- author = params['author']
254
- # verwendet title- und author-Variablen. Der query-Parameter ist für
255
- # die /post-Route optional
256
- end
257
- ```
258
-
259
- Anmerkung: Solange man den sog. Path Traversal Attack-Schutz nicht deaktiviert
260
- (siehe weiter unten), kann es sein, dass der Request-Pfad noch vor dem
261
- Abgleich mit den Routen modifiziert wird.
262
-
263
- Die Mustermann-Optionen können für eine gegebene Route angepasst werden,
264
- indem man der Route den `:mustermann_opts`-Hash mitgibt:
265
-
266
- ```ruby
267
- get '\A/posts\z', :mustermann_opts => { :type => :regexp, :check_anchors => false } do
268
- # Passt genau auf /posts mit explizitem Anchoring
269
- "Wenn Dein Anchor-Muster passt, darfst Du klatschen!"
270
- end
271
- ```
272
-
273
- Das sieht zwar genauso aus wie eine Bedingung, ist es aber nicht. Diese
274
- Option wird mit dem globalen `:mustermann_opts`-Hash zusammengeführt
275
- (siehe weiter unten).
276
-
277
- ### Bedingungen
278
-
279
- An Routen können eine Vielzahl von Bedingungen geknüpft werden, die erfüllt
280
- sein müssen, damit der Block ausgeführt wird. Möglich wäre etwa eine
281
- Einschränkung des User-Agents über die interne Bedingung `:agent`:
282
-
283
- ```ruby
284
- get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
285
- "Du verwendest Songbird Version #{params['agent'][0]}"
286
- end
287
- ```
288
-
289
- Wird Songbird als Browser nicht verwendet, springt Sinatra zur nächsten Route:
290
-
291
- ```ruby
292
- get '/foo' do
293
- # passt auf andere Browser
294
- end
295
- ```
296
-
297
- Andere verfügbare Bedingungen sind `:host_name` und `:provides`:
298
-
299
- ```ruby
300
- get '/', :host_name => /^admin\./ do
301
- "Adminbereich, Zugriff verweigert!"
302
- end
303
-
304
- get '/', :provides => 'html' do
305
- haml :index
306
- end
307
-
308
- get '/', :provides => ['rss', 'atom', 'xml'] do
309
- builder :feed
310
- end
311
- ```
312
- `provides` durchsucht den Accept-Header der Anfrage
313
-
314
- Eigene Bedingungen können relativ einfach hinzugefügt werden:
315
-
316
- ```ruby
317
- set(:wahrscheinlichkeit) { |value| condition { rand <= value } }
318
-
319
- get '/auto_gewinnen', :wahrscheinlichkeit => 0.1 do
320
- "Du hast gewonnen!"
321
- end
322
-
323
- get '/auto_gewinnen' do
324
- "Tut mir leid, verloren."
325
- end
326
- ```
327
-
328
- Bei Bedingungen, die mehrere Werte annehmen können, sollte ein Splat verwendet
329
- werden:
330
-
331
- ```ruby
332
- set(:auth) do |*roles| # <- hier kommt der Splat ins Spiel
333
- condition do
334
- unless logged_in? && roles.any? {|role| current_user.in_role? role }
335
- redirect "/login/", 303
336
- end
337
- end
338
- end
339
-
340
- get "/mein/account/", :auth => [:user, :admin] do
341
- "Mein Account"
342
- end
343
-
344
- get "/nur/admin/", :auth => :admin do
345
- "Nur Admins dürfen hier rein!"
346
- end
347
- ```
348
-
349
- ### Rückgabewerte
350
-
351
- Durch den Rückgabewert eines Routen-Blocks wird mindestens der Response-Body
352
- festgelegt, der an den HTTP-Client, bzw. die nächste Rack-Middleware,
353
- weitergegeben wird. Im Normalfall handelt es sich hierbei, wie in den
354
- vorangehenden Beispielen zu sehen war, um einen String. Es werden allerdings
355
- auch andere Werte akzeptiert.
356
-
357
- Es kann jedes gültige Objekt zurückgegeben werden, bei dem es sich entweder um
358
- einen Rack-Rückgabewert, einen Rack-Body oder einen HTTP-Status-Code handelt:
359
-
360
- * Ein Array mit drei Elementen: `[Status (Integer), Headers (Hash),
361
- Response-Body (antwortet auf #each)]`.
362
- * Ein Array mit zwei Elementen: `[Status (Integer), Response-Body (antwortet
363
- auf #each)]`.
364
- * Ein Objekt, das auf `#each` antwortet und den an diese Methode übergebenen
365
- Block nur mit Strings als Übergabewerten aufruft.
366
- * Ein Integer, das den Status-Code festlegt.
367
-
368
- Damit lässt sich relativ einfach Streaming implementieren:
369
-
370
- ```ruby
371
- class Stream
372
- def each
373
- 100.times { |i| yield "#{i}\n" }
374
- end
375
- end
376
-
377
- get('/') { Stream.new }
378
- ```
379
-
380
- Ebenso kann die `stream`-Helfer-Methode (s.u.) verwendet werden, die Streaming
381
- direkt in die Route integriert.
382
-
383
- ### Eigene Routen-Muster
384
-
385
- Wie oben schon beschrieben, ist Sinatra von Haus aus mit Unterstützung für
386
- String-Muster und Reguläre Ausdrücke zum Abgleichen von Routen ausgestattet.
387
- Das muss aber noch nicht alles sein, es können ohne großen Aufwand eigene
388
- Routen-Muster erstellt werden:
389
-
390
- ```ruby
391
- class AllButPattern
392
- Match = Struct.new(:captures)
393
-
394
- def initialize(except)
395
- @except = except
396
- @captures = Match.new([])
397
- end
398
-
399
- def match(str)
400
- @captures unless @except === str
401
- end
402
- end
403
-
404
- def all_but(pattern)
405
- AllButPattern.new(pattern)
406
- end
407
-
408
- get all_but("/index") do
409
- # ...
410
- end
411
- ```
412
-
413
- Beachte, dass das obige Beispiel etwas übertrieben wirkt. Es geht auch
414
- einfacher:
415
-
416
- ```ruby
417
- get // do
418
- pass if request.path_info == "/index"
419
- # ...
420
- end
421
- ```
422
-
423
- Oder unter Verwendung eines negativen look ahead:
424
-
425
- ```ruby
426
- get %r{(?!/index)} do
427
- # ...
428
- end
429
- ```
430
-
431
- ## Statische Dateien
432
-
433
- Statische Dateien werden im `./public`-Ordner erwartet. Es ist möglich,
434
- einen anderen Ort zu definieren, indem man die `:public_folder`-Option setzt:
435
-
436
- ```ruby
437
- set :public_folder, __dir__ + '/static'
438
- ```
439
-
440
- Zu beachten ist, dass der Ordnername `public` nicht Teil der URL ist.
441
- Die Datei `./public/css/style.css` ist unter
442
- `http://example.com/css/style.css` zu finden.
443
-
444
- Um den `Cache-Control`-Header mit Informationen zu versorgen, verwendet man
445
- die `:static_cache_control`-Einstellung (s.u.).
446
-
447
- ## Views/Templates
448
-
449
- Alle Templatesprachen verwenden ihre eigene Renderingmethode, die jeweils
450
- einen String zurückgibt:
451
-
452
- ```ruby
453
- get '/' do
454
- erb :index
455
- end
456
- ```
457
-
458
- Dieses Beispiel rendert `views/index.erb`.
459
-
460
- Anstelle eines Templatenamens kann man auch direkt die Templatesprache
461
- verwenden:
462
-
463
- ```ruby
464
- get '/' do
465
- code = "<%= Time.now %>"
466
- erb code
467
- end
468
- ```
469
-
470
- Templates nehmen ein zweites Argument an, den Options-Hash:
471
-
472
- ```ruby
473
- get '/' do
474
- erb :index, :layout => :post
475
- end
476
- ```
477
-
478
- Dieses Beispiel rendert `views/index.erb` eingebettet in `views/post.erb`
479
- (Voreinstellung ist `views/layout.erb`, sofern es vorhanden ist.)
480
-
481
- Optionen, die Sinatra nicht versteht, werden an das Template weitergereicht:
482
-
483
- ```ruby
484
- get '/' do
485
- haml :index, :format => :html5
486
- end
487
- ```
488
-
489
- Für alle Templates können auch Einstellungen, die für alle Routen gelten,
490
- festgelegt werden:
491
-
492
- ```ruby
493
- set :haml, :format => :html5
494
-
495
- get '/' do
496
- haml :index
497
- end
498
- ```
499
-
500
- Optionen, die an die Rendermethode weitergegeben werden, überschreiben die
501
- Einstellungen, die mit `set` festgelegt wurden.
502
-
503
- Einstellungen:
504
-
505
- <dl>
506
- <dt>locals</dt>
507
- <dd>Liste von lokalen Variablen, die an das Dokument weitergegeben werden.
508
- Praktisch für Partials:
509
-
510
- <tt>erb "<%= foo %>", :locals => {:foo => "bar"}</tt></dd>
511
-
512
- <dt>default_encoding</dt>
513
- <dd>Gibt die Stringkodierung an, die verwendet werden soll. Voreingestellt
514
- auf <tt>settings.default_encoding</tt>.</dd>
515
-
516
- <dt>views</dt>
517
- <dd>Ordner, aus dem die Templates geladen werden. Voreingestellt auf
518
- <tt>settings.views</tt>.</dd>
519
-
520
- <dt>layout</dt>
521
- <dd>Legt fest, ob ein Layouttemplate verwendet werden soll oder nicht
522
- (<tt>true</tt> oder<tt>false</tt>). Ist es ein Symbol, dann legt es fest,
523
- welches Template als Layout verwendet wird:
524
-
525
- <tt>erb :index, :layout => !request.xhr?</tt></dd>
526
-
527
- <dt>content_type</dt>
528
- <dd>Content-Typ den das Template ausgibt. Voreinstellung hängt von der
529
- Templatesprache ab.</dd>
530
-
531
- <dt>scope</dt>
532
- <dd>Scope, in dem das Template gerendert wird. Liegt standardmäßig innerhalb
533
- der App-Instanz. Wird Scope geändert, sind Instanzvariablen und
534
- Helfermethoden nicht verfügbar.</dd>
535
-
536
- <dt>layout_engine</dt>
537
- <dd>Legt fest, welcher Renderer für das Layout verantwortlich ist. Hilfreich
538
- für Sprachen, die sonst keine Templates unterstützen. Voreingestellt auf
539
- den Renderer, der für das Template verwendet wird:
540
-
541
- <tt>set :rdoc, :layout_engine => :erb</tt></dd>
542
-
543
- <dt>layout_options</dt>
544
- <dd>Besondere Einstellungen, die nur für das Rendering verwendet werden:
545
-
546
- <tt>set :rdoc, :layout_options => { :views => 'views/layouts' }</tt></dd>
547
- </dl>
548
-
549
- Sinatra geht davon aus, dass die Templates sich im `./views` Verzeichnis
550
- befinden. Es kann jedoch ein anderer Ordner festgelegt werden:
551
-
552
- ```ruby
553
- set :views, settings.root + '/templates'
554
- ```
555
-
556
- Es ist zu beachten, dass immer mit Symbolen auf Templates verwiesen
557
- werden muss, auch dann, wenn sie sich in einem Unterordner befinden:
558
-
559
- ```ruby
560
- haml :'unterverzeichnis/template'
561
- ```
562
-
563
- Wird einer Rendering-Methode ein String übergeben, wird dieser direkt
564
- gerendert.
565
-
566
- ### Direkte Templates
567
-
568
- ```ruby
569
- get '/' do
570
- haml '%div.title Hallo Welt'
571
- end
572
- ```
573
-
574
- Hier wird der String direkt gerendert.
575
-
576
- Optional kann `:path` und `:line` für einen genaueren Backtrace
577
- übergeben werden, wenn mit dem vorgegebenen String ein Pfad im
578
- Dateisystem oder eine Zeilennummer verbunden ist:
579
-
580
- ```ruby
581
- get '/' do
582
- haml '%div.title Hallo Welt', :path => 'examples/datei.haml', :line => 3
583
- end
584
- ```
585
-
586
- ### Verfügbare Templatesprachen
587
-
588
- Einige Sprachen haben mehrere Implementierungen. Um festzulegen, welche
589
- verwendet wird (und dann auch Thread-sicher ist), verwendet man am besten zu
590
- Beginn ein `'require'`:
591
-
592
- ```ruby
593
- require 'rdiscount' # oder require 'bluecloth'
594
- get('/') { markdown :index }
595
- ```
596
-
597
- #### Haml Templates
598
-
599
- <table>
600
- <tr>
601
- <td>Abhängigkeit</td>
602
- <td><a href="http://haml.info/">haml</a></td>
603
- </tr>
604
- <tr>
605
- <td>Dateierweiterung</td>
606
- <td><tt>.haml</tt></td>
607
- </tr>
608
- <tr>
609
- <td>Beispiel</td>
610
- <td><tt>haml :index, :format => :html5</tt></td>
611
- </tr>
612
- </table>
613
-
614
-
615
- #### Erb Templates
616
-
617
- <table>
618
- <tr>
619
- <td>Abhängigkeit</td>
620
- <td><a href="http://www.kuwata-lab.com/erubis/">erubis</a> oder erb
621
- (Standardbibliothek von Ruby)</td>
622
- </tr>
623
- <tr>
624
- <td>Dateierweiterungen</td>
625
- <td><tt>.erb</tt>, <tt>.rhtml</tt> oder <tt>.erubis</tt> (nur Erubis)</td>
626
- </tr>
627
- <tr>
628
- <td>Beispiel</td>
629
- <td><tt>erb :index</tt></td>
630
- </tr>
631
- </table>
632
-
633
-
634
- #### Builder Templates
635
-
636
- <table>
637
- <tr>
638
- <td>Abhängigkeit</td>
639
- <td><a href="https://github.com/jimweirich/builder">builder</a></td>
640
- </tr>
641
- <tr>
642
- <td>Dateierweiterung</td>
643
- <td><tt>.builder</tt></td>
644
- </tr>
645
- <tr>
646
- <td>Beispiel</td>
647
- <td><tt>builder { |xml| xml.em "Hallo" }</tt></td>
648
- </tr>
649
- </table>
650
-
651
- Nimmt ebenso einen Block für Inline-Templates entgegen (siehe Beispiel).
652
-
653
- #### Nokogiri Templates
654
-
655
- <table>
656
- <tr>
657
- <td>Abhängigkeit</td>
658
- <td><a href="http://www.nokogiri.org/">nokogiri</a></td>
659
- </tr>
660
- <tr>
661
- <td>Dateierweiterung</td>
662
- <td><tt>.nokogiri</tt></td>
663
- </tr>
664
- <tr>
665
- <td>Beispiel</td>
666
- <td><tt>nokogiri { |xml| xml.em "Hallo" }</tt></td>
667
- </tr>
668
- </table>
669
-
670
- Nimmt ebenso einen Block für Inline-Templates entgegen (siehe Beispiel).
671
-
672
- #### Sass Templates
673
-
674
- <table>
675
- <tr>
676
- <td>Abhängigkeit</td>
677
- <td><a href="http://sass-lang.com/">sass</a></td>
678
- </tr>
679
- <tr>
680
- <td>Dateierweiterung</td>
681
- <td><tt>.sass</tt></td>
682
- </tr>
683
- <tr>
684
- <td>Beispiel</td>
685
- <td><tt>sass :stylesheet, :style => :expanded</tt></td>
686
- </tr>
687
- </table>
688
-
689
-
690
- #### SCSS Templates
691
-
692
- <table>
693
- <tr>
694
- <td>Abhängigkeit</td>
695
- <td><a href="http://sass-lang.com/">sass</a></td>
696
- </tr>
697
- <tr>
698
- <td>Dateierweiterung</td>
699
- <td><tt>.scss</tt></td>
700
- </tr>
701
- <tr>
702
- <td>Beispiel</td>
703
- <td><tt>scss :stylesheet, :style => :expanded</tt></td>
704
- </tr>
705
- </table>
706
-
707
-
708
- #### Less Templates
709
-
710
- <table>
711
- <tr>
712
- <td>Abhängigkeit</td>
713
- <td><a href="http://lesscss.org/">less</a></td>
714
- </tr>
715
- <tr>
716
- <td>Dateierweiterung</td>
717
- <td><tt>.less</tt></td>
718
- </tr>
719
- <tr>
720
- <td>Beispiel</td>
721
- <td><tt>less :stylesheet</tt></td>
722
- </tr>
723
- </table>
724
-
725
-
726
- #### Liquid Templates
727
-
728
- <table>
729
- <tr>
730
- <td>Abhängigkeit</td>
731
- <td><a href="https://shopify.github.io/liquid/">liquid</a></td>
732
- </tr>
733
- <tr>
734
- <td>Dateierweiterung</td>
735
- <td><tt>.liquid</tt></td>
736
- </tr>
737
- <tr>
738
- <td>Beispiel</td>
739
- <td><tt>liquid :index, :locals => { :key => 'Wert' }</tt></td>
740
- </tr>
741
- </table>
742
-
743
- Da man aus dem Liquid-Template heraus keine Ruby-Methoden aufrufen kann
744
- (ausgenommen `yield`), wird man üblicherweise locals verwenden wollen, mit
745
- denen man Variablen weitergibt.
746
-
747
- #### Markdown Templates
748
-
749
- <table>
750
- <tr>
751
- <td>Abhängigkeit</td>
752
- <td>Eine der folgenden Bibliotheken:
753
- <a href="https://github.com/davidfstr/rdiscount" title="RDiscount">RDiscount</a>,
754
- <a href="https://github.com/vmg/redcarpet" title="RedCarpet">RedCarpet</a>,
755
- <a href="https://github.com/ged/bluecloth" title="bluecloth">BlueCloth</a>,
756
- <a href="http://kramdown.gettalong.org/" title="kramdown">kramdown</a> oder
757
- <a href="https://github.com/bhollis/maruku" title="maruku">maruku</a>
758
- </td>
759
- </tr>
760
- <tr>
761
- <td>Dateierweiterungen</td>
762
- <td><tt>.markdown</tt>, <tt>.mkd</tt> und <tt>.md</tt></td>
763
- </tr>
764
- <tr>
765
- <td>Beispiel</td>
766
- <td><tt>markdown :index, :layout_engine => :erb</tt></td>
767
- </tr>
768
- </table>
769
-
770
- Da man aus den Markdown-Templates heraus keine Ruby-Methoden aufrufen und auch
771
- keine locals verwenden kann, wird man Markdown üblicherweise in Kombination
772
- mit anderen Renderern verwenden wollen:
773
-
774
- ```ruby
775
- erb :overview, :locals => { :text => markdown(:einfuehrung) }
776
- ```
777
-
778
- Beachte, dass man die `markdown`-Methode auch aus anderen Templates heraus
779
- aufrufen kann:
780
-
781
- ```ruby
782
- %h1 Gruß von Haml!
783
- %p= markdown(:Grüße)
784
- ```
785
-
786
- Da man Ruby nicht von Markdown heraus aufrufen kann, können auch Layouts nicht
787
- in Markdown geschrieben werden. Es ist aber möglich, einen Renderer für die
788
- Templates zu verwenden und einen anderen für das Layout, indem die
789
- `:layout_engine`-Option verwendet wird.
790
-
791
- #### Textile Templates
792
-
793
- <table>
794
- <tr>
795
- <td>Abhängigkeit</td>
796
- <td><a href="http://redcloth.org/">RedCloth</a></td>
797
- </tr>
798
- <tr>
799
- <td>Dateierweiterung</td>
800
- <td><tt>.textile</tt></td>
801
- </tr>
802
- <tr>
803
- <td>Beispiel</td>
804
- <td><tt>textile :index, :layout_engine => :erb</tt></td>
805
- </tr>
806
- </table>
807
-
808
- Da man aus dem Textile-Template heraus keine Ruby-Methoden aufrufen und auch
809
- keine locals verwenden kann, wird man Textile üblicherweise in Kombination mit
810
- anderen Renderern verwenden wollen:
811
-
812
- ```ruby
813
- erb :overview, :locals => { :text => textile(:einfuehrung) }
814
- ```
815
-
816
- Beachte, dass man die `textile`-Methode auch aus anderen Templates heraus
817
- aufrufen kann:
818
-
819
- ```ruby
820
- %h1 Gruß von Haml!
821
- %p= textile(:Grüße)
822
- ```
823
-
824
- Da man Ruby nicht von Textile heraus aufrufen kann, können auch Layouts nicht
825
- in Textile geschrieben werden. Es ist aber möglich, einen Renderer für die
826
- Templates zu verwenden und einen anderen für das Layout, indem die
827
- `:layout_engine`-Option verwendet wird.
828
-
829
- #### RDoc Templates
830
-
831
- <table>
832
- <tr>
833
- <td>Abhängigkeit</td>
834
- <td><a href="http://rdoc.sourceforge.net/">rdoc</a></td>
835
- </tr>
836
- <tr>
837
- <td>Dateierweiterung</td>
838
- <td><tt>.rdoc</tt></td>
839
- </tr>
840
- <tr>
841
- <td>Beispiel</td>
842
- <td><tt>textile :README, :layout_engine => :erb</tt></td>
843
- </tr>
844
- </table>
845
-
846
- Da man aus dem RDoc-Template heraus keine Ruby-Methoden aufrufen und auch
847
- keine locals verwenden kann, wird man RDoc üblicherweise in Kombination mit
848
- anderen Renderern verwenden wollen:
849
-
850
- ```ruby
851
- erb :overview, :locals => { :text => rdoc(:einfuehrung) }
852
- ```
853
-
854
- Beachte, dass man die `rdoc`-Methode auch aus anderen Templates heraus
855
- aufrufen kann:
856
-
857
- ```ruby
858
- %h1 Gruß von Haml!
859
- %p= rdoc(:Grüße)
860
- ```
861
-
862
- Da man Ruby nicht von RDoc heraus aufrufen kann, können auch Layouts nicht in
863
- RDoc geschrieben werden. Es ist aber möglich, einen Renderer für die Templates
864
- zu verwenden und einen anderen für das Layout, indem die
865
- `:layout_engine`-Option verwendet wird.
866
-
867
- #### AsciiDoc Templates
868
-
869
- <table>
870
- <tr>
871
- <td>Abhängigkeit</td>
872
- <td><a href="http://asciidoctor.org/" title="Asciidoctor">Asciidoctor</a></td>
873
- </tr>
874
- <tr>
875
- <td>Dateierweiterungen</td>
876
- <td><tt>.asciidoc</tt>, <tt>.adoc</tt> und <tt>.ad</tt></td>
877
- </tr>
878
- <tr>
879
- <td>Beispiel</td>
880
- <td><tt>asciidoc :README, :layout_engine => :erb</tt></td>
881
- </tr>
882
- </table>
883
-
884
- Da man aus dem AsciiDoc-Template heraus keine Ruby-Methoden aufrufen kann
885
- (ausgenommen `yield`), wird man üblicherweise locals verwenden wollen, mit
886
- denen man Variablen weitergibt.
887
-
888
- #### Radius Templates
889
-
890
- <table>
891
- <tr>
892
- <td>Abhängigkeit</td>
893
- <td><a href="https://github.com/jlong/radius">radius</a></td>
894
- </tr>
895
- <tr>
896
- <td>Dateierweiterung</td>
897
- <td><tt>.radius</tt></td>
898
- </tr>
899
- <tr>
900
- <td>Beispiel</td>
901
- <td><tt>radius :index, :locals => { :key => 'Wert' }</tt></td>
902
- </tr>
903
- </table>
904
-
905
- Da man aus dem Radius-Template heraus keine Ruby-Methoden aufrufen kann, wird
906
- man üblicherweise locals verwenden wollen, mit denen man Variablen weitergibt.
907
-
908
- #### Markaby Templates
909
-
910
- <table>
911
- <tr>
912
- <td>Abhängigkeit</td>
913
- <td><a href="http://markaby.github.io/">markaby</a></td>
914
- </tr>
915
- <tr>
916
- <td>Dateierweiterung</td>
917
- <td><tt>.mab</tt></td>
918
- </tr>
919
- <tr>
920
- <td>Beispiel</td>
921
- <td><tt>markaby { h1 "Willkommen!" }</tt></td>
922
- </tr>
923
- </table>
924
-
925
- Nimmt ebenso einen Block für Inline-Templates entgegen (siehe Beispiel).
926
-
927
- #### RABL Templates
928
-
929
- <table>
930
- <tr>
931
- <td>Abhängigkeit</td>
932
- <td><a href="https://github.com/nesquena/rabl">rabl</a></td>
933
- </tr>
934
- <tr>
935
- <td>Dateierweiterung</td>
936
- <td><tt>.rabl</tt></td>
937
- </tr>
938
- <tr>
939
- <td>Beispiel</td>
940
- <td><tt>rabl :index</tt></td>
941
- </tr>
942
- </table>
943
-
944
- #### Slim Templates
945
-
946
- <table>
947
- <tr>
948
- <td>Abhängigkeit</td>
949
- <td><a href="http://slim-lang.com/">slim</a></td>
950
- </tr>
951
- <tr>
952
- <td>Dateierweiterung</td>
953
- <td><tt>.slim</tt></td>
954
- </tr>
955
- <tr>
956
- <td>Beispiel</td>
957
- <td><tt>slim :index</tt></td>
958
- </tr>
959
- </table>
960
-
961
- #### Creole Templates
962
-
963
- <table>
964
- <tr>
965
- <td>Abhängigkeit</td>
966
- <td><a href="https://github.com/minad/creole">creole</a></td>
967
- </tr>
968
- <tr>
969
- <td>Dateierweiterung</td>
970
- <td><tt>.creole</tt></td>
971
- </tr>
972
- <tr>
973
- <td>Beispiel</td>
974
- <td><tt>creole :wiki, :layout_engine => :erb</tt></td>
975
- </tr>
976
- </table>
977
-
978
- Da man aus dem Creole-Template heraus keine Ruby-Methoden aufrufen und auch
979
- keine locals verwenden kann, wird man Creole üblicherweise in Kombination mit
980
- anderen Renderern verwenden wollen:
981
-
982
- ```ruby
983
- erb :overview, :locals => { :text => creole(:einfuehrung) }
984
- ```
985
-
986
- Beachte, dass man die `creole`-Methode auch aus anderen Templates heraus
987
- aufrufen kann:
988
-
989
- ```ruby
990
- %h1 Gruß von Haml!
991
- %p= creole(:Grüße)
992
- ```
993
-
994
- Da man Ruby nicht von Creole heraus aufrufen kann, können auch Layouts
995
- nicht in Creole geschrieben werden. Es ist aber möglich, einen Renderer
996
- für die Templates zu verwenden und einen anderen für das Layout, indem
997
- die `:layout_engine`-Option verwendet wird.
998
-
999
- #### MediaWiki Templates
1000
-
1001
- <table>
1002
- <tr>
1003
- <td>Abhängigkeit</td>
1004
- <td><a href="https://github.com/nricciar/wikicloth" title="WikiCloth">WikiCloth</a></td>
1005
- </tr>
1006
- <tr>
1007
- <td>Dateierweiterungen</td>
1008
- <td><tt>.mediawiki</tt> und <tt>.mw</tt></td>
1009
- </tr>
1010
- <tr>
1011
- <td>Beispiel</td>
1012
- <td><tt>mediawiki :wiki, :layout_engine => :erb</tt></td>
1013
- </tr>
1014
- </table>
1015
-
1016
- Da man aus dem Mediawiki-Template heraus keine Ruby-Methoden aufrufen
1017
- und auch keine locals verwenden kann, wird man Mediawiki üblicherweise
1018
- in Kombination mit anderen Renderern verwenden wollen:
1019
-
1020
- ```ruby
1021
- erb :overview, :locals => { :text => mediawiki(:introduction) }
1022
- ```
1023
-
1024
- Beachte: Man kann die `mediawiki`-Methode auch aus anderen Templates
1025
- heraus aufrufen:
1026
-
1027
- ```ruby
1028
- %h1 Grüße von Haml!
1029
- %p= mediawiki(:greetings)
1030
- ```
1031
-
1032
- Da man Ruby nicht von MediaWiki heraus aufrufen kann, können auch
1033
- Layouts nicht in MediaWiki geschrieben werden. Es ist aber möglich,
1034
- einen Renderer für die Templates zu verwenden und einen anderen für das
1035
- Layout, indem die `:layout_engine`-Option verwendet wird.
1036
-
1037
- #### CoffeeScript Templates
1038
-
1039
- <table>
1040
- <tr>
1041
- <td>Abhängigkeit</td>
1042
- <td><a href="https://github.com/josh/ruby-coffee-script">coffee-script</a>
1043
- und eine <a href="https://github.com/sstephenson/execjs/blob/master/README.md#readme">Möglichkeit JavaScript auszuführen</a>.
1044
- </td>
1045
- </tr>
1046
- <td>Dateierweiterung</td>
1047
- <td><tt>.coffee</tt></td>
1048
- </tr>
1049
- <tr>
1050
- <td>Beispiel</td>
1051
- <td><tt>coffee :index</tt></td>
1052
- </tr>
1053
- </table>
1054
-
1055
- #### Stylus Templates
1056
-
1057
- <table>
1058
- <tr>
1059
- <td>Abhängigkeit</td>
1060
- <td>
1061
- <a href="https://github.com/forgecrafted/ruby-stylus" title="Ruby Stylus">
1062
- Stylus
1063
- </a> und eine Möglichkeit
1064
- <a href="https://github.com/sstephenson/execjs/blob/master/README.md#readme" title="ExecJS">
1065
- JavaScript auszuführen
1066
- </a>.
1067
- </td>
1068
- </tr>
1069
- <tr>
1070
- <td>Dateierweiterung</td>
1071
- <td><tt>.styl</tt></td>
1072
- </tr>
1073
- <tr>
1074
- <td>Beispiel</td>
1075
- <td><tt>stylus :index</tt></td>
1076
- </tr>
1077
- </table>
1078
-
1079
- Um Stylus-Templates ausführen zu können, müssen `stylus` und `stylus/tilt`
1080
- zuerst geladen werden:
1081
-
1082
- ```ruby
1083
- require 'sinatra'
1084
- require 'stylus'
1085
- require 'stylus/tilt'
1086
-
1087
- get '/' do
1088
- stylus :example
1089
- end
1090
- ```
1091
-
1092
- #### Yajl Templates
1093
-
1094
- <table>
1095
- <tr>
1096
- <td>Abhängigkeit</td>
1097
- <td><a href="https://github.com/brianmario/yajl-ruby" title="yajl-ruby">yajl-ruby</a></td>
1098
- </tr>
1099
- <tr>
1100
- <td>Dateierweiterung</td>
1101
- <td><tt>.yajl</tt></td>
1102
- </tr>
1103
- <tr>
1104
- <td>Beispiel</td>
1105
- <td>
1106
- <tt>
1107
- yajl :index,
1108
- :locals => { :key => 'qux' },
1109
- :callback => 'present',
1110
- :variable => 'resource'
1111
- </tt>
1112
- </td>
1113
- </tr>
1114
- </table>
1115
-
1116
- Die Template-Quelle wird als Ruby-String evaluiert. Die daraus resultierende
1117
- Json-Variable wird mit Hilfe von `#to_json` umgewandelt:
1118
-
1119
- ```ruby
1120
- json = { :foo => 'bar' }
1121
- json[:baz] = key
1122
- ```
1123
-
1124
- Die `:callback` und `:variable` Optionen können mit dem gerenderten Objekt
1125
- verwendet werden:
1126
-
1127
- ```javascript
1128
- var resource = {"foo":"bar","baz":"qux"};
1129
- present(resource);
1130
- ```
1131
-
1132
- #### WLang Templates
1133
-
1134
- <table>
1135
- <tr>
1136
- <td>Abhängigkeit</td>
1137
- <td><a href="https://github.com/blambeau/wlang/">wlang</a></td>
1138
- </tr>
1139
- <tr>
1140
- <td>Dateierweiterung</td>
1141
- <td><tt>.wlang</tt></td>
1142
- </tr>
1143
- <tr>
1144
- <td>Beispiel</td>
1145
- <td><tt>wlang :index, :locals => { :key => 'value' }</tt></td>
1146
- </tr>
1147
- </table>
1148
-
1149
- Ruby-Methoden in Wlang aufzurufen entspricht nicht den idiomatischen Vorgaben
1150
- von Wlang, es bietet sich deshalb an, `:locals` zu verwenden. Layouts, die
1151
- Wlang und `yield` verwenden, werden aber trotzdem unterstützt.
1152
-
1153
- Rendert den eingebetteten Template-String.
1154
-
1155
- ### Auf Variablen in Templates zugreifen
1156
-
1157
- Templates werden in demselben Kontext ausgeführt wie Routen. Instanzvariablen
1158
- in Routen sind auch direkt im Template verfügbar:
1159
-
1160
- ```ruby
1161
- get '/:id' do
1162
- @foo = Foo.find(params['id'])
1163
- haml '%h1= @foo.name'
1164
- end
1165
- ```
1166
-
1167
- Oder durch einen expliziten Hash von lokalen Variablen:
1168
-
1169
- ```ruby
1170
- get '/:id' do
1171
- foo = Foo.find(params['id'])
1172
- haml '%h1= bar.name', :locals => { :bar => foo }
1173
- end
1174
- ```
1175
-
1176
- Dies wird typischerweise bei Verwendung von Subtemplates (partials) in anderen
1177
- Templates eingesetzt.
1178
-
1179
- ### Templates mit `yield` und verschachtelte Layouts
1180
-
1181
- Ein Layout ist üblicherweise ein Template, das ein `yield` aufruft. Ein
1182
- solches Template kann entweder wie oben beschrieben über die `:template`
1183
- Option verwendet werden oder mit einem Block gerendert werden:
1184
-
1185
- ```ruby
1186
- erb :post, :layout => false do
1187
- erb :index
1188
- end
1189
- ```
1190
-
1191
- Dieser Code entspricht weitestgehend `erb :index, :layout => :post`.
1192
-
1193
- Blöcke an Render-Methoden weiterzugeben ist besonders bei verschachtelten
1194
- Layouts hilfreich:
1195
-
1196
- ```ruby
1197
- erb :main_layout, :layout => false do
1198
- erb :admin_layout do
1199
- erb :user
1200
- end
1201
- end
1202
- ```
1203
-
1204
- Der gleiche Effekt kann auch mit weniger Code erreicht werden:
1205
-
1206
- ```ruby
1207
- erb :admin_layout, :layout => :main_layout do
1208
- erb :user
1209
- end
1210
- ```
1211
-
1212
- Zur Zeit nehmen folgende Renderer Blöcke an: `erb`, `haml`, `liquid`, `slim `
1213
- und `wlang`.
1214
-
1215
- Das gleich gilt auch für die allgemeine `render` Methode.
1216
-
1217
- ### Inline-Templates
1218
-
1219
- Templates können auch am Ende der Datei definiert werden:
1220
-
1221
- ```ruby
1222
- require 'sinatra'
1223
-
1224
- get '/' do
1225
- haml :index
1226
- end
1227
-
1228
- __END__
1229
-
1230
- @@ layout
1231
- %html
1232
- = yield
1233
-
1234
- @@ index
1235
- %div.title Hallo Welt
1236
- ```
1237
-
1238
- Anmerkung: Inline-Templates, die in der Datei definiert sind, die `require
1239
- 'sinatra'` aufruft, werden automatisch geladen. Um andere Inline-Templates in
1240
- weiteren Dateien aufzurufen, muss explizit `enable :inline_templates`
1241
- verwendet werden.
1242
-
1243
- ### Benannte Templates
1244
-
1245
- Templates können auch mit der Top-Level `template`-Methode definiert werden:
1246
-
1247
- ```ruby
1248
- template :layout do
1249
- "%html\n =yield\n"
1250
- end
1251
-
1252
- template :index do
1253
- '%div.title Hallo Welt!'
1254
- end
1255
-
1256
- get '/' do
1257
- haml :index
1258
- end
1259
- ```
1260
-
1261
- Wenn ein Template mit dem Namen "layout" existiert, wird es bei jedem Aufruf
1262
- verwendet. Durch `:layout => false` kann das Ausführen individuell nach Route
1263
- verhindert werden, oder generell für ein Template, z.B. Haml via:
1264
- `set :haml, :layout => false`:
1265
-
1266
- ```ruby
1267
- get '/' do
1268
- haml :index, :layout => !request.xhr?
1269
- # !request.xhr? prüft, ob es sich um einen asynchronen Request handelt.
1270
- # wenn nicht, dann verwende ein Layout (negiert durch !)
1271
- end
1272
- ```
1273
-
1274
- ### Dateiendungen zuordnen
1275
-
1276
- Um eine Dateiendung einer Template-Engine zuzuordnen, kann `Tilt.register`
1277
- genutzt werden. Wenn etwa die Dateiendung `tt` für Textile-Templates genutzt
1278
- werden soll, lässt sich dies wie folgt bewerkstelligen:
1279
-
1280
- ```ruby
1281
- Tilt.register :tt, Tilt[:textile]
1282
- ```
1283
-
1284
- ### Eine eigene Template-Engine hinzufügen
1285
-
1286
- Zu allererst muss die Engine bei Tilt registriert und danach eine
1287
- Rendering-Methode erstellt werden:
1288
-
1289
- ```ruby
1290
- Tilt.register :mtt, MeineTolleTemplateEngine
1291
-
1292
- helpers do
1293
- def mtt(*args) render(:mtt, *args) end
1294
- end
1295
-
1296
- get '/' do
1297
- mtt :index
1298
- end
1299
- ```
1300
-
1301
- Dieser Code rendert `./views/application.mtt`. Siehe
1302
- [github.com/rtomayko/tilt](https://github.com/rtomayko/tilt), um mehr über
1303
- Tilt zu erfahren.
1304
-
1305
- ### Eigene Methoden zum Aufsuchen von Templates verwenden
1306
-
1307
- Um einen eigenen Mechanismus zum Aufsuchen von Templates zu
1308
- implementieren, muss `#find_template` definiert werden:
1309
-
1310
- ```ruby
1311
- configure do
1312
- set :views [ './views/a', './views/b' ]
1313
- end
1314
-
1315
- def find_template(views, name, engine, &block)
1316
- Array(views).each do |v|
1317
- super(v, name, engine, &block)
1318
- end
1319
- end
1320
- ```
1321
-
1322
- ## Filter
1323
-
1324
- Before-Filter werden vor jedem Request in demselben Kontext, wie danach die
1325
- Routen, ausgeführt. So können etwa Request und Antwort geändert werden.
1326
- Gesetzte Instanzvariablen in Filtern können in Routen und Templates verwendet
1327
- werden:
1328
-
1329
- ```ruby
1330
- before do
1331
- @note = 'Hi!'
1332
- request.path_info = '/foo/bar/baz'
1333
- end
1334
-
1335
- get '/foo/*' do
1336
- @note #=> 'Hi!'
1337
- params['splat'] #=> 'bar/baz'
1338
- end
1339
- ```
1340
-
1341
- After-Filter werden nach jedem Request in demselben Kontext ausgeführt und
1342
- können ebenfalls Request und Antwort ändern. In Before-Filtern gesetzte
1343
- Instanzvariablen können in After-Filtern verwendet werden:
1344
-
1345
- ```ruby
1346
- after do
1347
- puts response.status
1348
- end
1349
- ```
1350
-
1351
- Achtung: Wenn statt der body-Methode ein einfacher String verwendet
1352
- wird, ist der Response-body im after-Filter noch nicht verfügbar, da
1353
- er erst nach dem Durchlaufen des after-Filters erzeugt wird.
1354
-
1355
- Filter können optional auch mit einem Muster ausgestattet werden, das auf den
1356
- Request-Pfad passen muss, damit der Filter ausgeführt wird:
1357
-
1358
- ```ruby
1359
- before '/protected/*' do
1360
- authenticate!
1361
- end
1362
-
1363
- after '/create/:slug' do |slug|
1364
- session[:last_slug] = slug
1365
- end
1366
- ```
1367
-
1368
- Ähnlich wie Routen können Filter auch mit weiteren Bedingungen eingeschränkt
1369
- werden:
1370
-
1371
- ```ruby
1372
- before :agent => /Songbird/ do
1373
- # ...
1374
- end
1375
-
1376
- after '/blog/*', :host_name => 'example.com' do
1377
- # ...
1378
- end
1379
- ```
1380
-
1381
- ## Helfer
1382
-
1383
- Durch die Top-Level `helpers`-Methode werden sogenannte Helfer-Methoden
1384
- definiert, die in Routen und Templates verwendet werden können:
1385
-
1386
- ```ruby
1387
- helpers do
1388
- def bar(name)
1389
- "#{name}bar"
1390
- end
1391
- end
1392
-
1393
- get '/:name' do
1394
- bar(params['name'])
1395
- end
1396
- ```
1397
-
1398
- Ebenso können Helfer auch in einem eigenen Modul definiert werden:
1399
-
1400
- ```ruby
1401
- module FooUtils
1402
- def foo(name) "#{name}foo" end
1403
- end
1404
-
1405
- module BarUtils
1406
- def bar(name) "#{name}bar" end
1407
- end
1408
-
1409
- helpers FooUtils, BarUtils
1410
- ```
1411
-
1412
- Das Ergebnis ist das gleiche, wie beim Einbinden in die
1413
- Anwendungs-Klasse.
1414
-
1415
- ### Sessions verwenden
1416
- Sessions werden verwendet, um Zustände zwischen den Requests zu speichern.
1417
- Sind sie aktiviert, kann ein Session-Hash je Benutzer-Session verwendet
1418
- werden:
1419
-
1420
- ```ruby
1421
- enable :sessions
1422
-
1423
- get '/' do
1424
- "value = " << session[:value].inspect
1425
- end
1426
-
1427
- get '/:value' do
1428
- session[:value] = params['value']
1429
- end
1430
- ```
1431
-
1432
- Um die Sicherheit zu erhöhen, werden Daten mit einem geheimen
1433
- Sitzungsschlüssel unter Verwendung von `HMAC-SHA1` in einem Cookie signiert.
1434
- Der Sitzungsschlüssel sollte optimalerweise ein kryptografisch zufällig
1435
- erzeugter Wert mit angemessener Länge sein, für den `HMAC-SHA1` größer
1436
- oder gleich 65 Bytes ist (256 Bits, 64 Hex-Zeichen). Es wird empfohlen,
1437
- keinen Schlüssel zu verwenden, dessen Zufälligkeit weniger als 32 Bytes
1438
- entspricht (also 256 Bits, 64 Hex-Zeichen). Es ist deshalb **wirklich
1439
- wichtig**, dass nicht einfach irgendetwas als Schlüssel verwendet wird,
1440
- sondern ein sicherer Zufallsgenerator die Zeichenkette erstellt. Menschen sind
1441
- nicht besonders gut darin, zufällige Zeichenfolgen zu erstellen.
1442
-
1443
- Sinatra generiert automatisch einen zufälligen, 32 Byte langen
1444
- Schlüssel. Da jedoch bei jedem Neustart der Schlüssel ebenfalls neu generiert
1445
- wird, ist es sinnvoll einen eigenen Schlüssel festzulegen, damit er über alle
1446
- Anwendungsinstanzen hinweg geteilt werden kann.
1447
-
1448
- Aus praktikablen und Sicherheitsgründen wird
1449
- [empfohlen](https://12factor.net/config), dass ein sicherer Zufallswert
1450
- erzeugt und in einer Umgebungsvariable abgelegt wird, damit alle
1451
- Anwendungsinstanzen darauf zugreifen können. Dieser Sitzungsschlüssel
1452
- sollte in regelmäßigen Abständen erneuert werden. Zum Erzeugen von 64
1453
- Byte starken Schlüsseln sind hier ein paar Beispiele vorgestellt:
1454
-
1455
- **Sitzungsschlüssel erzeugen**
1456
-
1457
- ```text
1458
- $ ruby -e "require 'securerandom'; puts SecureRandom.hex(64)"
1459
- 99ae8afi...usw...ec0f262ac
1460
- ```
1461
-
1462
- **Sitzungsschlüssel erzeugen (Bonuspunkte)**
1463
-
1464
- Um den systemweiten Zufallszahlengenerator zu verwenden, kann das
1465
- [sysrandom gem](https://github.com/cryptosphere/sysrandom) installiert
1466
- werden, anstelle von Zufallszahlen aus dem Userspace, auf die MRI zur
1467
- Zeit standardmäßig zugreift:
1468
-
1469
- ```text
1470
- $ gem install sysrandom
1471
- Building native extensions. This could take a while...
1472
- Successfully installed sysrandom-1.x
1473
- 1 gem installed
1474
-
1475
- $ ruby -e "require 'sysrandom/securerandom'; puts SecureRandom.hex(64)"
1476
- 99ae8af...snip...ec0f262ac
1477
- ```
1478
-
1479
- **Sitzungsschlüssel-Umgebungsvariable**
1480
-
1481
- Wird eine `SESSION_SECRET`-Umgebungsvariable persistent gesetzt, kann
1482
- Sinatra darauf zugreifen. Da die folgende Methode von System zu System
1483
- variieren kann, ist dies als Beispiel zu verstehen:
1484
-
1485
- ```bash
1486
- $ echo "export SESSION_SECRET=99ae8af...etc...ec0f262ac" >> ~/.bashrc
1487
- ```
1488
-
1489
- **Anwendungseinstellung für Sitzungsschlüssel**
1490
-
1491
- Die Anwendung sollte unabhängig von der `SESSION_SECRET`-Umgebungsvariable
1492
- auf einen sicheren zufälligen Schlüssel zurückgreifen.
1493
-
1494
- Auch hier sollte das
1495
- [sysrandom gem](https://github.com/cryptosphere/sysrandom) verwendet
1496
- werden:
1497
-
1498
- ```ruby
1499
- require 'securerandom'
1500
- # -or- require 'sysrandom/securerandom'
1501
- set :session_secret, ENV.fetch('SESSION_SECRET') { SecureRandom.hex(64) }
1502
- ```
1503
-
1504
- #### Sitzungseinstellungen
1505
-
1506
- Im Options-Hash können weitere Einstellungen abgelegt werden:
1507
-
1508
- ```ruby
1509
- set :sessions, :domain => 'foo.com'
1510
- ```
1511
-
1512
- Um Sitzungsdaten über mehrere Anwendungen und Subdomains hinweg zu
1513
- teilen, muss die Domain mit einem `*.*` vor der Domain ausgestattet
1514
- werden:
1515
-
1516
- ```ruby
1517
- set :sessions, :domain => '.foo.com'
1518
- ```
1519
-
1520
- #### Eigene Sitzungs-Middleware auswählen
1521
-
1522
- Beachte, dass `enable :sessions` alle Daten in einem Cookie speichert. Unter
1523
- Umständen kann dies negative Effekte haben, z.B. verursachen viele Daten
1524
- höheren, teilweise überflüssigen Traffic. Es kann daher eine beliebige
1525
- Rack-Session Middleware verwendet werden. Folgende Methoden stehen zur
1526
- Verfügung:
1527
-
1528
- ```ruby
1529
- enable :sessions
1530
- set :session_store, Rack::Session::Pool
1531
- ```
1532
-
1533
- Oder Sitzungen werden mit einem Options-Hash ausgestattet:
1534
-
1535
- ```ruby
1536
- set :sessions, :expire_after => 2592000
1537
- set :session_store, Rack::Session::Pool
1538
- ```
1539
-
1540
- Eine weitere Methode ist der Verzicht auf `enable :session` und
1541
- stattdessen die Verwendung einer beliebigen anderen Middleware.
1542
-
1543
- Dabei ist jedoch zu beachten, dass der reguläre sitzungsbasierte
1544
- Sicherungsmechanismus **nicht automatisch aktiviert wird**.
1545
-
1546
- Die dazu benötigte Rack-Middleware muss explizit eingebunden werden:
1547
-
1548
- ```ruby
1549
- use Rack::Session::Pool, :expire_after => 2592000
1550
- use Rack::Protection::RemoteToken
1551
- use Rack::Protection::SessionHijacking
1552
- ```
1553
-
1554
- Mehr dazu unter [Einstellung des Angiffsschutzes](https://github.com/sinatra/sinatra/blob/master/README.de.md#einstellung-des-angriffsschutzes).
1555
-
1556
- ### Anhalten
1557
-
1558
- Zum sofortigen Stoppen eines Request in einem Filter oder einer Route:
1559
-
1560
- ```ruby
1561
- halt
1562
- ```
1563
-
1564
- Der Status kann beim Stoppen mit angegeben werden:
1565
-
1566
- ```ruby
1567
- halt 410
1568
- ```
1569
-
1570
- Oder auch den Response-Body:
1571
-
1572
- ```ruby
1573
- halt 'Hier steht der Body'
1574
- ```
1575
-
1576
- Oder beides:
1577
-
1578
- ```ruby
1579
- halt 401, 'verschwinde!'
1580
- ```
1581
-
1582
- Sogar mit Headern:
1583
-
1584
- ```ruby
1585
- halt 402, {'Content-Type' => 'text/plain'}, 'Rache'
1586
- ```
1587
-
1588
- Natürlich ist es auch möglich, ein Template mit `halt` zu verwenden:
1589
-
1590
- ```ruby
1591
- halt erb(:error)
1592
- ```
1593
-
1594
- ### Weiterspringen
1595
-
1596
- Eine Route kann mittels `pass` zu der nächsten passenden Route springen:
1597
-
1598
- ```ruby
1599
- get '/raten/:wer' do
1600
- pass unless params['wer'] == 'Frank'
1601
- 'Du hast mich!'
1602
- end
1603
-
1604
- get '/raten/*' do
1605
- 'Du hast mich nicht!'
1606
- end
1607
- ```
1608
-
1609
- Der Block wird sofort verlassen und es wird nach der nächsten treffenden Route
1610
- gesucht. Ein 404-Fehler wird zurückgegeben, wenn kein treffendes Routen-Muster
1611
- gefunden wird.
1612
-
1613
- ### Eine andere Route ansteuern
1614
-
1615
- Wenn nicht zu einer anderen Route gesprungen werden soll, sondern nur das
1616
- Ergebnis einer anderen Route gefordert wird, kann `call` für einen internen
1617
- Request verwendet werden:
1618
-
1619
- ```ruby
1620
- get '/foo' do
1621
- status, headers, body = call env.merge("PATH_INFO" => '/bar')
1622
- [status, headers, body.map(&:upcase)]
1623
- end
1624
-
1625
- get '/bar' do
1626
- "bar"
1627
- end
1628
- ```
1629
-
1630
- Beachte, dass in dem oben angegeben Beispiel die Performance erheblich erhöht
1631
- werden kann, wenn `"bar"` in eine Helfer-Methode umgewandelt wird, auf die
1632
- `/foo` und `/bar` zugreifen können.
1633
-
1634
- Wenn der Request innerhalb derselben Applikations-Instanz aufgerufen und keine
1635
- Kopie der Instanz erzeugt werden soll, kann `call!` anstelle von `call`
1636
- verwendet werden.
1637
-
1638
- Weitere Informationen zu `call` finden sich in den Rack-Spezifikationen.
1639
-
1640
- ### Body, Status-Code und Header setzen
1641
-
1642
- Es ist möglich und empfohlen, den Status-Code sowie den Response-Body mit
1643
- einem Returnwert in der Route zu setzen. In manchen Situationen kann es
1644
- jedoch sein, dass der Body an anderer Stelle während der Ausführung gesetzt
1645
- werden soll. Dafür kann man die Helfer-Methode `body` einsetzen. Ist sie
1646
- gesetzt, kann sie zu einem späteren Zeitpunkt aufgerufen werden:
1647
-
1648
- ```ruby
1649
- get '/foo' do
1650
- body "bar"
1651
- end
1652
-
1653
- after do
1654
- puts body
1655
- end
1656
- ```
1657
-
1658
- Ebenso ist es möglich, einen Block an `body` weiterzureichen, der dann vom
1659
- Rack-Handler ausgeführt wird (lässt sich z.B. zur Umsetzung von Streaming
1660
- einsetzen, siehe auch "Rückgabewerte").
1661
-
1662
- Vergleichbar mit `body` lassen sich auch Status-Code und Header setzen:
1663
-
1664
- ```ruby
1665
- get '/foo' do
1666
- status 418
1667
- headers \
1668
- "Allow" => "BREW, POST, GET, PROPFIND, WHEN",
1669
- "Refresh" => "Refresh: 20; http://www.ietf.org/rfc/rfc2324.txt"
1670
- halt "Ich bin ein Teekesselchen"
1671
- end
1672
- ```
1673
-
1674
- Genau wie bei `body` liest ein Aufrufen von `headers` oder `status` ohne
1675
- Argumente den aktuellen Wert aus.
1676
-
1677
- ### Response-Streams
1678
-
1679
- In manchen Situationen sollen Daten bereits an den Client zurückgeschickt
1680
- werden, bevor ein vollständiger Response bereit steht. Manchmal will man die
1681
- Verbindung auch erst dann beenden und Daten so lange an den Client
1682
- zurückschicken, bis er die Verbindung abbricht. Für diese Fälle gibt es die
1683
- `stream`-Helfer-Methode, die es einem erspart, eigene Lösungen zu schreiben:
1684
-
1685
- ```ruby
1686
- get '/' do
1687
- stream do |out|
1688
- out << "Das ist ja mal wieder fanta -\n"
1689
- sleep 0.5
1690
- out << " (bitte warten …) \n"
1691
- sleep 1
1692
- out << "- stisch!\n"
1693
- end
1694
- end
1695
- ```
1696
-
1697
- Damit lassen sich Streaming-APIs realisieren, sog.
1698
- [Server Sent Events](https://w3c.github.io/eventsource/), die als Basis für
1699
- [WebSockets](https://en.wikipedia.org/wiki/WebSocket) dienen. Ebenso können
1700
- sie verwendet werden, um den Durchsatz zu erhöhen, wenn ein Teil der Daten von
1701
- langsamen Ressourcen abhängig ist.
1702
-
1703
- Es ist zu beachten, dass das Verhalten beim Streaming, insbesondere die Anzahl
1704
- nebenläufiger Anfragen, stark davon abhängt, welcher Webserver für die
1705
- Applikation verwendet wird. Einige Server unterstützen
1706
- Streaming nicht oder nur teilweise. Sollte der Server Streaming nicht
1707
- unterstützen, wird ein vollständiger Response-Body zurückgeschickt, sobald der
1708
- an `stream` weitergegebene Block abgearbeitet ist. Mit Shotgun funktioniert
1709
- Streaming z.B. überhaupt nicht.
1710
-
1711
- Ist der optionale Parameter `keep_open` aktiviert, wird beim gestreamten
1712
- Objekt `close` nicht aufgerufen und es ist einem überlassen dies an einem
1713
- beliebigen späteren Zeitpunkt nachholen. Die Funktion ist jedoch nur bei
1714
- Event-gesteuerten Serven wie Thin oder Rainbows möglich, andere Server werden
1715
- trotzdem den Stream beenden:
1716
-
1717
- ```ruby
1718
- # Durchgehende Anfrage (long polling)
1719
-
1720
- set :server, :thin
1721
- connections = []
1722
-
1723
- get '/subscribe' do
1724
- # Client-Registrierung beim Server, damit Events mitgeteilt werden können
1725
- stream(:keep_open) do |out|
1726
- connections << out
1727
- # tote Verbindungen entfernen
1728
- connections.reject!(&:closed?)
1729
- end
1730
- end
1731
-
1732
- post '/:message' do
1733
- connections.each do |out|
1734
- # Den Client über eine neue Nachricht in Kenntnis setzen
1735
- # notify client that a new message has arrived
1736
- out << params['message'] << "\n"
1737
-
1738
- # Den Client zur erneuten Verbindung auffordern
1739
- out.close
1740
- end
1741
-
1742
- # Rückmeldung
1743
- "Mitteiling erhalten"
1744
- end
1745
- ```
1746
-
1747
- Es ist ebenfalls möglich, dass der Client die Verbindung schließt, während in
1748
- den Socket geschrieben wird. Deshalb ist es sinnvoll, vor einem
1749
- Schreibvorgang `out.closed?` zu prüfen.
1750
-
1751
- ### Logger
1752
-
1753
- Im Geltungsbereich eines Request stellt die `logger` Helfer-Methode eine
1754
- `Logger` Instanz zur Verfügung:
1755
-
1756
- ```ruby
1757
- get '/' do
1758
- logger.info "es passiert gerade etwas"
1759
- # ...
1760
- end
1761
- ```
1762
-
1763
- Der Logger übernimmt dabei automatisch alle im Rack-Handler eingestellten
1764
- Log-Vorgaben. Ist Loggen ausgeschaltet, gibt die Methode ein Leerobjekt
1765
- zurück. In den Routen und Filtern muss man sich also nicht weiter darum
1766
- kümmern.
1767
-
1768
- Beachte, dass das Loggen standardmäßig nur für `Sinatra::Application`
1769
- voreingestellt ist. Wird über `Sinatra::Base` vererbt, muss es erst aktiviert
1770
- werden:
1771
-
1772
- ```ruby
1773
- class MyApp < Sinatra::Base
1774
- configure :production, :development do
1775
- enable :logging
1776
- end
1777
- end
1778
- ```
1779
-
1780
- Damit auch keine Middleware das Logging aktivieren kann, muss die `logging`
1781
- Einstellung auf `nil` gesetzt werden. Das heißt aber auch, dass `logger` in
1782
- diesem Fall `nil` zurückgeben wird. Üblicherweise wird das eingesetzt, wenn
1783
- ein eigener Logger eingerichtet werden soll. Sinatra wird dann verwenden, was
1784
- in `env['rack.logger']` eingetragen ist.
1785
-
1786
- ### Mime-Types
1787
-
1788
- Wenn `send_file` oder statische Dateien verwendet werden, kann es vorkommen,
1789
- dass Sinatra den Mime-Typ nicht kennt. Registriert wird dieser mit `mime_type`
1790
- per Dateiendung:
1791
-
1792
- ```ruby
1793
- configure do
1794
- mime_type :foo, 'text/foo'
1795
- end
1796
- ```
1797
-
1798
- Es kann aber auch der `content_type`-Helfer verwendet werden:
1799
-
1800
- ```ruby
1801
- get '/' do
1802
- content_type :foo
1803
- "foo foo foo"
1804
- end
1805
- ```
1806
-
1807
- ### URLs generieren
1808
-
1809
- Zum Generieren von URLs sollte die `url`-Helfer-Methode genutzen werden, so
1810
- z.B. beim Einsatz von Haml:
1811
-
1812
- ```ruby
1813
- %a{:href => url('/foo')} foo
1814
- ```
1815
-
1816
- Soweit vorhanden, wird Rücksicht auf Proxys und Rack-Router genommen.
1817
-
1818
- Diese Methode ist ebenso über das Alias `to` zu erreichen (siehe Beispiel
1819
- unten).
1820
-
1821
- ### Browser-Umleitung
1822
-
1823
- Eine Browser-Umleitung kann mithilfe der `redirect`-Helfer-Methode erreicht
1824
- werden:
1825
-
1826
- ```ruby
1827
- get '/foo' do
1828
- redirect to('/bar')
1829
- end
1830
- ```
1831
-
1832
- Weitere Parameter werden wie Argumente der `halt`-Methode behandelt:
1833
-
1834
- ```ruby
1835
- redirect to('/bar'), 303
1836
- redirect 'http://www.google.com/', 'Hier bist du falsch'
1837
- ```
1838
-
1839
- Ebenso leicht lässt sich ein Schritt zurück mit dem Alias `redirect back`
1840
- erreichen:
1841
-
1842
- ```ruby
1843
- get '/foo' do
1844
- "<a href='/bar'>mach was</a>"
1845
- end
1846
-
1847
- get '/bar' do
1848
- mach_was
1849
- redirect back
1850
- end
1851
- ```
1852
-
1853
- Um Argumente an einen Redirect weiterzugeben, können sie entweder dem Query
1854
- übergeben:
1855
-
1856
- ```ruby
1857
- redirect to('/bar?summe=42')
1858
- ```
1859
-
1860
- oder eine Session verwendet werden:
1861
-
1862
- ```ruby
1863
- enable :sessions
1864
-
1865
- get '/foo' do
1866
- session[:secret] = 'foo'
1867
- redirect to('/bar')
1868
- end
1869
-
1870
- get '/bar' do
1871
- session[:secret]
1872
- end
1873
- ```
1874
-
1875
- ### Cache einsetzen
1876
-
1877
- Ein sinnvolles Einstellen von Header-Daten ist die Grundlage für ein
1878
- ordentliches HTTP-Caching.
1879
-
1880
- Der Cache-Control-Header lässt sich ganz einfach einstellen:
1881
-
1882
- ```ruby
1883
- get '/' do
1884
- cache_control :public
1885
- "schon gecached!"
1886
- end
1887
- ```
1888
-
1889
- Profitipp: Caching im before-Filter aktivieren
1890
-
1891
- ```ruby
1892
- before do
1893
- cache_control :public, :must_revalidate, :max_age => 60
1894
- end
1895
- ```
1896
-
1897
- Bei Verwendung der `expires`-Helfermethode zum Setzen des gleichnamigen
1898
- Headers, wird `Cache-Control` automatisch eigestellt:
1899
-
1900
- ```ruby
1901
- before do
1902
- expires 500, :public, :must_revalidate
1903
- end
1904
- ```
1905
-
1906
- Um alles richtig zu machen, sollten auch `etag` oder `last_modified` verwendet
1907
- werden. Es wird empfohlen, dass diese Helfer aufgerufen werden *bevor* die
1908
- eigentliche Arbeit anfängt, da sie sofort eine Antwort senden, wenn der Client
1909
- eine aktuelle Version im Cache vorhält:
1910
-
1911
- ```ruby
1912
- get '/article/:id' do
1913
- @article = Article.find params['id']
1914
- last_modified @article.updated_at
1915
- etag @article.sha1
1916
- erb :article
1917
- end
1918
- ```
1919
-
1920
- ebenso ist es möglich einen
1921
- [schwachen ETag](https://de.wikipedia.org/wiki/HTTP_ETag) zu verwenden:
1922
-
1923
- ```ruby
1924
- etag @article.sha1, :weak
1925
- ```
1926
-
1927
- Diese Helfer führen nicht das eigentliche Caching aus, sondern geben die dafür
1928
- notwendigen Informationen an den Cache weiter. Für schnelle Reverse-Proxy
1929
- Cache-Lösungen bietet sich z.B.
1930
- [rack-cache](https://github.com/rtomayko/rack-cache) an:
1931
-
1932
- ```ruby
1933
- require "rack/cache"
1934
- require "sinatra"
1935
-
1936
- use Rack::Cache
1937
-
1938
- get '/' do
1939
- cache_control :public, :max_age => 36000
1940
- sleep 5
1941
- "hello"
1942
- end
1943
- ```
1944
-
1945
- Um den `Cache-Control`-Header mit Informationen zu versorgen, verwendet man
1946
- die `:static_cache_control`-Einstellung (s.u.).
1947
-
1948
- Nach RFC 2616 sollte sich die Anwendung anders verhalten, wenn ein If-Match
1949
- oder ein If-None-Match Header auf `*` gesetzt wird in Abhängigkeit davon, ob
1950
- die Resource bereits existiert. Sinatra geht davon aus, dass Ressourcen bei
1951
- sicheren Anfragen (z.B. bei get oder Idempotenten Anfragen wie put) bereits
1952
- existieren, wobei anderen Ressourcen (besipielsweise bei post), als neue
1953
- Ressourcen behandelt werden. Dieses Verhalten lässt sich mit der
1954
- `:new_resource` Option ändern:
1955
-
1956
- ```ruby
1957
- get '/create' do
1958
- etag '', :new_resource => true
1959
- Article.create
1960
- erb :new_article
1961
- end
1962
- ```
1963
-
1964
- Soll das schwache ETag trotzdem verwendet werden, verwendet man die `:kind`
1965
- Option:
1966
-
1967
- ```ruby
1968
- etag '', :new_resource => true, :kind => :weak
1969
- ```
1970
-
1971
- ### Dateien versenden
1972
-
1973
- Um den Inhalt einer Datei als Response zurückzugeben, kann die
1974
- `send_file`-Helfer-Methode verwendet werden:
1975
-
1976
- ```ruby
1977
- get '/' do
1978
- send_file 'foo.png'
1979
- end
1980
- ```
1981
-
1982
- Für `send_file` stehen einige Hash-Optionen zur Verfügung:
1983
-
1984
- ```ruby
1985
- send_file 'foo.png', :type => :jpg
1986
- ```
1987
-
1988
- <dl>
1989
- <dt>filename</dt>
1990
- <dd>Dateiname als Response.
1991
- Standardwert ist der eigentliche Dateiname.</dd>
1992
-
1993
- <dt>last_modified</dt>
1994
- <dd>Wert für den Last-Modified-Header, Standardwert ist <tt>mtime</tt> der
1995
- Datei.</dd>
1996
-
1997
- <dt>type</dt>
1998
- <dd>Content-Type, der verwendet werden soll. Wird, wenn nicht angegeben,
1999
- von der Dateiendung abgeleitet.</dd>
2000
-
2001
- <dt>disposition</dt>
2002
- <dd>Verwendet für Content-Disposition. Mögliche Werte sind: <tt>nil</tt>
2003
- (Standard), <tt>:attachment</tt> und <tt>:inline</tt>.</dd>
2004
-
2005
- <dt>length</dt>
2006
- <dd>Content-Length-Header. Standardwert ist die Dateigröße.</dd>
2007
- <dt>Status</dt>
2008
- <dd>Zu versendender Status-Code. Nützlich, wenn eine statische Datei
2009
- als Fehlerseite zurückgegeben werden soll. Wenn der Rack-Handler es
2010
- unterstützt, dann können auch andere Methoden außer Streaming vom
2011
- Ruby-Prozess verwendet werden. Wird diese Helfermethode verwendet,
2012
- dann wird Sinatra sich automatisch um die Range-Anfrage kümmern.</dd>
2013
- </dl>
2014
-
2015
- ### Das Request-Objekt
2016
-
2017
- Auf das `request`-Objekt der eigehenden Anfrage kann vom Anfrage-Scope aus
2018
- zugegriffen werden (d.h. Filter, Routen, Fehlerbehandlung):
2019
-
2020
- ```ruby
2021
- # App läuft unter http://example.com/example
2022
- get '/foo' do
2023
- t = %w[text/css text/html application/javascript]
2024
- request.accept # ['text/html', '*/*']
2025
- request.accept? 'text/xml' # true
2026
- request.preferred_type(t) # 'text/html'
2027
- request.body # Request-Body des Client (siehe unten)
2028
- request.scheme # "http"
2029
- request.script_name # "/example"
2030
- request.path_info # "/foo"
2031
- request.port # 80
2032
- request.request_method # "GET"
2033
- request.query_string # ""
2034
- request.content_length # Länge des request.body
2035
- request.media_type # Medientypus von request.body
2036
- request.host # "example.com"
2037
- request.get? # true (ähnliche Methoden für andere Verben)
2038
- request.form_data? # false
2039
- request["irgendein_param"] # Wert von einem Parameter; [] ist die Kurzform für den params Hash
2040
- request.referrer # Der Referrer des Clients oder '/'
2041
- request.user_agent # User-Agent (verwendet in der :agent Bedingung)
2042
- request.cookies # Hash des Browser-Cookies
2043
- request.xhr? # Ist das hier ein Ajax-Request?
2044
- request.url # "http://example.com/example/foo"
2045
- request.path # "/example/foo"
2046
- request.ip # IP-Adresse des Clients
2047
- request.secure? # false (true wenn SSL)
2048
- request.forwarded? # true (Wenn es hinter einem Reverse-Proxy verwendet wird)
2049
- request.env # vollständiger env-Hash von Rack übergeben
2050
- end
2051
- ```
2052
-
2053
- Manche Optionen, wie etwa `script_name` oder `path_info`, sind auch
2054
- schreibbar:
2055
-
2056
- ```ruby
2057
- before { request.path_info = "/" }
2058
-
2059
- get "/" do
2060
- "Alle Anfragen kommen hier an!"
2061
- end
2062
- ```
2063
-
2064
- Der `request.body` ist ein IO- oder StringIO-Objekt:
2065
-
2066
- ```ruby
2067
- post "/api" do
2068
- request.body.rewind # falls schon jemand davon gelesen hat
2069
- daten = JSON.parse request.body.read
2070
- "Hallo #{daten['name']}!"
2071
- end
2072
- ```
2073
-
2074
- ### Anhänge
2075
-
2076
- Damit der Browser erkennt, dass ein Response gespeichert und nicht im Browser
2077
- angezeigt werden soll, kann der `attachment`-Helfer verwendet werden:
2078
-
2079
- ```ruby
2080
- get '/' do
2081
- attachment
2082
- "Speichern!"
2083
- end
2084
- ```
2085
-
2086
- Ebenso kann ein Dateiname als Parameter hinzugefügt werden:
2087
-
2088
- ```ruby
2089
- get '/' do
2090
- attachment "info.txt"
2091
- "Speichern!"
2092
- end
2093
- ```
2094
-
2095
- ### Umgang mit Datum und Zeit
2096
-
2097
- Sinatra bietet eine `time_for`-Helfer-Methode, die aus einem gegebenen Wert
2098
- ein Time-Objekt generiert. Ebenso kann sie nach `DateTime`, `Date` und
2099
- ähnliche Klassen konvertieren:
2100
-
2101
- ```ruby
2102
- get '/' do
2103
- pass if Time.now > time_for('Dec 23, 2016')
2104
- "noch Zeit"
2105
- end
2106
- ```
2107
-
2108
- Diese Methode wird intern für `expires`, `last_modiefied` und ihresgleichen
2109
- verwendet. Mit ein paar Handgriffen lässt sich diese Methode also in ihrem
2110
- Verhalten erweitern, indem man `time_for` in der eigenen Applikation
2111
- überschreibt:
2112
-
2113
- ```ruby
2114
- helpers do
2115
- def time_for(value)
2116
- case value
2117
- when :yesterday then Time.now - 24*60*60
2118
- when :tomorrow then Time.now + 24*60*60
2119
- else super
2120
- end
2121
- end
2122
- end
2123
-
2124
- get '/' do
2125
- last_modified :yesterday
2126
- expires :tomorrow
2127
- "Hallo"
2128
- end
2129
- ```
2130
-
2131
- ### Nachschlagen von Template-Dateien
2132
-
2133
- Die `find_template`-Helfer-Methode wird genutzt, um Template-Dateien zum
2134
- Rendern aufzufinden:
2135
-
2136
- ```ruby
2137
- find_template settings.views, 'foo', Tilt[:haml] do |file|
2138
- puts "könnte diese hier sein: #{file}"
2139
- end
2140
- ```
2141
-
2142
- Das ist zwar nicht wirklich brauchbar, aber wenn man sie überschreibt, kann
2143
- sie nützlich werden, um eigene Nachschlage-Mechanismen einzubauen. Zum
2144
- Beispiel dann, wenn mehr als nur ein view-Verzeichnis verwendet werden soll:
2145
-
2146
- ```ruby
2147
- set :views, ['views', 'templates']
2148
-
2149
- helpers do
2150
- def find_template(views, name, engine, &block)
2151
- Array(views).each { |v| super(v, name, engine, &block) }
2152
- end
2153
- end
2154
- ```
2155
-
2156
- Ein anderes Beispiel wäre, verschiedene Verzeichnisse für verschiedene Engines
2157
- zu verwenden:
2158
-
2159
- ```ruby
2160
- set :views, :sass => 'views/sass', :haml => 'templates', :default => 'views'
2161
-
2162
- helpers do
2163
- def find_template(views, name, engine, &block)
2164
- _, folder = views.detect { |k,v| engine == Tilt[k] }
2165
- folder ||= views[:default]
2166
- super(folder, name, engine, &block)
2167
- end
2168
- end
2169
- ```
2170
-
2171
- Ebensogut könnte eine Extension aber auch geschrieben und mit anderen geteilt
2172
- werden!
2173
-
2174
- Beachte, dass `find_template` nicht prüft, ob eine Datei tatsächlich
2175
- existiert. Es wird lediglich der angegebene Block aufgerufen und nach allen
2176
- möglichen Pfaden gesucht. Das ergibt kein Performance-Problem, da `render`
2177
- `block` verwendet, sobald eine Datei gefunden wurde. Ebenso werden
2178
- Template-Pfade samt Inhalten gecached, solange nicht im Entwicklungsmodus
2179
- gearbeitet wird. Das sollte im Hinterkopf behalten werden, wenn irgendwelche
2180
- verrückten Methoden zusammengebastelt werden.
2181
-
2182
- ### Konfiguration
2183
-
2184
- Wird einmal beim Starten in jedweder Umgebung ausgeführt:
2185
-
2186
- ```ruby
2187
- configure do
2188
- # setze eine Option
2189
- set :option, 'wert'
2190
-
2191
- # setze mehrere Optionen
2192
- set :a => 1, :b => 2
2193
-
2194
- # das gleiche wie `set :option, true`
2195
- enable :option
2196
-
2197
- # das gleiche wie `set :option, false`
2198
- disable :option
2199
-
2200
- # dynamische Einstellungen mit Blöcken
2201
- set(:css_dir) { File.join(views, 'css') }
2202
- end
2203
- ```
2204
-
2205
- Läuft nur, wenn die Umgebung (`APP_ENV`-Umgebungsvariable) auf `:production`
2206
- gesetzt ist:
2207
-
2208
- ```ruby
2209
- configure :production do
2210
- ...
2211
- end
2212
- ```
2213
-
2214
- Läuft nur, wenn die Umgebung auf `:production` oder auf `:test` gesetzt ist:
2215
-
2216
- ```ruby
2217
- configure :production, :test do
2218
- ...
2219
- end
2220
- ```
2221
-
2222
- Diese Einstellungen sind über `settings` erreichbar:
2223
-
2224
- ```ruby
2225
- configure do
2226
- set :foo, 'bar'
2227
- end
2228
-
2229
- get '/' do
2230
- settings.foo? # => true
2231
- settings.foo # => 'bar'
2232
- ...
2233
- end
2234
- ```
2235
-
2236
- #### Einstellung des Angriffsschutzes
2237
-
2238
- Sinatra verwendet
2239
- [Rack::Protection](https://github.com/sinatra/sinatra/tree/master/rack-protection#readme), um die
2240
- Anwendung vor häufig vorkommenden Angriffen zu schützen. Diese Voreinstellung
2241
- lässt sich selbstverständlich deaktivieren, der damit verbundene
2242
- Geschwindigkeitszuwachs steht aber in keinem Verhätnis zu den möglichen
2243
- Risiken.
2244
-
2245
- ```ruby
2246
- disable :protection
2247
- ```
2248
-
2249
- Um einen bestimmten Schutzmechanismus zu deaktivieren, fügt man `protection`
2250
- einen Hash mit Optionen hinzu:
2251
-
2252
- ```ruby
2253
- set :protection, :except => :path_traversal
2254
- ```
2255
-
2256
- Neben Strings akzeptiert `:except` auch Arrays, um gleich mehrere
2257
- Schutzmechanismen zu deaktivieren:
2258
-
2259
- ```ruby
2260
- set :protection, :except => [:path_traversal, :session_hijacking]
2261
- ```
2262
-
2263
- Standardmäßig setzt Sinatra einen sitzungbasierten Schutz nur dann ein,
2264
- wenn `:sessions` aktiviert wurde (siehe oben). Manchmal kann es aber
2265
- auch sein, dass Sitzungen außerhalb von Sinatra eingerichtet werden,
2266
- z.B. über eine config.ru oder einer zusätzlichen
2267
- `Rack::Builder`-Instance. In diesen Situationen kann eine
2268
- sitzungbasierte Sicherung eingesetzt werden mit Hilfe der
2269
- `:session`-Option:
2270
-
2271
- ```ruby
2272
- set :protection, session => true
2273
- ```
2274
-
2275
- #### Mögliche Einstellungen
2276
-
2277
- <dl>
2278
- <dt>absolute_redirects</dt>
2279
- <dd>
2280
- Wenn ausgeschaltet, wird Sinatra relative Redirects zulassen.
2281
- Jedoch ist Sinatra dann nicht mehr mit RFC 2616 (HTTP 1.1)
2282
- konform, das nur absolute Redirects zulässt.
2283
- </dd>
2284
- <dd>
2285
- Sollte eingeschaltet werden, wenn die Applikation hinter einem
2286
- Reverse-Proxy liegt, der nicht ordentlich eingerichtet ist.
2287
- Beachte, dass die <tt>url</tt>-Helfer-Methode nach wie vor
2288
- absolute URLs erstellen wird, es sei denn, es wird als zweiter
2289
- Parameter <tt>false</tt> angegeben.
2290
- </dd>
2291
- <dd>Standardmäßig nicht aktiviert.</dd>
2292
-
2293
- <dt>add_charset</dt>
2294
- <dd>
2295
- Mime-Types werden hier automatisch der Helfer-Methode
2296
- <tt>content_type</tt> zugeordnet. Es empfielt sich, Werte
2297
- hinzuzufügen statt sie zu überschreiben: <tt>settings.add_charset
2298
- << "application/foobar"</tt>
2299
- </dd>
2300
-
2301
- <dt>app_file</dt>
2302
- <dd>
2303
- Pfad zur Hauptdatei der Applikation. Wird verwendet, um das Wurzel-,
2304
- Inline-, View- und öffentliche Verzeichnis des Projekts festzustellen.
2305
- </dd>
2306
-
2307
- <dt>bind</dt>
2308
- <dd>
2309
- IP-Adresse, an die gebunden wird (Standardwert: <tt>0.0.0.0</tt>
2310
- <em>oder</em> <tt>localhost</tt>). Wird nur für den eingebauten Server
2311
- verwendet.
2312
- </dd>
2313
-
2314
- <dt>default_encoding</dt>
2315
- <dd>
2316
- Das Encoding, falls keines angegeben wurde. Standardwert ist
2317
- <tt>"utf-8"</tt>.
2318
- </dd>
2319
-
2320
- <dt>dump_errors</dt>
2321
- <dd>Fehler im Log anzeigen.</dd>
2322
-
2323
- <dt>environment</dt>
2324
- <dd>
2325
- Momentane Umgebung. Standardmäßig auf <tt>ENV['APP_ENV']</tt> oder
2326
- <tt>"development"</tt> eingestellt, soweit ersteres nicht vorhanden.
2327
- </dd>
2328
-
2329
- <dt>logging</dt>
2330
- <dd>Den Logger verwenden.</dd>
2331
-
2332
- <dt>lock</dt>
2333
- <dd>
2334
- Jeder Request wird gelocked. Es kann nur ein Request pro Ruby-Prozess
2335
- gleichzeitig verarbeitet werden.
2336
- </dd>
2337
- <dd>
2338
- Eingeschaltet, wenn die Applikation threadsicher ist. Standardmäßig
2339
- nicht aktiviert.
2340
- </dd>
2341
-
2342
- <dt>method_override</dt>
2343
- <dd>
2344
- Verwende <tt>_method</tt>, um put/delete-Formulardaten in Browsern zu
2345
- verwenden, die dies normalerweise nicht unterstützen.
2346
- </dd>
2347
-
2348
- <dt>mustermann_opts</dt>
2349
- <dd>
2350
- Ein Hash mit Standardeinstellungen, der an Mustermann.new beim
2351
- Kompilieren der Routen übergeben wird.
2352
- </dd>
2353
-
2354
- <dt>port</dt>
2355
- <dd>Port für die Applikation. Wird nur im internen Server verwendet.</dd>
2356
-
2357
- <dt>prefixed_redirects</dt>
2358
- <dd>
2359
- Entscheidet, ob <tt>request.script_name</tt> in Redirects
2360
- eingefügt wird oder nicht, wenn kein absoluter Pfad angegeben ist.
2361
- Auf diese Weise verhält sich <tt>redirect '/foo'</tt> so, als wäre
2362
- es ein <tt>redirect to('/foo')</tt>. Standardmäßig nicht
2363
- aktiviert.
2364
- </dd>
2365
-
2366
- <dt>protection</dt>
2367
- <dd>
2368
- Legt fest, ob der Schutzmechanismus für häufig Vorkommende Webangriffe
2369
- auf Webapplikationen aktiviert wird oder nicht. Weitere Informationen im
2370
- vorhergehenden Abschnitt.
2371
- </dd>
2372
-
2373
- <dt>public_folder</dt>
2374
- <dd>
2375
- Das öffentliche Verzeichnis, aus dem Daten zur Verfügung gestellt
2376
- werden können. Wird nur dann verwendet, wenn statische Daten zur
2377
- Verfügung gestellt werden können (s.u. <tt>static</tt> Option).
2378
- Leitet sich von der <tt>app_file</tt> Einstellung ab, wenn nicht
2379
- gesetzt.
2380
- </dd>
2381
-
2382
- <dt>quiet</dt>
2383
- <dd>
2384
- Deaktiviert Logs, die beim Starten und Beenden von Sinatra
2385
- ausgegeben werden. <tt>false</tt> ist die Standardeinstellung.
2386
- </dd>
2387
-
2388
- <dt>public_dir</dt>
2389
- <dd>Alias für <tt>public_folder</tt>, s.o.</dd>
2390
-
2391
- <dt>reload_templates</dt>
2392
- <dd>
2393
- Legt fest, ob Templates für jede Anfrage neu generiert werden. Im
2394
- development-Modus aktiviert.
2395
- </dd>
2396
-
2397
- <dt>root</dt>
2398
- <dd>
2399
- Wurzelverzeichnis des Projekts. Leitet sich von der <tt>app_file</tt>
2400
- Einstellung ab, wenn nicht gesetzt.
2401
- </dd>
2402
-
2403
- <dt>raise_errors</dt>
2404
- <dd>
2405
- Einen Ausnahmezustand aufrufen. Beendet die Applikation. Ist
2406
- automatisch aktiviert, wenn die Umgebung auf <tt>"test"</tt>
2407
- eingestellt ist. Ansonsten ist diese Option deaktiviert.
2408
- </dd>
2409
-
2410
- <dt>run</dt>
2411
- <dd>
2412
- Wenn aktiviert, wird Sinatra versuchen, den Webserver zu starten. Nicht
2413
- verwenden, wenn Rackup oder anderes verwendet werden soll.
2414
- </dd>
2415
-
2416
- <dt>running</dt>
2417
- <dd>Läuft der eingebaute Server? Diese Einstellung nicht ändern!</dd>
2418
-
2419
- <dt>server</dt>
2420
- <dd>
2421
- Server oder Liste von Servern, die als eingebaute Server zur
2422
- Verfügung stehen. Die Reihenfolge gibt die Priorität vor, die
2423
- Voreinstellung hängt von der verwendenten Ruby Implementierung ab.
2424
- </dd>
2425
-
2426
- <dt>sessions</dt>
2427
- <dd>
2428
- Sessions auf Cookiebasis mittels
2429
- <tt>Rack::Session::Cookie</tt> aktivieren. Für weitere Infos bitte
2430
- in der Sektion ‘Sessions verwenden’ nachschauen.
2431
- </dd>
2432
-
2433
- <dt>session_store</dt>
2434
- <dd>
2435
- Die verwendete Rack Sitzungs-Middleware. Verweist standardmäßig
2436
- auf <tt>Rack::Session::Cookie</tt>. Für weitere Infos bitte
2437
- in der Sektion ‘Sessions verwenden’ nachschauen.
2438
- </dd>
2439
-
2440
- <dt>show_exceptions</dt>
2441
- <dd>
2442
- Bei Fehlern einen Stacktrace im Browser anzeigen. Ist automatisch
2443
- aktiviert, wenn die Umgebung auf <tt>"development"</tt>
2444
- eingestellt ist. Ansonsten ist diese Option deaktiviert.
2445
- </dd>
2446
- <dd>
2447
- Kann auch auf <tt>:after_handler</tt> gestellt werden, um eine
2448
- anwendungsspezifische Fehlerbehandlung auszulösen, bevor der
2449
- Fehlerverlauf im Browser angezeigt wird.
2450
- </dd>
2451
-
2452
- <dt>static</dt>
2453
- <dd>
2454
- Entscheidet, ob Sinatra statische Dateien zur Verfügung stellen
2455
- soll oder nicht. Sollte nicht aktiviert werden, wenn ein Server
2456
- verwendet wird, der dies auch selbstständig erledigen kann.
2457
- Deaktivieren wird die Performance erhöhen. Standardmäßig
2458
- aktiviert.
2459
- </dd>
2460
-
2461
- <dt>static_cache_control</dt>
2462
- <dd>
2463
- Wenn Sinatra statische Daten zur Verfügung stellt, können mit
2464
- dieser Einstellung die <tt>Cache-Control</tt> Header zu den
2465
- Responses hinzugefügt werden. Die Einstellung verwendet dazu die
2466
- <tt>cache_control</tt> Helfer-Methode. Standardmäßig deaktiviert.
2467
- Ein Array wird verwendet, um mehrere Werte gleichzeitig zu
2468
- übergeben: <tt>set :static_cache_control, [:public, :max_age =>
2469
- 300]</tt>
2470
- </dd>
2471
-
2472
- <dt>threaded</dt>
2473
- <dd>
2474
- Wird es auf <tt>true</tt> gesetzt, wird Thin aufgefordert
2475
- <tt>EventMachine.defer</tt> zur Verarbeitung des Requests einzusetzen.
2476
- </dd>
2477
-
2478
- <dt>traps</dt>
2479
- <dd>Legt fest, wie Sinatra mit System-Signalen umgehen soll.</dd>
2480
-
2481
- <dt>views</dt>
2482
- <dd>
2483
- Verzeichnis der Views. Leitet sich von der <tt>app_file</tt> Einstellung
2484
- ab, wenn nicht gesetzt.
2485
- </dd>
2486
-
2487
- <dt>x_cascade</dt>
2488
- <dd>
2489
- Einstellung, ob der X-Cascade Header bei fehlender Route gesetzt
2490
- wird oder nicht. Standardeinstellung ist <tt>true</tt>.
2491
- </dd>
2492
- </dl>
2493
-
2494
- ## Umgebungen
2495
-
2496
- Es gibt drei voreingestellte Umgebungen in Sinatra: `"development"`,
2497
- `"production"` und `"test"`. Umgebungen können über die `APP_ENV`
2498
- Umgebungsvariable gesetzt werden. Die Standardeinstellung ist `"development"`.
2499
- In diesem Modus werden alle Templates zwischen Requests neu geladen. Dazu gibt
2500
- es besondere Fehlerseiten für 404 Stati und Fehlermeldungen. In `"production"`
2501
- und `"test"` werden Templates automatisch gecached.
2502
-
2503
- Um die Anwendung in einer anderen Umgebung auszuführen, kann man die
2504
- `APP_ENV`-Umgebungsvariable setzen:
2505
-
2506
- ```shell
2507
- APP_ENV=production ruby my_app.rb
2508
- ```
2509
-
2510
- In der Anwendung kann man die die Methoden `development?`, `test?` und
2511
- `production?` verwenden, um die aktuelle Umgebung zu erfahren:
2512
-
2513
-
2514
- ```ruby
2515
- get '/' do
2516
- if settings.development?
2517
- "development!"
2518
- else
2519
- "nicht development!"
2520
- end
2521
- end
2522
- ```
2523
-
2524
- ## Fehlerbehandlung
2525
-
2526
- Error-Handler laufen in demselben Kontext wie Routen und Filter, was bedeutet,
2527
- dass alle Goodies wie `haml`, `erb`, `halt`, etc. verwendet werden können.
2528
-
2529
- ### Nicht gefunden
2530
-
2531
- Wenn eine `Sinatra::NotFound`-Exception geworfen wird oder der Statuscode 404
2532
- ist, wird der `not_found`-Handler ausgeführt:
2533
-
2534
- ```ruby
2535
- not_found do
2536
- 'Seite kann nirgendwo gefunden werden.'
2537
- end
2538
- ```
2539
-
2540
- ### Fehler
2541
-
2542
- Der `error`-Handler wird immer ausgeführt, wenn eine Exception in einem
2543
- Routen-Block oder in einem Filter geworfen wurde. In der
2544
- `development`-Umgebung wird es nur dann funktionieren, wenn die
2545
- `:show_exceptions`-Option auf `:after_handler` eingestellt wurde:
2546
-
2547
- ```ruby
2548
- set :show_exceptions, :after_handler
2549
- ```
2550
-
2551
- Die Exception kann über die `sinatra.error`-Rack-Variable angesprochen werden:
2552
-
2553
- ```ruby
2554
- error do
2555
- 'Entschuldige, es gab einen hässlichen Fehler - ' + env['sinatra.error'].message
2556
- end
2557
- ```
2558
-
2559
- Benutzerdefinierte Fehler:
2560
-
2561
- ```ruby
2562
- error MeinFehler do
2563
- 'Au weia, ' + env['sinatra.error'].message
2564
- end
2565
- ```
2566
-
2567
- Dann, wenn das passiert:
2568
-
2569
- ```ruby
2570
- get '/' do
2571
- raise MeinFehler, 'etwas Schlimmes ist passiert'
2572
- end
2573
- ```
2574
-
2575
- bekommt man dieses:
2576
-
2577
- ```shell
2578
- Au weia, etwas Schlimmes ist passiert
2579
- ```
2580
-
2581
- Alternativ kann ein Error-Handler auch für einen Status-Code definiert werden:
2582
-
2583
- ```ruby
2584
- error 403 do
2585
- 'Zugriff verboten'
2586
- end
2587
-
2588
- get '/geheim' do
2589
- 403
2590
- end
2591
- ```
2592
-
2593
- Oder ein Status-Code-Bereich:
2594
-
2595
- ```ruby
2596
- error 400..510 do
2597
- 'Hallo?'
2598
- end
2599
- ```
2600
-
2601
- Sinatra setzt verschiedene `not_found`- und `error`-Handler in der
2602
- Development-Umgebung ein, um hilfreiche Debugging-Informationen und
2603
- Stack-Traces anzuzeigen.
2604
-
2605
- ## Rack-Middleware
2606
-
2607
- Sinatra baut auf [Rack](http://rack.github.io/) auf, einem minimalistischen
2608
- Standard-Interface für Ruby-Webframeworks. Eines der interessantesten Features
2609
- für Entwickler ist der Support von Middlewares, die zwischen den Server und
2610
- die Anwendung geschaltet werden und so HTTP-Request und/oder Antwort
2611
- überwachen und/oder manipulieren können.
2612
-
2613
- Sinatra macht das Erstellen von Middleware-Verkettungen mit der
2614
- Top-Level-Methode `use` zu einem Kinderspiel:
2615
-
2616
- ```ruby
2617
- require 'sinatra'
2618
- require 'meine_middleware'
2619
-
2620
- use Rack::Lint
2621
- use MeineMiddleware
2622
-
2623
- get '/hallo' do
2624
- 'Hallo Welt'
2625
- end
2626
- ```
2627
-
2628
- Die Semantik von `use` entspricht der gleichnamigen Methode der
2629
- [Rack::Builder](http://www.rubydoc.info/github/rack/rack/master/Rack/Builder)-DSL
2630
- (meist verwendet in Rackup-Dateien). Ein Beispiel dafür ist, dass die
2631
- `use`-Methode mehrere/verschiedene Argumente und auch Blöcke
2632
- entgegennimmt:
2633
-
2634
- ```ruby
2635
- use Rack::Auth::Basic do |username, password|
2636
- username == 'admin' && password == 'geheim'
2637
- end
2638
- ```
2639
-
2640
- Rack bietet eine Vielzahl von Standard-Middlewares für Logging, Debugging,
2641
- URL-Routing, Authentifizierung und Session-Verarbeitung. Sinatra verwendet
2642
- viele von diesen Komponenten automatisch, abhängig von der Konfiguration. So
2643
- muss `use` häufig nicht explizit verwendet werden.
2644
-
2645
- Hilfreiche Middleware gibt es z.B. hier:
2646
- [rack](https://github.com/rack/rack/tree/master/lib/rack),
2647
- [rack-contrib](https://github.com/rack/rack-contrib#readme),
2648
- oder im [Rack wiki](https://github.com/rack/rack/wiki/List-of-Middleware).
2649
-
2650
- ## Testen
2651
-
2652
- Sinatra-Tests können mit jedem auf Rack aufbauendem Test-Framework
2653
- geschrieben werden.
2654
- [Rack::Test](http://www.rubydoc.info/github/brynary/rack-test/master/frames)
2655
- wird empfohlen:
2656
-
2657
- ```ruby
2658
- require 'my_sinatra_app'
2659
- require 'minitest/autorun'
2660
- require 'rack/test'
2661
-
2662
- class MyAppTest < Minitest::Test
2663
- include Rack::Test::Methods
2664
-
2665
- def app
2666
- Sinatra::Application
2667
- end
2668
-
2669
- def test_my_default
2670
- get '/'
2671
- assert_equal 'Hallo Welt!', last_response.body
2672
- end
2673
-
2674
- def test_with_params
2675
- get '/meet', :name => 'Frank'
2676
- assert_equal 'Hallo Frank!', last_response.body
2677
- end
2678
-
2679
- def test_with_user_agent
2680
- get '/', {}, 'HTTP_USER_AGENT' => 'Songbird'
2681
- assert_equal "Du verwendest Songbird!", last_response.body
2682
- end
2683
- end
2684
- ```
2685
-
2686
- Hinweis: Wird Sinatra modular verwendet, muss
2687
- `Sinatra::Application` mit dem Namen der Applikations-Klasse
2688
- ersetzt werden.
2689
-
2690
- ## Sinatra::Base - Middleware, Bibliotheken und modulare Anwendungen
2691
-
2692
- Das Definieren einer Top-Level-Anwendung funktioniert gut für
2693
- Mikro-Anwendungen, hat aber Nachteile, wenn wiederverwendbare Komponenten wie
2694
- Middleware, Rails Metal, einfache Bibliotheken mit Server-Komponenten oder
2695
- auch Sinatra-Erweiterungen geschrieben werden sollen.
2696
-
2697
- Das Top-Level geht von einer Konfiguration für eine Mikro-Anwendung aus (wie
2698
- sie z.B. bei einer einzelnen Anwendungsdatei, `./public` und `./views` Ordner,
2699
- Logging, Exception-Detail-Seite, usw.). Genau hier kommt `Sinatra::Base` ins
2700
- Spiel:
2701
-
2702
- ```ruby
2703
- require 'sinatra/base'
2704
-
2705
- class MyApp < Sinatra::Base
2706
- set :sessions, true
2707
- set :foo, 'bar'
2708
-
2709
- get '/' do
2710
- 'Hallo Welt!'
2711
- end
2712
- end
2713
- ```
2714
-
2715
- Die Methoden der `Sinatra::Base`-Subklasse sind genau dieselben wie die der
2716
- Top-Level-DSL. Die meisten Top-Level-Anwendungen können mit nur zwei
2717
- Veränderungen zu `Sinatra::Base` konvertiert werden:
2718
-
2719
- * Die Datei sollte `require 'sinatra/base'` anstelle von `require
2720
- 'sinatra'` aufrufen, ansonsten werden alle von Sinatras DSL-Methoden
2721
- in den Top-Level-Namespace importiert.
2722
- * Alle Routen, Error-Handler, Filter und Optionen der Applikation müssen in
2723
- einer Subklasse von `Sinatra::Base` definiert werden.
2724
-
2725
- `Sinatra::Base` ist ein unbeschriebenes Blatt. Die meisten Optionen sind per
2726
- Standard deaktiviert. Das betrifft auch den eingebauten Server. Siehe
2727
- [Optionen und Konfiguration](http://www.sinatrarb.com/configuration.html) für
2728
- Details über mögliche Optionen.
2729
-
2730
- Damit eine App sich ähnlich wie eine klassische App verhält, kann man
2731
- auch eine Subclass von `Sinatra::Application` erstellen:
2732
-
2733
- ```ruby
2734
- require 'sinatra/base'
2735
-
2736
- class MyApp < Sinatra::Application
2737
- get '/' do
2738
- 'Hello world!'
2739
- end
2740
- end
2741
- ```
2742
-
2743
- ### Modularer vs. klassischer Stil
2744
-
2745
- Entgegen häufiger Meinungen gibt es nichts gegen den klassischen Stil
2746
- einzuwenden. Solange es die Applikation nicht beeinträchtigt, besteht kein
2747
- Grund, eine modulare Applikation zu erstellen.
2748
-
2749
- Der größte Nachteil der klassischen Sinatra Anwendung gegenüber einer
2750
- modularen ist die Einschränkung auf eine Sinatra Anwendung pro Ruby-Prozess.
2751
- Sollen mehrere zum Einsatz kommen, muss auf den modularen Stil umgestiegen
2752
- werden. Dabei ist es kein Problem klassische und modulare Anwendungen
2753
- miteinander zu vermischen.
2754
-
2755
- Bei einem Umstieg, sollten einige Unterschiede in den Einstellungen beachtet
2756
- werden:
2757
-
2758
- <table>
2759
- <tr>
2760
- <th>Szenario</th>
2761
- <th>Classic</th>
2762
- <th>Modular</th>
2763
- <th>Modular</th>
2764
- </tr>
2765
-
2766
- <tr>
2767
- <td>app_file</td>
2768
- <td>Sinatra ladende Datei</td>
2769
- <td>Sinatra::Base subklassierende Datei</td>
2770
- <td>Sinatra::Application subklassierende Datei</td>
2771
- </tr>
2772
-
2773
- <tr>
2774
- <td>run</td>
2775
- <td>$0 == app_file</td>
2776
- <td>false</td>
2777
- <td>false</td>
2778
- </tr>
2779
-
2780
- <tr>
2781
- <td>logging</td>
2782
- <td>true</td>
2783
- <td>false</td>
2784
- <td>true</td>
2785
- </tr>
2786
-
2787
- <tr>
2788
- <td>method_override</td>
2789
- <td>true</td>
2790
- <td>false</td>
2791
- <td>true</td>
2792
- </tr>
2793
-
2794
- <tr>
2795
- <td>inline_templates</td>
2796
- <td>true</td>
2797
- <td>false</td>
2798
- <td>true</td>
2799
- </tr>
2800
-
2801
- <tr>
2802
- <td>static</td>
2803
- <td>true</td>
2804
- <td>File.exist?(public_folder)</td>
2805
- <td>true</td>
2806
- </tr>
2807
- </table>
2808
-
2809
- ### Eine modulare Applikation bereitstellen
2810
-
2811
- Es gibt zwei übliche Wege, eine modulare Anwendung zu starten. Zum einen über
2812
- `run!`:
2813
-
2814
- ```ruby
2815
- # mein_app.rb
2816
- require 'sinatra/base'
2817
-
2818
- class MeinApp < Sinatra::Base
2819
- # ... Anwendungscode hierhin ...
2820
-
2821
- # starte den Server, wenn die Ruby-Datei direkt ausgeführt wird
2822
- run! if app_file == $0
2823
- end
2824
- ```
2825
-
2826
- Starte mit:
2827
-
2828
- ```shell
2829
- ruby mein_app.rb
2830
- ```
2831
-
2832
- Oder über eine `config.ru`-Datei, die es erlaubt, einen beliebigen
2833
- Rack-Handler zu verwenden:
2834
-
2835
- ```ruby
2836
- # config.ru (mit rackup starten)
2837
- require './mein_app'
2838
- run MeineApp
2839
- ```
2840
-
2841
- Starte:
2842
-
2843
- ```shell
2844
- rackup -p 4567
2845
- ```
2846
-
2847
- ### Eine klassische Anwendung mit einer config.ru verwenden
2848
-
2849
- Schreibe eine Anwendungsdatei:
2850
-
2851
- ```ruby
2852
- # app.rb
2853
- require 'sinatra'
2854
-
2855
- get '/' do
2856
- 'Hallo Welt!'
2857
- end
2858
- ```
2859
-
2860
- sowie eine dazugehörige `config.ru`-Datei:
2861
-
2862
- ```ruby
2863
- require './app'
2864
- run Sinatra::Application
2865
- ```
2866
-
2867
- ### Wann sollte eine config.ru-Datei verwendet werden?
2868
-
2869
- Anzeichen dafür, dass eine `config.ru`-Datei gebraucht wird:
2870
-
2871
- * Es soll ein anderer Rack-Handler verwendet werden (Passenger, Unicorn,
2872
- Heroku, ...).
2873
- * Es gibt mehr als nur eine Subklasse von `Sinatra::Base`.
2874
- * Sinatra soll als Middleware verwendet werden, nicht als Endpunkt.
2875
-
2876
- **Es gibt keinen Grund, eine `config.ru`-Datei zu verwenden, nur weil eine
2877
- Anwendung im modularen Stil betrieben werden soll. Ebenso wird keine Anwendung
2878
- mit modularem Stil benötigt, um eine `config.ru`-Datei zu verwenden.**
2879
-
2880
- ### Sinatra als Middleware nutzen
2881
-
2882
- Es ist nicht nur möglich, andere Rack-Middleware mit Sinatra zu nutzen, es
2883
- kann außerdem jede Sinatra-Anwendung selbst als Middleware vor jeden
2884
- beliebigen Rack-Endpunkt gehangen werden. Bei diesem Endpunkt muss es sich
2885
- nicht um eine andere Sinatra-Anwendung handeln, es kann jede andere
2886
- Rack-Anwendung sein (Rails/Hanami/Roda/...):
2887
-
2888
- ```ruby
2889
- require 'sinatra/base'
2890
-
2891
- class LoginScreen < Sinatra::Base
2892
- enable :sessions
2893
-
2894
- get('/login') { haml :login }
2895
-
2896
- post('/login') do
2897
- if params['name'] == 'admin' && params['password'] == 'admin'
2898
- session['user_name'] = params['name']
2899
- else
2900
- redirect '/login'
2901
- end
2902
- end
2903
- end
2904
-
2905
- class MyApp < Sinatra::Base
2906
- # Middleware wird vor Filtern ausgeführt
2907
- use LoginScreen
2908
-
2909
- before do
2910
- unless session['user_name']
2911
- halt "Zugriff verweigert, bitte <a href='/login'>einloggen</a>."
2912
- end
2913
- end
2914
-
2915
- get('/') { "Hallo #{session['user_name']}." }
2916
- end
2917
- ```
2918
-
2919
- ### Dynamische Applikationserstellung
2920
-
2921
- Manche Situationen erfordern die Erstellung neuer Applikationen zur Laufzeit,
2922
- ohne dass sie einer Konstanten zugeordnet werden. Dies lässt sich mit
2923
- `Sinatra.new` erreichen:
2924
-
2925
- ```ruby
2926
- require 'sinatra/base'
2927
- my_app = Sinatra.new { get('/') { "hallo" } }
2928
- my_app.run!
2929
- ```
2930
-
2931
- Die Applikation kann mit Hilfe eines optionalen Parameters erstellt werden:
2932
-
2933
- ```ruby
2934
- # config.ru
2935
- require 'sinatra/base'
2936
-
2937
- controller = Sinatra.new do
2938
- enable :logging
2939
- helpers MyHelpers
2940
- end
2941
-
2942
- map('/a') do
2943
- run Sinatra.new(controller) { get('/') { 'a' } }
2944
- end
2945
-
2946
- map('/b') do
2947
- run Sinatra.new(controller) { get('/') { 'b' } }
2948
- end
2949
- ```
2950
-
2951
- Das ist besonders dann interessant, wenn Sinatra-Erweiterungen getestet werden
2952
- oder Sinatra in einer Bibliothek Verwendung findet.
2953
-
2954
- Ebenso lassen sich damit hervorragend Sinatra-Middlewares erstellen:
2955
-
2956
- ```ruby
2957
- require 'sinatra/base'
2958
-
2959
- use Sinatra do
2960
- get('/') { ... }
2961
- end
2962
-
2963
- run RailsProject::Application
2964
- ```
2965
-
2966
- ## Geltungsbereich und Bindung
2967
-
2968
- Der Geltungsbereich (Scope) legt fest, welche Methoden und Variablen zur
2969
- Verfügung stehen.
2970
-
2971
- ### Anwendungs- oder Klassen-Scope
2972
-
2973
- Jede Sinatra-Anwendung entspricht einer `Sinatra::Base`-Subklasse. Falls die
2974
- Top- Level-DSL verwendet wird (`require 'sinatra'`), handelt es sich um
2975
- `Sinatra::Application`, andernfalls ist es jene Subklasse, die explizit
2976
- angelegt wurde. Auf Klassenebene stehen Methoden wie `get` oder `before` zur
2977
- Verfügung, es gibt aber keinen Zugriff auf das `request`-Object oder die
2978
- `session`, da nur eine einzige Klasse für alle eingehenden Anfragen genutzt
2979
- wird.
2980
-
2981
- Optionen, die via `set` gesetzt werden, sind Methoden auf Klassenebene:
2982
-
2983
- ```ruby
2984
- class MyApp < Sinatra::Base
2985
- # Hey, ich bin im Anwendungsscope!
2986
- set :foo, 42
2987
- foo # => 42
2988
-
2989
- get '/foo' do
2990
- # Hey, ich bin nicht mehr im Anwendungs-Scope!
2991
- end
2992
- end
2993
- ```
2994
-
2995
- Im Anwendungs-Scope befindet man sich:
2996
-
2997
- * Innerhalb der Anwendungs-Klasse
2998
- * In Methoden, die von Erweiterungen definiert werden
2999
- * Im Block, der an `helpers` übergeben wird
3000
- * In Procs und Blöcken, die an `set` übergeben werden
3001
- * Der an `Sinatra.new` übergebene Block
3002
-
3003
- Auf das Scope-Objekt (die Klasse) kann wie folgt zugegriffen werden:
3004
-
3005
- * Über das Objekt, das an den `configure`-Block übergeben wird (`configure {
3006
- |c| ... }`).
3007
- * `settings` aus den anderen Scopes heraus.
3008
-
3009
- ### Anfrage- oder Instanz-Scope
3010
-
3011
- Für jede eingehende Anfrage wird eine neue Instanz der Anwendungs-Klasse
3012
- erstellt und alle Handler in diesem Scope ausgeführt. Aus diesem Scope heraus
3013
- kann auf `request` oder `session` zugegriffen und Methoden wie `erb` oder
3014
- `haml` aufgerufen werden. Außerdem kann mit der `settings`-Method auf den
3015
- Anwendungs-Scope zugegriffen werden:
3016
-
3017
- ```ruby
3018
- class MyApp < Sinatra::Base
3019
- # Hey, ich bin im Anwendungs-Scope!
3020
- get '/neue_route/:name' do
3021
- # Anfrage-Scope für '/neue_route/:name'
3022
- @value = 42
3023
-
3024
- settings.get "/#{params['name']}" do
3025
- # Anfrage-Scope für "/#{params['name']}"
3026
- @value # => nil (nicht dieselbe Anfrage)
3027
- end
3028
-
3029
- "Route definiert!"
3030
- end
3031
- end
3032
- ```
3033
-
3034
- Im Anfrage-Scope befindet man sich:
3035
-
3036
- * In get, head, post, put, delete, options, patch, link und unlink Blöcken
3037
- * In before und after Filtern
3038
- * In Helfer-Methoden
3039
- * In Templates/Views
3040
-
3041
- ### Delegation-Scope
3042
-
3043
- Vom Delegation-Scope aus werden Methoden einfach an den Klassen-Scope
3044
- weitergeleitet. Dieser verhält sich jedoch nicht 100%ig wie der Klassen-Scope,
3045
- da man nicht die Bindung der Klasse besitzt: Nur Methoden, die explizit als
3046
- delegierbar markiert wurden, stehen hier zur Verfügung und es kann nicht auf
3047
- die Variablen des Klassenscopes zugegriffen werden (mit anderen Worten: es
3048
- gibt ein anderes `self`). Weitere Delegationen können mit
3049
- `Sinatra::Delegator.delegate :methoden_name` hinzugefügt werden.
3050
-
3051
- Im Delegation-Scop befindet man sich:
3052
-
3053
- * Im Top-Level, wenn `require 'sinatra'` aufgerufen wurde.
3054
- * In einem Objekt, das mit dem `Sinatra::Delegator`-Mixin erweitert wurde.
3055
-
3056
- Schau am besten im Code nach: Hier ist [Sinatra::Delegator
3057
- mixin](http://github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb#L1064
3058
- ) definiert und wird in den [globalen Namespace
3059
- eingebunden](http://github.com/sinatra/sinatra/blob/master/lib/sinatra/main.rb).
3060
-
3061
- ## Kommandozeile
3062
-
3063
- Sinatra-Anwendungen können direkt von der Kommandozeile aus gestartet werden:
3064
-
3065
- ```shell
3066
- ruby myapp.rb [-h] [-x] [-q] [-e ENVIRONMENT] [-p PORT] [-h HOST] [-s HANDLER]
3067
- ```
3068
-
3069
- Die Optionen sind:
3070
-
3071
- ```
3072
- -h # Hilfe
3073
- -p # Port setzen (Standard ist 4567)
3074
- -h # Host setzen (Standard ist 0.0.0.0)
3075
- -e # Umgebung setzen (Standard ist development)
3076
- -s # Rack-Server/Handler setzen (Standard ist thin)
3077
- -q # den lautlosen Server-Modus einschalten (Standard ist aus)
3078
- -x # Mutex-Lock einschalten (Standard ist aus)
3079
- ```
3080
-
3081
- ### Multi-threading
3082
-
3083
- _Paraphrasiert von [dieser Antwort auf StackOverflow][so-answer] von
3084
- Konstantin_
3085
-
3086
- Sinatra erlegt kein Nebenläufigkeitsmodell auf, sondern überlässt dies dem
3087
- selbst gewählten Rack-Proxy (Server), so wie Thin, Puma oder WEBrick.
3088
- Sinatra selbst ist Thread-sicher, somit ist es kein Problem wenn der
3089
- Rack-Proxy ein anderes Threading-Modell für Nebenläufigkeit benutzt.
3090
- Das heißt, dass wenn der Server gestartet wird, dass man die korrekte
3091
- Aufrufsmethode benutzen sollte für den jeweiligen Rack-Proxy.
3092
- Das folgende Beispiel ist eine Veranschaulichung eines mehrprozessigen
3093
- Thin Servers:
3094
-
3095
- ``` ruby
3096
- # app.rb
3097
-
3098
- require 'sinatra/base'
3099
-
3100
- class App < Sinatra::Base
3101
- get '/' do
3102
- "Hello, World"
3103
- end
3104
- end
3105
-
3106
- App.run!
3107
-
3108
- ```
3109
-
3110
- Um den Server zu starten, führt man das folgende Kommando aus:
3111
-
3112
- ``` shell
3113
- thin --threaded start
3114
- ```
3115
-
3116
- [so-answer]: http://stackoverflow.com/questions/6278817/is-sinatra-multi-threaded/6282999#6282999)
3117
-
3118
- ## Systemanforderungen
3119
-
3120
- Die folgenden Versionen werden offiziell unterstützt:
3121
-
3122
- <dl>
3123
- <dt>Ruby 2.3</dt>
3124
- <dd>
3125
- 2.3 wird vollständig unterstützt. Es gibt derzeit keine Pläne die
3126
- offizielle Unterstützung zu beenden
3127
- </dd>
3128
-
3129
- <dt>Rubinius</dt>
3130
- <dd>
3131
- Rubinius (Version >= 2.x) wird offiziell unterstützt. Es wird
3132
- empfohlen, den <a href="http://puma.io">Puma Server</a> zu
3133
- installieren (<tt>gem install puma</tt>)
3134
- </dd>
3135
-
3136
- <dt>JRuby</dt>
3137
- <dd>
3138
- Aktuelle JRuby Versionen werden offiziell unterstützt. Es wird empfohlen,
3139
- keine C-Erweiterungen zu verwenden und als Server Trinidad zu verwenden
3140
- (<tt>gem install trinidad</tt>).
3141
- </dd>
3142
- </dl>
3143
-
3144
- Versionen vor Ruby 2.2.2 werden ab Sinatra 2.0 nicht länger unterstützt.
3145
-
3146
- Nachfolgende Ruby-Versionen werden regelmäßig auf Unterstützung geprüft.
3147
-
3148
- Die nachfolgend aufgeführten Ruby-Implementierungen werden offiziell nicht von
3149
- Sinatra unterstützt, funktionieren aber normalerweise:
3150
-
3151
- * Ruby Enterprise Edition
3152
- * Ältere Versionen von JRuby und Rubinius
3153
- * MacRuby, Maglev, IronRuby
3154
- * Ruby 1.9.0 und 1.9.1 (wird aber nicht empfohlen)
3155
-
3156
- Nicht offiziell unterstützt bedeutet, dass wenn Sachen nicht funktionieren,
3157
- wir davon ausgehen, dass es nicht an Sinatra sondern an der jeweiligen
3158
- Implementierung liegt.
3159
-
3160
- Im Rahmen unserer CI (Kontinuierlichen Integration) wird bereits ruby-head
3161
- (zukünftige Versionen von MRI) mit eingebunden. Es kann davon ausgegangen
3162
- werden, dass Sinatra MRI auch weiterhin vollständig unterstützen wird.
3163
-
3164
- Sinatra sollte auf jedem Betriebssystem laufen, das einen funktionierenden
3165
- Ruby-Interpreter aufweist.
3166
-
3167
- Sinatra läuft aktuell nicht unter Cardinal, SmallRuby, BlueRuby oder Ruby <=
3168
- 2.2.
3169
-
3170
- ## Der neuste Stand (The Bleeding Edge)
3171
-
3172
- Um auf dem neusten Stand zu bleiben, kann der Master-Branch verwendet werden.
3173
- Er sollte recht stabil sein. Ebenso gibt es von Zeit zu Zeit prerelease Gems,
3174
- die so installiert werden:
3175
-
3176
- ```shell
3177
- gem install sinatra --pre
3178
- ```
3179
-
3180
- ### Mit Bundler
3181
-
3182
- Wenn die Applikation mit der neuesten Version von Sinatra und
3183
- [Bundler](http://bundler.io) genutzt werden soll, empfehlen wir den
3184
- nachfolgenden Weg.
3185
-
3186
- Soweit Bundler noch nicht installiert ist:
3187
-
3188
- ```shell
3189
- gem install bundler
3190
- ```
3191
-
3192
- Anschließend wird eine `Gemfile`-Datei im Projektverzeichnis mit folgendem
3193
- Inhalt erstellt:
3194
-
3195
- ```ruby
3196
- source :rubygems
3197
- gem 'sinatra', :git => "git://github.com/sinatra/sinatra.git"
3198
-
3199
- # evtl. andere Abhängigkeiten
3200
- gem 'haml' # z.B. wenn du Haml verwendest...
3201
- ```
3202
-
3203
- Beachte: Hier sollten alle Abhängigkeiten eingetragen werden. Sinatras eigene,
3204
- direkte Abhängigkeiten (Tilt und Rack) werden von Bundler automatisch aus dem
3205
- Gemfile von Sinatra hinzugefügt.
3206
-
3207
- Jetzt kannst du deine Applikation starten:
3208
-
3209
- ```shell
3210
- bundle exec ruby myapp.rb
3211
- ```
3212
-
3213
- ## Versions-Verfahren
3214
-
3215
- Sinatra folgt dem sogenannten [Semantic Versioning](http://semver.org/), d.h.
3216
- SemVer und SemVerTag.
3217
-
3218
- ## Mehr
3219
-
3220
- * [Projekt-Website](http://www.sinatrarb.com/) - Ergänzende Dokumentation,
3221
- News und Links zu anderen Ressourcen.
3222
- * [Mitmachen](http://www.sinatrarb.com/contributing.html) - Einen Fehler
3223
- gefunden? Brauchst du Hilfe? Hast du einen Patch?
3224
- * [Issue-Tracker](https://github.com/sinatra/sinatra/issues)
3225
- * [Twitter](https://twitter.com/sinatra)
3226
- * [Mailing-Liste](http://groups.google.com/group/sinatrarb)
3227
- * IRC [#sinatra](irc://chat.freenode.net/#sinatra) auf
3228
- http://freenode.net Es gibt dort auch immer wieder deutschsprachige
3229
- Entwickler, die gerne weiterhelfen.
3230
- * [Sinatra & Friends](https://sinatrarb.slack.com) on Slack and see
3231
- [here](https://sinatra-slack.herokuapp.com/) for an invite.
3232
- * [Sinatra Book](https://github.com/sinatra/sinatra-book/) Kochbuch Tutorial
3233
- * [Sinatra Recipes](http://recipes.sinatrarb.com/) Sinatra-Rezepte aus der
3234
- Community
3235
- * API Dokumentation für die
3236
- [aktuelle Version](http://www.rubydoc.info//gems/sinatra) oder für
3237
- [HEAD](http://www.rubydoc.info/github/sinatra/sinatra) auf
3238
- http://rubydoc.info
3239
- * [CI Server](https://travis-ci.org/sinatra/sinatra)