sinatra 2.0.0.beta2 → 2.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sinatra might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/Gemfile +4 -1
- data/LICENSE +2 -1
- data/README.de.md +640 -432
- data/README.es.md +1 -1
- data/README.hu.md +34 -0
- data/README.ja.md +86 -39
- data/README.md +407 -328
- data/README.ru.md +0 -38
- data/Rakefile +3 -2
- data/lib/sinatra/base.rb +38 -31
- data/lib/sinatra/show_exceptions.rb +55 -47
- data/lib/sinatra/version.rb +1 -1
- data/sinatra.gemspec +2 -2
- metadata +6 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 26f095dff5ea1010cfcf4cb7059a25aadf478a5c
|
4
|
+
data.tar.gz: 72d51178bb74784cda5ed6fd22dff39782510730
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 56d6d5c81311d1b54cb9beabf7f328ff8949796f4c91c1891006d81b1782e3be438cd87d07e8945489ee47fd565b94f09df02128986c71889fe7c21b338311ee
|
7
|
+
data.tar.gz: 6b12c4051b97b9fb4b752d282e66c587ac248c95fa7332b4c9aee248ac5df1ef7cbc9b44a02a70de0868fc69e47bacd6e575276471256e15a8222df75420bea2
|
data/CHANGELOG.md
CHANGED
@@ -28,6 +28,14 @@
|
|
28
28
|
|
29
29
|
* Ensure template is cached only once #1021 by Patrik Rak.
|
30
30
|
|
31
|
+
* Rack middleware is initialized at server runtime rather than after receiving first request #1205 by Itamar Turner-Trauring.
|
32
|
+
|
33
|
+
* Improve Session Secret documentation to encourage better security practices #1218 by Glenn Rempe
|
34
|
+
|
35
|
+
* Exposed global and per-route options for Mustermann route parsing #1233 by Mike Pastore
|
36
|
+
|
37
|
+
* Use same `session_secret` for classic and modular apps in development #1245 by Marcus Stollsteimer
|
38
|
+
|
31
39
|
## 1.4.7 / 2016-01-24
|
32
40
|
|
33
41
|
* Add Ashley Williams, Trevor Bramble, and Kashyap Kondamudi to team Sinatra.
|
data/Gemfile
CHANGED
@@ -11,13 +11,15 @@ source 'https://rubygems.org' unless ENV['QUICK']
|
|
11
11
|
gemspec
|
12
12
|
|
13
13
|
gem 'rake'
|
14
|
-
gem 'rack',
|
14
|
+
gem 'rack', git: 'https://github.com/rack/rack.git'
|
15
15
|
gem 'rack-test', '>= 0.6.2'
|
16
16
|
gem "minitest", "~> 5.0"
|
17
17
|
|
18
18
|
gem "rack-protection", path: "rack-protection"
|
19
19
|
gem "sinatra-contrib", path: "sinatra-contrib"
|
20
20
|
|
21
|
+
gem "twitter-text", "1.14.0"
|
22
|
+
|
21
23
|
if RUBY_ENGINE == 'jruby'
|
22
24
|
gem 'nokogiri', '!= 1.5.0'
|
23
25
|
gem 'trinidad'
|
@@ -54,6 +56,7 @@ if RUBY_ENGINE == "ruby"
|
|
54
56
|
gem 'sass'
|
55
57
|
gem 'reel-rack'
|
56
58
|
gem 'celluloid', '~> 0.16.0'
|
59
|
+
gem 'simplecov', require: false
|
57
60
|
end
|
58
61
|
|
59
62
|
if RUBY_ENGINE == "rbx"
|
data/LICENSE
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
Copyright (c) 2007, 2008, 2009 Blake Mizerany
|
2
|
-
Copyright (c) 2010
|
2
|
+
Copyright (c) 2010-2017 Konstantin Haase
|
3
|
+
Copyright (c) 2015-2017 Zachary Scott
|
3
4
|
|
4
5
|
Permission is hereby granted, free of charge, to any person
|
5
6
|
obtaining a copy of this software and associated documentation
|
data/README.de.md
CHANGED
@@ -1,28 +1,31 @@
|
|
1
1
|
# Sinatra
|
2
2
|
|
3
|
+
[![Build Status](https://secure.travis-ci.org/sinatra/sinatra.svg)](http://travis-ci.org/sinatra/sinatra)
|
4
|
+
|
3
5
|
*Wichtig: Dieses Dokument ist eine Übersetzung aus dem Englischen und unter
|
4
|
-
Umständen nicht auf dem aktuellen Stand (aktuell Sinatra
|
6
|
+
Umständen nicht auf dem aktuellen Stand (aktuell Sinatra 2.0
|
7
|
+
Vorabausgabe).*
|
5
8
|
|
6
9
|
Sinatra ist eine
|
7
10
|
[DSL](https://de.wikipedia.org/wiki/Domänenspezifische_Sprache), die das
|
8
11
|
schnelle Erstellen von Webanwendungen in Ruby mit minimalem Aufwand
|
9
12
|
ermöglicht:
|
10
13
|
|
11
|
-
Sinatra via `rubygems` installieren:
|
12
|
-
|
13
|
-
```shell
|
14
|
-
gem install sinatra
|
15
|
-
```
|
16
|
-
|
17
|
-
Eine Datei mit dem Namen `myapp.rb` erstellen:
|
18
|
-
|
19
14
|
```ruby
|
15
|
+
# myapp.rb
|
20
16
|
require 'sinatra'
|
17
|
+
|
21
18
|
get '/' do
|
22
19
|
'Hallo Welt!'
|
23
20
|
end
|
24
21
|
```
|
25
22
|
|
23
|
+
Sinatra-Gem installieren:
|
24
|
+
|
25
|
+
```shell
|
26
|
+
gem install sinatra
|
27
|
+
```
|
28
|
+
|
26
29
|
und im gleichen Verzeichnis ausführen:
|
27
30
|
|
28
31
|
```shell
|
@@ -32,98 +35,104 @@ ruby myapp.rb
|
|
32
35
|
Die Seite kann nun unter [http://localhost:4567](http://localhost:4567)
|
33
36
|
aufgerufen werden.
|
34
37
|
|
38
|
+
Es wird empfohlen `gem installl thin` auszuführen, Sinatra wird dann
|
39
|
+
diesen Server verwenden.
|
40
|
+
|
35
41
|
## Inhalt
|
36
42
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
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)
|
122
131
|
|
123
132
|
## Routen
|
124
133
|
|
125
|
-
In Sinatra wird eine Route durch eine HTTP-Methode und ein URL-Muster
|
126
|
-
Jeder dieser Routen wird ein Ruby-Block zugeordnet:
|
134
|
+
In Sinatra wird eine Route durch eine HTTP-Methode und ein URL-Muster
|
135
|
+
definiert. Jeder dieser Routen wird ein Ruby-Block zugeordnet:
|
127
136
|
|
128
137
|
```ruby
|
129
138
|
get '/' do
|
@@ -158,6 +167,14 @@ end
|
|
158
167
|
Die Routen werden in der Reihenfolge durchlaufen, in der sie definiert wurden.
|
159
168
|
Das erste Routen-Muster, das mit dem Request übereinstimmt, wird ausgeführt.
|
160
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
|
+
|
161
178
|
Die Muster der Routen können benannte Parameter beinhalten, die über den
|
162
179
|
`params`-Hash zugänglich gemacht werden:
|
163
180
|
|
@@ -213,6 +230,7 @@ Und auch hier können Block-Parameter genutzt werden:
|
|
213
230
|
|
214
231
|
```ruby
|
215
232
|
get %r{/hallo/([\w]+)} do |c|
|
233
|
+
# erkennt "GET /hallo/frank" oder "GET /sag/hallo/frank" usw.
|
216
234
|
"Hallo, #{c}!"
|
217
235
|
end
|
218
236
|
```
|
@@ -230,10 +248,11 @@ Routen können auch den query-Parameter verwenden:
|
|
230
248
|
|
231
249
|
```ruby
|
232
250
|
get '/posts' do
|
233
|
-
#
|
251
|
+
# passt zu "GET /posts?title=foo&author=bar"
|
234
252
|
title = params['title']
|
235
253
|
author = params['author']
|
236
|
-
#
|
254
|
+
# verwendet title- und author-Variablen. Der query-Parameter ist für
|
255
|
+
# die /post-Route optional
|
237
256
|
end
|
238
257
|
```
|
239
258
|
|
@@ -241,6 +260,20 @@ Anmerkung: Solange man den sog. Path Traversal Attack-Schutz nicht deaktiviert
|
|
241
260
|
(siehe weiter unten), kann es sein, dass der Request-Pfad noch vor dem
|
242
261
|
Abgleich mit den Routen modifiziert wird.
|
243
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
|
+
|
244
277
|
### Bedingungen
|
245
278
|
|
246
279
|
An Routen können eine Vielzahl von Bedingungen geknüpft werden, die erfüllt
|
@@ -261,7 +294,7 @@ get '/foo' do
|
|
261
294
|
end
|
262
295
|
```
|
263
296
|
|
264
|
-
Andere
|
297
|
+
Andere verfügbare Bedingungen sind `:host_name` und `:provides`:
|
265
298
|
|
266
299
|
```ruby
|
267
300
|
get '/', :host_name => /^admin\./ do
|
@@ -296,7 +329,7 @@ Bei Bedingungen, die mehrere Werte annehmen können, sollte ein Splat verwendet
|
|
296
329
|
werden:
|
297
330
|
|
298
331
|
```ruby
|
299
|
-
set(:auth) do |*roles|
|
332
|
+
set(:auth) do |*roles| # <- hier kommt der Splat ins Spiel
|
300
333
|
condition do
|
301
334
|
unless logged_in? && roles.any? {|role| current_user.in_role? role }
|
302
335
|
redirect "/login/", 303
|
@@ -377,7 +410,8 @@ get all_but("/index") do
|
|
377
410
|
end
|
378
411
|
```
|
379
412
|
|
380
|
-
Beachte, dass das obige Beispiel etwas übertrieben wirkt. Es geht auch
|
413
|
+
Beachte, dass das obige Beispiel etwas übertrieben wirkt. Es geht auch
|
414
|
+
einfacher:
|
381
415
|
|
382
416
|
```ruby
|
383
417
|
get // do
|
@@ -403,8 +437,9 @@ einen anderen Ort zu definieren, indem man die `:public_folder`-Option setzt:
|
|
403
437
|
set :public_folder, File.dirname(__FILE__) + '/static'
|
404
438
|
```
|
405
439
|
|
406
|
-
Zu beachten ist, dass der Ordnername `public` nicht Teil der URL ist.
|
407
|
-
`./public/css/style.css` ist unter
|
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.
|
408
443
|
|
409
444
|
Um den `Cache-Control`-Header mit Informationen zu versorgen, verwendet man
|
410
445
|
die `:static_cache_control`-Einstellung (s.u.).
|
@@ -422,7 +457,8 @@ end
|
|
422
457
|
|
423
458
|
Dieses Beispiel rendert `views/index.erb`.
|
424
459
|
|
425
|
-
Anstelle eines Templatenamens kann man auch direkt die Templatesprache
|
460
|
+
Anstelle eines Templatenamens kann man auch direkt die Templatesprache
|
461
|
+
verwenden:
|
426
462
|
|
427
463
|
```ruby
|
428
464
|
get '/' do
|
@@ -517,14 +553,15 @@ befinden. Es kann jedoch ein anderer Ordner festgelegt werden:
|
|
517
553
|
set :views, settings.root + '/templates'
|
518
554
|
```
|
519
555
|
|
520
|
-
Es ist zu beachten, dass immer mit Symbolen auf Templates verwiesen
|
521
|
-
auch dann, wenn sie sich in einem Unterordner befinden:
|
556
|
+
Es ist zu beachten, dass immer mit Symbolen auf Templates verwiesen
|
557
|
+
werden muss, auch dann, wenn sie sich in einem Unterordner befinden:
|
522
558
|
|
523
559
|
```ruby
|
524
560
|
haml :'unterverzeichnis/template'
|
525
561
|
```
|
526
562
|
|
527
|
-
Rendering-
|
563
|
+
Wird einer Rendering-Methode ein String übergeben, wird dieser direkt
|
564
|
+
gerendert.
|
528
565
|
|
529
566
|
### Direkte Templates
|
530
567
|
|
@@ -536,6 +573,16 @@ end
|
|
536
573
|
|
537
574
|
Hier wird der String direkt gerendert.
|
538
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
|
+
|
539
586
|
### Verfügbare Templatesprachen
|
540
587
|
|
541
588
|
Einige Sprachen haben mehrere Implementierungen. Um festzulegen, welche
|
@@ -944,10 +991,10 @@ aufrufen kann:
|
|
944
991
|
%p= creole(:Grüße)
|
945
992
|
```
|
946
993
|
|
947
|
-
Da man Ruby nicht von Creole heraus aufrufen kann, können auch Layouts
|
948
|
-
Creole geschrieben werden. Es ist aber möglich, einen Renderer
|
949
|
-
zu verwenden und einen anderen für das Layout, indem
|
950
|
-
verwendet wird.
|
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.
|
951
998
|
|
952
999
|
#### MediaWiki Templates
|
953
1000
|
|
@@ -966,9 +1013,9 @@ verwendet wird.
|
|
966
1013
|
</tr>
|
967
1014
|
</table>
|
968
1015
|
|
969
|
-
Da man aus dem Mediawiki-Template heraus keine Ruby-Methoden aufrufen
|
970
|
-
keine locals verwenden kann, wird man Mediawiki üblicherweise
|
971
|
-
anderen Renderern verwenden wollen:
|
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:
|
972
1019
|
|
973
1020
|
```ruby
|
974
1021
|
erb :overview, :locals => { :text => mediawiki(:introduction) }
|
@@ -982,10 +1029,10 @@ heraus aufrufen:
|
|
982
1029
|
%p= mediawiki(:greetings)
|
983
1030
|
```
|
984
1031
|
|
985
|
-
Da man Ruby nicht von MediaWiki heraus aufrufen kann, können auch
|
986
|
-
in MediaWiki geschrieben werden. Es ist aber möglich,
|
987
|
-
Templates zu verwenden und einen anderen für das
|
988
|
-
`:layout_engine`-Option verwendet wird.
|
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.
|
989
1036
|
|
990
1037
|
#### CoffeeScript Templates
|
991
1038
|
|
@@ -1131,9 +1178,9 @@ Templates eingesetzt.
|
|
1131
1178
|
|
1132
1179
|
### Templates mit `yield` und verschachtelte Layouts
|
1133
1180
|
|
1134
|
-
Ein Layout ist üblicherweise ein Template, das ein `yield` aufruft. Ein
|
1135
|
-
Template kann entweder wie oben beschrieben über die `:template`
|
1136
|
-
verwendet werden oder mit einem Block gerendert werden:
|
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:
|
1137
1184
|
|
1138
1185
|
```ruby
|
1139
1186
|
erb :post, :layout => false do
|
@@ -1185,13 +1232,13 @@ __END__
|
|
1185
1232
|
= yield
|
1186
1233
|
|
1187
1234
|
@@ index
|
1188
|
-
%div.title Hallo Welt
|
1235
|
+
%div.title Hallo Welt
|
1189
1236
|
```
|
1190
1237
|
|
1191
1238
|
Anmerkung: Inline-Templates, die in der Datei definiert sind, die `require
|
1192
1239
|
'sinatra'` aufruft, werden automatisch geladen. Um andere Inline-Templates in
|
1193
|
-
|
1194
|
-
werden.
|
1240
|
+
weiteren Dateien aufzurufen, muss explizit `enable :inline_templates`
|
1241
|
+
verwendet werden.
|
1195
1242
|
|
1196
1243
|
### Benannte Templates
|
1197
1244
|
|
@@ -1199,7 +1246,7 @@ Templates können auch mit der Top-Level `template`-Methode definiert werden:
|
|
1199
1246
|
|
1200
1247
|
```ruby
|
1201
1248
|
template :layout do
|
1202
|
-
"%html\n
|
1249
|
+
"%html\n =yield\n"
|
1203
1250
|
end
|
1204
1251
|
|
1205
1252
|
template :index do
|
@@ -1212,7 +1259,9 @@ end
|
|
1212
1259
|
```
|
1213
1260
|
|
1214
1261
|
Wenn ein Template mit dem Namen "layout" existiert, wird es bei jedem Aufruf
|
1215
|
-
verwendet. Durch `:layout => false` kann das Ausführen
|
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`:
|
1216
1265
|
|
1217
1266
|
```ruby
|
1218
1267
|
get '/' do
|
@@ -1299,6 +1348,10 @@ after do
|
|
1299
1348
|
end
|
1300
1349
|
```
|
1301
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
|
+
|
1302
1355
|
Filter können optional auch mit einem Muster ausgestattet werden, das auf den
|
1303
1356
|
Request-Pfad passen muss, damit der Filter ausgeführt wird:
|
1304
1357
|
|
@@ -1342,30 +1395,30 @@ get '/:name' do
|
|
1342
1395
|
end
|
1343
1396
|
```
|
1344
1397
|
|
1345
|
-
|
1346
|
-
Sessions werden verwendet, um Zustände zwischen den Requests zu speichern. Sind
|
1347
|
-
sie aktiviert, kann ein Session-Hash je Benutzer-Session verwendet werden:
|
1398
|
+
Ebenso können Helfer auch in einem eigenen Modul definiert werden:
|
1348
1399
|
|
1349
1400
|
```ruby
|
1350
|
-
|
1351
|
-
|
1352
|
-
get '/' do
|
1353
|
-
"value = " << session[:value].inspect
|
1401
|
+
module FooUtils
|
1402
|
+
def foo(name) "#{name}foo" end
|
1354
1403
|
end
|
1355
1404
|
|
1356
|
-
|
1357
|
-
|
1405
|
+
module BarUtils
|
1406
|
+
def bar(name) "#{name}bar" end
|
1358
1407
|
end
|
1408
|
+
|
1409
|
+
helpers FooUtils, BarUtils
|
1359
1410
|
```
|
1360
1411
|
|
1361
|
-
|
1362
|
-
|
1363
|
-
|
1364
|
-
|
1365
|
-
|
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:
|
1366
1419
|
|
1367
1420
|
```ruby
|
1368
|
-
|
1421
|
+
enable :sessions
|
1369
1422
|
|
1370
1423
|
get '/' do
|
1371
1424
|
"value = " << session[:value].inspect
|
@@ -1376,30 +1429,130 @@ get '/:value' do
|
|
1376
1429
|
end
|
1377
1430
|
```
|
1378
1431
|
|
1379
|
-
Um die Sicherheit zu erhöhen, werden
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1383
|
-
|
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, zufällige Zeichenfolgen zu erstellen.
|
1442
|
+
|
1443
|
+
Sinatra generiert automatisch einen zufälligen 32 Byte langen zufälligen
|
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 abgelgegt 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:
|
1384
1497
|
|
1385
1498
|
```ruby
|
1386
|
-
|
1499
|
+
require 'securerandom'
|
1500
|
+
# -or- require 'sysrandom/securerandom'
|
1501
|
+
set :session_secret, ENV.fetch('SESSION_SECRET') { SecureRandom.hex(64) }
|
1387
1502
|
```
|
1388
1503
|
|
1389
|
-
|
1390
|
-
|
1504
|
+
#### Sitzungseinstellungen
|
1505
|
+
|
1506
|
+
Im Options-Hash können weitere Einstellungen abgelegt werden:
|
1391
1507
|
|
1392
1508
|
```ruby
|
1393
1509
|
set :sessions, :domain => 'foo.com'
|
1394
1510
|
```
|
1395
1511
|
|
1396
|
-
Um
|
1397
|
-
|
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:
|
1398
1534
|
|
1399
1535
|
```ruby
|
1400
|
-
set :sessions, :
|
1536
|
+
set :sessions, :expire_after => 2592000
|
1537
|
+
set :session_store, Rack::Session::Pool
|
1401
1538
|
```
|
1402
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
|
+
|
1403
1556
|
### Anhalten
|
1404
1557
|
|
1405
1558
|
Zum sofortigen Stoppen eines Request in einem Filter oder einer Route:
|
@@ -1482,13 +1635,15 @@ Wenn der Request innerhalb derselben Applikations-Instanz aufgerufen und keine
|
|
1482
1635
|
Kopie der Instanz erzeugt werden soll, kann `call!` anstelle von `call`
|
1483
1636
|
verwendet werden.
|
1484
1637
|
|
1638
|
+
Weitere Informationen zu `call` finden sich in den Rack-Spezifikationen.
|
1639
|
+
|
1485
1640
|
### Body, Status-Code und Header setzen
|
1486
1641
|
|
1487
|
-
Es ist möglich und empfohlen, den Status-Code sowie den Response-Body mit
|
1488
|
-
Returnwert in der Route zu setzen. In manchen Situationen kann es
|
1489
|
-
dass der Body an anderer Stelle während der Ausführung gesetzt
|
1490
|
-
Dafür kann man die Helfer-Methode `body` einsetzen. Ist sie
|
1491
|
-
einem späteren Zeitpunkt aufgerufen werden:
|
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:
|
1492
1647
|
|
1493
1648
|
```ruby
|
1494
1649
|
get '/foo' do
|
@@ -1525,14 +1680,14 @@ In manchen Situationen sollen Daten bereits an den Client zurückgeschickt
|
|
1525
1680
|
werden, bevor ein vollständiger Response bereit steht. Manchmal will man die
|
1526
1681
|
Verbindung auch erst dann beenden und Daten so lange an den Client
|
1527
1682
|
zurückschicken, bis er die Verbindung abbricht. Für diese Fälle gibt es die
|
1528
|
-
`stream`-Helfer-Methode, die es einem erspart eigene Lösungen zu schreiben:
|
1683
|
+
`stream`-Helfer-Methode, die es einem erspart, eigene Lösungen zu schreiben:
|
1529
1684
|
|
1530
1685
|
```ruby
|
1531
1686
|
get '/' do
|
1532
1687
|
stream do |out|
|
1533
1688
|
out << "Das ist ja mal wieder fanta -\n"
|
1534
1689
|
sleep 0.5
|
1535
|
-
out << " (bitte warten…) \n"
|
1690
|
+
out << " (bitte warten …) \n"
|
1536
1691
|
sleep 1
|
1537
1692
|
out << "- stisch!\n"
|
1538
1693
|
end
|
@@ -1541,8 +1696,8 @@ end
|
|
1541
1696
|
|
1542
1697
|
Damit lassen sich Streaming-APIs realisieren, sog.
|
1543
1698
|
[Server Sent Events](https://w3c.github.io/eventsource/), die als Basis für
|
1544
|
-
[WebSockets](https://en.wikipedia.org/wiki/WebSocket) dienen. Ebenso können
|
1545
|
-
verwendet werden, um den Durchsatz zu erhöhen, wenn ein Teil der Daten von
|
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
|
1546
1701
|
langsamen Ressourcen abhängig ist.
|
1547
1702
|
|
1548
1703
|
Es ist zu beachten, dass das Verhalten beim Streaming, insbesondere die Anzahl
|
@@ -1553,11 +1708,11 @@ unterstützen, wird ein vollständiger Response-Body zurückgeschickt, sobald de
|
|
1553
1708
|
an `stream` weitergegebene Block abgearbeitet ist. Mit Shotgun funktioniert
|
1554
1709
|
Streaming z.B. überhaupt nicht.
|
1555
1710
|
|
1556
|
-
Ist der optionale Parameter `keep_open` aktiviert, wird beim gestreamten
|
1557
|
-
`close` nicht aufgerufen und es ist einem überlassen dies an einem
|
1558
|
-
späteren Zeitpunkt nachholen. Die Funktion ist jedoch nur bei
|
1559
|
-
Serven wie Thin oder Rainbows möglich, andere Server werden
|
1560
|
-
beenden:
|
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:
|
1561
1716
|
|
1562
1717
|
```ruby
|
1563
1718
|
# Durchgehende Anfrage (long polling)
|
@@ -1589,10 +1744,14 @@ post '/:message' do
|
|
1589
1744
|
end
|
1590
1745
|
```
|
1591
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
|
+
|
1592
1751
|
### Logger
|
1593
1752
|
|
1594
|
-
Im Geltungsbereich eines Request stellt die `logger` Helfer-Methode eine
|
1595
|
-
Instanz zur Verfügung:
|
1753
|
+
Im Geltungsbereich eines Request stellt die `logger` Helfer-Methode eine
|
1754
|
+
`Logger` Instanz zur Verfügung:
|
1596
1755
|
|
1597
1756
|
```ruby
|
1598
1757
|
get '/' do
|
@@ -1602,8 +1761,9 @@ end
|
|
1602
1761
|
```
|
1603
1762
|
|
1604
1763
|
Der Logger übernimmt dabei automatisch alle im Rack-Handler eingestellten
|
1605
|
-
Log-Vorgaben. Ist Loggen ausgeschaltet, gibt die Methode ein Leerobjekt
|
1606
|
-
In den Routen und Filtern muss man sich also nicht weiter darum
|
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.
|
1607
1767
|
|
1608
1768
|
Beachte, dass das Loggen standardmäßig nur für `Sinatra::Application`
|
1609
1769
|
voreingestellt ist. Wird über `Sinatra::Base` vererbt, muss es erst aktiviert
|
@@ -1611,7 +1771,7 @@ werden:
|
|
1611
1771
|
|
1612
1772
|
```ruby
|
1613
1773
|
class MyApp < Sinatra::Base
|
1614
|
-
configure :production, :development
|
1774
|
+
configure :production, :development do
|
1615
1775
|
enable :logging
|
1616
1776
|
end
|
1617
1777
|
end
|
@@ -1619,9 +1779,9 @@ end
|
|
1619
1779
|
|
1620
1780
|
Damit auch keine Middleware das Logging aktivieren kann, muss die `logging`
|
1621
1781
|
Einstellung auf `nil` gesetzt werden. Das heißt aber auch, dass `logger` in
|
1622
|
-
diesem Fall `nil` zurückgeben wird. Üblicherweise wird das eingesetzt, wenn
|
1623
|
-
eigener Logger eingerichtet werden soll. Sinatra wird dann verwenden, was
|
1624
|
-
`env['rack.logger']` eingetragen ist.
|
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.
|
1625
1785
|
|
1626
1786
|
### Mime-Types
|
1627
1787
|
|
@@ -1646,8 +1806,8 @@ end
|
|
1646
1806
|
|
1647
1807
|
### URLs generieren
|
1648
1808
|
|
1649
|
-
Zum Generieren von URLs sollte die `url`-Helfer-Methode genutzen werden, so
|
1650
|
-
beim Einsatz von Haml:
|
1809
|
+
Zum Generieren von URLs sollte die `url`-Helfer-Methode genutzen werden, so
|
1810
|
+
z.B. beim Einsatz von Haml:
|
1651
1811
|
|
1652
1812
|
```ruby
|
1653
1813
|
%a{:href => url('/foo')} foo
|
@@ -1655,7 +1815,8 @@ beim Einsatz von Haml:
|
|
1655
1815
|
|
1656
1816
|
Soweit vorhanden, wird Rücksicht auf Proxys und Rack-Router genommen.
|
1657
1817
|
|
1658
|
-
Diese Methode ist ebenso über das Alias `to` zu erreichen (siehe Beispiel
|
1818
|
+
Diese Methode ist ebenso über das Alias `to` zu erreichen (siehe Beispiel
|
1819
|
+
unten).
|
1659
1820
|
|
1660
1821
|
### Browser-Umleitung
|
1661
1822
|
|
@@ -1733,8 +1894,8 @@ before do
|
|
1733
1894
|
end
|
1734
1895
|
```
|
1735
1896
|
|
1736
|
-
Bei Verwendung der `expires`-Helfermethode zum Setzen des gleichnamigen
|
1737
|
-
wird `Cache-Control` automatisch eigestellt:
|
1897
|
+
Bei Verwendung der `expires`-Helfermethode zum Setzen des gleichnamigen
|
1898
|
+
Headers, wird `Cache-Control` automatisch eigestellt:
|
1738
1899
|
|
1739
1900
|
```ruby
|
1740
1901
|
before do
|
@@ -1743,7 +1904,7 @@ end
|
|
1743
1904
|
```
|
1744
1905
|
|
1745
1906
|
Um alles richtig zu machen, sollten auch `etag` oder `last_modified` verwendet
|
1746
|
-
werden. Es wird empfohlen, dass diese Helfer aufgerufen werden
|
1907
|
+
werden. Es wird empfohlen, dass diese Helfer aufgerufen werden *bevor* die
|
1747
1908
|
eigentliche Arbeit anfängt, da sie sofort eine Antwort senden, wenn der Client
|
1748
1909
|
eine aktuelle Version im Cache vorhält:
|
1749
1910
|
|
@@ -1781,16 +1942,16 @@ get '/' do
|
|
1781
1942
|
end
|
1782
1943
|
```
|
1783
1944
|
|
1784
|
-
Um den `Cache-Control`-Header mit Informationen zu versorgen, verwendet man
|
1785
|
-
`:static_cache_control`-Einstellung (s.u.).
|
1945
|
+
Um den `Cache-Control`-Header mit Informationen zu versorgen, verwendet man
|
1946
|
+
die `:static_cache_control`-Einstellung (s.u.).
|
1786
1947
|
|
1787
|
-
Nach RFC 2616 sollte sich die Anwendung anders verhalten, wenn ein If-Match
|
1788
|
-
ein If-
|
1789
|
-
Resource bereits existiert. Sinatra geht davon aus, dass Ressourcen bei
|
1790
|
-
Anfragen (z.B. bei get oder Idempotenten Anfragen wie put) bereits
|
1791
|
-
wobei anderen Ressourcen (besipielsweise bei post), als neue
|
1792
|
-
behandelt werden. Dieses Verhalten lässt sich mit der
|
1793
|
-
ändern:
|
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:
|
1794
1955
|
|
1795
1956
|
```ruby
|
1796
1957
|
get '/create' do
|
@@ -1826,33 +1987,35 @@ send_file 'foo.png', :type => :jpg
|
|
1826
1987
|
|
1827
1988
|
<dl>
|
1828
1989
|
<dt>filename</dt>
|
1829
|
-
|
1990
|
+
<dd>Dateiname als Response.
|
1991
|
+
Standardwert ist der eigentliche Dateiname.</dd>
|
1830
1992
|
|
1831
1993
|
<dt>last_modified</dt>
|
1832
|
-
|
1994
|
+
<dd>Wert für den Last-Modified-Header, Standardwert ist <tt>mtime</tt> der
|
1833
1995
|
Datei.</dd>
|
1834
1996
|
|
1835
1997
|
<dt>type</dt>
|
1836
|
-
|
1837
|
-
der Dateiendung abgeleitet.</dd>
|
1998
|
+
<dd>Content-Type, der verwendet werden soll. Wird, wenn nicht angegeben,
|
1999
|
+
von der Dateiendung abgeleitet.</dd>
|
1838
2000
|
|
1839
2001
|
<dt>disposition</dt>
|
1840
|
-
|
2002
|
+
<dd>Verwendet für Content-Disposition. Mögliche Werte sind: <tt>nil</tt>
|
1841
2003
|
(Standard), <tt>:attachment</tt> und <tt>:inline</tt>.</dd>
|
1842
2004
|
|
1843
2005
|
<dt>length</dt>
|
1844
|
-
|
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>
|
1845
2013
|
</dl>
|
1846
2014
|
|
1847
|
-
Soweit vom Rack-Handler unterstützt, werden neben der Übertragung über den
|
1848
|
-
Ruby-Prozess auch andere Möglichkeiten genutzt. Bei Verwendung der
|
1849
|
-
`send_file`-Helfer-Methode kümmert sich Sinatra selbstständig um die
|
1850
|
-
Range-Requests.
|
1851
|
-
|
1852
2015
|
### Das Request-Objekt
|
1853
2016
|
|
1854
2017
|
Auf das `request`-Objekt der eigehenden Anfrage kann vom Anfrage-Scope aus
|
1855
|
-
zugegriffen werden:
|
2018
|
+
zugegriffen werden (d.h. Filter, Routen, Fehlerbehandlung):
|
1856
2019
|
|
1857
2020
|
```ruby
|
1858
2021
|
# App läuft unter http://example.com/example
|
@@ -1931,18 +2094,18 @@ end
|
|
1931
2094
|
|
1932
2095
|
### Umgang mit Datum und Zeit
|
1933
2096
|
|
1934
|
-
Sinatra bietet eine `time_for`-Helfer-Methode, die aus einem gegebenen Wert
|
1935
|
-
Time-Objekt generiert. Ebenso kann sie nach `DateTime`, `Date` und
|
1936
|
-
Klassen konvertieren:
|
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:
|
1937
2100
|
|
1938
2101
|
```ruby
|
1939
2102
|
get '/' do
|
1940
|
-
pass if Time.now > time_for('Dec 23,
|
2103
|
+
pass if Time.now > time_for('Dec 23, 2016')
|
1941
2104
|
"noch Zeit"
|
1942
2105
|
end
|
1943
2106
|
```
|
1944
2107
|
|
1945
|
-
Diese Methode wird intern für
|
2108
|
+
Diese Methode wird intern für `expires`, `last_modiefied` und ihresgleichen
|
1946
2109
|
verwendet. Mit ein paar Handgriffen lässt sich diese Methode also in ihrem
|
1947
2110
|
Verhalten erweitern, indem man `time_for` in der eigenen Applikation
|
1948
2111
|
überschreibt:
|
@@ -1967,8 +2130,8 @@ end
|
|
1967
2130
|
|
1968
2131
|
### Nachschlagen von Template-Dateien
|
1969
2132
|
|
1970
|
-
Die `find_template`-Helfer-Methode wird genutzt, um Template-Dateien zum
|
1971
|
-
aufzufinden:
|
2133
|
+
Die `find_template`-Helfer-Methode wird genutzt, um Template-Dateien zum
|
2134
|
+
Rendern aufzufinden:
|
1972
2135
|
|
1973
2136
|
```ruby
|
1974
2137
|
find_template settings.views, 'foo', Tilt[:haml] do |file|
|
@@ -1976,9 +2139,9 @@ find_template settings.views, 'foo', Tilt[:haml] do |file|
|
|
1976
2139
|
end
|
1977
2140
|
```
|
1978
2141
|
|
1979
|
-
Das ist zwar nicht wirklich brauchbar, aber wenn man sie überschreibt, kann
|
1980
|
-
nützlich werden, um eigene Nachschlage-Mechanismen einzubauen. Zum
|
1981
|
-
dann, wenn mehr als nur ein view-Verzeichnis verwendet werden soll:
|
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:
|
1982
2145
|
|
1983
2146
|
```ruby
|
1984
2147
|
set :views, ['views', 'templates']
|
@@ -2008,13 +2171,13 @@ end
|
|
2008
2171
|
Ebensogut könnte eine Extension aber auch geschrieben und mit anderen geteilt
|
2009
2172
|
werden!
|
2010
2173
|
|
2011
|
-
Beachte, dass `find_template` nicht prüft, ob eine Datei tatsächlich
|
2012
|
-
Es wird lediglich der angegebene Block aufgerufen und nach allen
|
2013
|
-
Pfaden gesucht. Das ergibt kein Performance-Problem, da `render`
|
2014
|
-
verwendet, sobald eine Datei gefunden wurde. Ebenso werden
|
2015
|
-
Inhalt gecached, solange nicht im Entwicklungsmodus
|
2016
|
-
im Hinterkopf behalten werden, wenn irgendwelche
|
2017
|
-
|
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 Inhalt gecached, solange nicht im Entwicklungsmodus
|
2179
|
+
gearbeitet wird. Das sollte im Hinterkopf behalten werden, wenn irgendwelche
|
2180
|
+
verrückten Methoden zusammengebastelt werden.
|
2018
2181
|
|
2019
2182
|
### Konfiguration
|
2020
2183
|
|
@@ -2039,7 +2202,7 @@ configure do
|
|
2039
2202
|
end
|
2040
2203
|
```
|
2041
2204
|
|
2042
|
-
Läuft nur, wenn die Umgebung (APP_ENV
|
2205
|
+
Läuft nur, wenn die Umgebung (`APP_ENV`-Umgebungsvariable) auf `:production`
|
2043
2206
|
gesetzt ist:
|
2044
2207
|
|
2045
2208
|
```ruby
|
@@ -2097,143 +2260,235 @@ Schutzmechanismen zu deaktivieren:
|
|
2097
2260
|
set :protection, :except => [:path_traversal, :session_hijacking]
|
2098
2261
|
```
|
2099
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
|
+
|
2100
2275
|
#### Mögliche Einstellungen
|
2101
2276
|
|
2102
2277
|
<dl>
|
2103
2278
|
<dt>absolute_redirects</dt>
|
2104
|
-
|
2105
|
-
|
2106
|
-
|
2107
|
-
|
2108
|
-
|
2109
|
-
|
2110
|
-
|
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>
|
2111
2292
|
|
2112
2293
|
<dt>add_charset</dt>
|
2113
|
-
|
2114
|
-
|
2115
|
-
|
2116
|
-
|
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>
|
2117
2300
|
|
2118
2301
|
<dt>app_file</dt>
|
2119
|
-
|
2120
|
-
|
2302
|
+
<dd>
|
2303
|
+
Pfad zur Hauptdatei der Applikation. Wird verwendet, um das Wurzel-,
|
2304
|
+
Inline-, View- und öffentliche Verzeichnis des Projekts festzustellen.
|
2305
|
+
</dd>
|
2121
2306
|
|
2122
2307
|
<dt>bind</dt>
|
2123
|
-
|
2124
|
-
|
2125
|
-
|
2308
|
+
<dd>
|
2309
|
+
IP-Address, 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>
|
2126
2313
|
|
2127
2314
|
<dt>default_encoding</dt>
|
2128
|
-
|
2129
|
-
|
2315
|
+
<dd>
|
2316
|
+
Das Encoding, falls keines angegeben wurde. Standardwert ist
|
2317
|
+
<tt>"utf-8"</tt>.
|
2318
|
+
</dd>
|
2130
2319
|
|
2131
2320
|
<dt>dump_errors</dt>
|
2132
|
-
|
2321
|
+
<dd>Fehler im Log anzeigen.</dd>
|
2133
2322
|
|
2134
2323
|
<dt>environment</dt>
|
2135
|
-
|
2136
|
-
|
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>
|
2137
2328
|
|
2138
2329
|
<dt>logging</dt>
|
2139
|
-
|
2330
|
+
<dd>Den Logger verwenden.</dd>
|
2140
2331
|
|
2141
2332
|
<dt>lock</dt>
|
2142
|
-
|
2143
|
-
|
2144
|
-
|
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>
|
2145
2341
|
|
2146
2342
|
<dt>method_override</dt>
|
2147
|
-
|
2148
|
-
|
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>
|
2149
2353
|
|
2150
2354
|
<dt>port</dt>
|
2151
|
-
|
2355
|
+
<dd>Port für die Applikation. Wird nur im internen Server verwendet.</dd>
|
2152
2356
|
|
2153
2357
|
<dt>prefixed_redirects</dt>
|
2154
|
-
|
2155
|
-
|
2156
|
-
|
2157
|
-
|
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>
|
2158
2365
|
|
2159
2366
|
<dt>protection</dt>
|
2160
|
-
|
2161
|
-
|
2162
|
-
|
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>
|
2163
2372
|
|
2164
2373
|
<dt>public_folder</dt>
|
2165
|
-
|
2166
|
-
|
2167
|
-
|
2168
|
-
|
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>
|
2169
2387
|
|
2170
2388
|
<dt>public_dir</dt>
|
2171
|
-
|
2389
|
+
<dd>Alias für <tt>public_folder</tt>, s.o.</dd>
|
2172
2390
|
|
2173
2391
|
<dt>reload_templates</dt>
|
2174
|
-
|
2392
|
+
<dd>
|
2393
|
+
Legt fest, ob Templates für jede Anfrage neu generiert werden. Im
|
2394
|
+
development-Modus aktiviert.
|
2395
|
+
</dd>
|
2175
2396
|
|
2176
2397
|
<dt>root</dt>
|
2177
|
-
|
2178
|
-
|
2398
|
+
<dd>
|
2399
|
+
Wurzelverzeichnis des Projekts. Leitet sich von der <tt>app_file</tt>
|
2400
|
+
Einstellung ab, wenn nicht gesetzt.
|
2401
|
+
</dd>
|
2179
2402
|
|
2180
2403
|
<dt>raise_errors</dt>
|
2181
|
-
|
2182
|
-
|
2183
|
-
|
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>
|
2184
2409
|
|
2185
2410
|
<dt>run</dt>
|
2186
|
-
|
2187
|
-
|
2411
|
+
<dd>
|
2412
|
+
Wenn aktiviert, wird Sinatra versuchen, den Webserver zu starten. Nicht
|
2413
|
+
verwenden, wenn Rackup oder anderes verwendet werden soll.
|
2414
|
+
</dd>
|
2188
2415
|
|
2189
2416
|
<dt>running</dt>
|
2190
|
-
|
2417
|
+
<dd>Läuft der eingebaute Server? Diese Einstellung nicht ändern!</dd>
|
2191
2418
|
|
2192
2419
|
<dt>server</dt>
|
2193
|
-
|
2194
|
-
|
2195
|
-
|
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>
|
2196
2425
|
|
2197
2426
|
<dt>sessions</dt>
|
2198
|
-
|
2199
|
-
|
2200
|
-
|
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>
|
2201
2439
|
|
2202
2440
|
<dt>show_exceptions</dt>
|
2203
|
-
|
2204
|
-
|
2205
|
-
|
2206
|
-
|
2207
|
-
|
2441
|
+
<dd>
|
2442
|
+
Bei Fehlern einen Stacktrace im Browseranzeigen. 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>
|
2208
2451
|
|
2209
2452
|
<dt>static</dt>
|
2210
|
-
|
2211
|
-
|
2212
|
-
|
2213
|
-
|
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>
|
2214
2460
|
|
2215
2461
|
<dt>static_cache_control</dt>
|
2216
|
-
|
2217
|
-
|
2218
|
-
|
2219
|
-
|
2220
|
-
|
2221
|
-
|
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>
|
2222
2471
|
|
2223
2472
|
<dt>threaded</dt>
|
2224
|
-
|
2225
|
-
|
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>
|
2226
2477
|
|
2227
2478
|
<dt>traps</dt>
|
2228
|
-
|
2479
|
+
<dd>Legt fest, wie Sinatra mit System-Signalen umgehen soll.</dd>
|
2229
2480
|
|
2230
2481
|
<dt>views</dt>
|
2231
|
-
|
2232
|
-
|
2482
|
+
<dd>
|
2483
|
+
Verzeichnis der Views. Leitet sich von der <tt>app_file</tt> Einstellung
|
2484
|
+
ab, wenn nicht gesetzt.
|
2485
|
+
</dd>
|
2233
2486
|
|
2234
2487
|
<dt>x_cascade</dt>
|
2235
|
-
|
2236
|
-
|
2488
|
+
<dd>
|
2489
|
+
Einstellung, ob der X-Cascade Header bei fehlender Route gesetzt
|
2490
|
+
wird oder nicht. Standardeinstellung ist <tt>true</tt>.
|
2491
|
+
</dd>
|
2237
2492
|
</dl>
|
2238
2493
|
|
2239
2494
|
## Umgebungen
|
@@ -2245,15 +2500,26 @@ In diesem Modus werden alle Templates zwischen Requests neu geladen. Dazu gibt
|
|
2245
2500
|
es besondere Fehlerseiten für 404 Stati und Fehlermeldungen. In `"production"`
|
2246
2501
|
und `"test"` werden Templates automatisch gecached.
|
2247
2502
|
|
2248
|
-
Um die Anwendung in einer anderen Umgebung auszuführen kann man die
|
2249
|
-
|
2503
|
+
Um die Anwendung in einer anderen Umgebung auszuführen, kann man die
|
2504
|
+
`APP_ENV`-Umgebungsvariable setzen:
|
2250
2505
|
|
2251
2506
|
```shell
|
2252
|
-
ruby my_app.rb
|
2507
|
+
APP_ENV=production ruby my_app.rb
|
2253
2508
|
```
|
2254
2509
|
|
2255
|
-
In der Anwendung kann man die die Methoden
|
2256
|
-
`production?` verwenden, um die aktuelle Umgebung zu erfahren
|
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
|
+
```
|
2257
2523
|
|
2258
2524
|
## Fehlerbehandlung
|
2259
2525
|
|
@@ -2333,12 +2599,12 @@ end
|
|
2333
2599
|
```
|
2334
2600
|
|
2335
2601
|
Sinatra setzt verschiedene `not_found`- und `error`-Handler in der
|
2336
|
-
Development-Umgebung ein, um hilfreiche Debugging
|
2337
|
-
anzuzeigen.
|
2602
|
+
Development-Umgebung ein, um hilfreiche Debugging-Informationen und
|
2603
|
+
Stack-Traces anzuzeigen.
|
2338
2604
|
|
2339
2605
|
## Rack-Middleware
|
2340
2606
|
|
2341
|
-
Sinatra baut auf [Rack](http://rack.github.io/), einem minimalistischen
|
2607
|
+
Sinatra baut auf [Rack](http://rack.github.io/) auf, einem minimalistischen
|
2342
2608
|
Standard-Interface für Ruby-Webframeworks. Eines der interessantesten Features
|
2343
2609
|
für Entwickler ist der Support von Middlewares, die zwischen den Server und
|
2344
2610
|
die Anwendung geschaltet werden und so HTTP-Request und/oder Antwort
|
@@ -2362,7 +2628,8 @@ end
|
|
2362
2628
|
Die Semantik von `use` entspricht der gleichnamigen Methode der
|
2363
2629
|
[Rack::Builder](http://www.rubydoc.info/github/rack/rack/master/Rack/Builder)-DSL
|
2364
2630
|
(meist verwendet in Rackup-Dateien). Ein Beispiel dafür ist, dass die
|
2365
|
-
`use`-Methode mehrere/verschiedene Argumente und auch Blöcke
|
2631
|
+
`use`-Methode mehrere/verschiedene Argumente und auch Blöcke
|
2632
|
+
entgegennimmt:
|
2366
2633
|
|
2367
2634
|
```ruby
|
2368
2635
|
use Rack::Auth::Basic do |username, password|
|
@@ -2382,8 +2649,9 @@ oder im [Rack wiki](https://github.com/rack/rack/wiki/List-of-Middleware).
|
|
2382
2649
|
|
2383
2650
|
## Testen
|
2384
2651
|
|
2385
|
-
Sinatra-Tests können mit jedem auf Rack aufbauendem Test-Framework
|
2386
|
-
werden.
|
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)
|
2387
2655
|
wird empfohlen:
|
2388
2656
|
|
2389
2657
|
```ruby
|
@@ -2415,8 +2683,9 @@ class MyAppTest < Minitest::Test
|
|
2415
2683
|
end
|
2416
2684
|
```
|
2417
2685
|
|
2418
|
-
Hinweis: Wird Sinatra modular verwendet, muss
|
2419
|
-
dem Namen der Applikations-Klasse
|
2686
|
+
Hinweis: Wird Sinatra modular verwendet, muss
|
2687
|
+
`Sinatra::Application` mit dem Namen der Applikations-Klasse
|
2688
|
+
ersetzt werden.
|
2420
2689
|
|
2421
2690
|
## Sinatra::Base - Middleware, Bibliotheken und modulare Anwendungen
|
2422
2691
|
|
@@ -2443,21 +2712,12 @@ class MyApp < Sinatra::Base
|
|
2443
2712
|
end
|
2444
2713
|
```
|
2445
2714
|
|
2446
|
-
Die MyApp-Klasse ist eine unabhängige Rack-Komponente, die als Middleware,
|
2447
|
-
Endpunkt oder via Rails Metal verwendet werden kann. Verwendet wird sie durch
|
2448
|
-
`use` oder `run` von einer Rackup-`config.ru`-Datei oder als Server-Komponente
|
2449
|
-
einer Bibliothek:
|
2450
|
-
|
2451
|
-
```ruby
|
2452
|
-
MyApp.run! :host => 'localhost', :port => 9090
|
2453
|
-
```
|
2454
|
-
|
2455
2715
|
Die Methoden der `Sinatra::Base`-Subklasse sind genau dieselben wie die der
|
2456
2716
|
Top-Level-DSL. Die meisten Top-Level-Anwendungen können mit nur zwei
|
2457
2717
|
Veränderungen zu `Sinatra::Base` konvertiert werden:
|
2458
2718
|
|
2459
2719
|
* Die Datei sollte `require 'sinatra/base'` anstelle von `require
|
2460
|
-
'sinatra
|
2720
|
+
'sinatra'` aufrufen, ansonsten werden alle von Sinatras DSL-Methoden
|
2461
2721
|
in den Top-Level-Namespace importiert.
|
2462
2722
|
* Alle Routen, Error-Handler, Filter und Optionen der Applikation müssen in
|
2463
2723
|
einer Subklasse von `Sinatra::Base` definiert werden.
|
@@ -2613,7 +2873,6 @@ Anzeichen dafür, dass eine `config.ru`-Datei gebraucht wird:
|
|
2613
2873
|
* Es gibt mehr als nur eine Subklasse von `Sinatra::Base`.
|
2614
2874
|
* Sinatra soll als Middleware verwendet werden, nicht als Endpunkt.
|
2615
2875
|
|
2616
|
-
|
2617
2876
|
**Es gibt keinen Grund, eine `config.ru`-Datei zu verwenden, nur weil eine
|
2618
2877
|
Anwendung im modularen Stil betrieben werden soll. Ebenso wird keine Anwendung
|
2619
2878
|
mit modularem Stil benötigt, um eine `config.ru`-Datei zu verwenden.**
|
@@ -2624,7 +2883,7 @@ Es ist nicht nur möglich, andere Rack-Middleware mit Sinatra zu nutzen, es
|
|
2624
2883
|
kann außerdem jede Sinatra-Anwendung selbst als Middleware vor jeden
|
2625
2884
|
beliebigen Rack-Endpunkt gehangen werden. Bei diesem Endpunkt muss es sich
|
2626
2885
|
nicht um eine andere Sinatra-Anwendung handeln, es kann jede andere
|
2627
|
-
Rack-Anwendung sein (Rails/
|
2886
|
+
Rack-Anwendung sein (Rails/Hanami/Roda/...):
|
2628
2887
|
|
2629
2888
|
```ruby
|
2630
2889
|
require 'sinatra/base'
|
@@ -2724,7 +2983,7 @@ Optionen, die via `set` gesetzt werden, sind Methoden auf Klassenebene:
|
|
2724
2983
|
```ruby
|
2725
2984
|
class MyApp < Sinatra::Base
|
2726
2985
|
# Hey, ich bin im Anwendungsscope!
|
2727
|
-
|
2986
|
+
set :foo, 42
|
2728
2987
|
foo # => 42
|
2729
2988
|
|
2730
2989
|
get '/foo' do
|
@@ -2735,20 +2994,18 @@ end
|
|
2735
2994
|
|
2736
2995
|
Im Anwendungs-Scope befindet man sich:
|
2737
2996
|
|
2738
|
-
*
|
2739
|
-
* In Methoden, die von Erweiterungen definiert werden
|
2740
|
-
* Im Block, der an `helpers` übergeben wird
|
2741
|
-
* In Procs und Blöcken, die an `set` übergeben werden
|
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
|
2742
3001
|
* Der an `Sinatra.new` übergebene Block
|
2743
3002
|
|
2744
|
-
|
2745
3003
|
Auf das Scope-Objekt (die Klasse) kann wie folgt zugegriffen werden:
|
2746
3004
|
|
2747
3005
|
* Über das Objekt, das an den `configure`-Block übergeben wird (`configure {
|
2748
3006
|
|c| ... }`).
|
2749
3007
|
* `settings` aus den anderen Scopes heraus.
|
2750
3008
|
|
2751
|
-
|
2752
3009
|
### Anfrage- oder Instanz-Scope
|
2753
3010
|
|
2754
3011
|
Für jede eingehende Anfrage wird eine neue Instanz der Anwendungs-Klasse
|
@@ -2779,8 +3036,7 @@ Im Anfrage-Scope befindet man sich:
|
|
2779
3036
|
* In get, head, post, put, delete, options, patch, link und unlink Blöcken
|
2780
3037
|
* In before und after Filtern
|
2781
3038
|
* In Helfer-Methoden
|
2782
|
-
* In Templates
|
2783
|
-
|
3039
|
+
* In Templates/Views
|
2784
3040
|
|
2785
3041
|
### Delegation-Scope
|
2786
3042
|
|
@@ -2797,18 +3053,17 @@ Im Delegation-Scop befindet man sich:
|
|
2797
3053
|
* Im Top-Level, wenn `require 'sinatra'` aufgerufen wurde.
|
2798
3054
|
* In einem Objekt, das mit dem `Sinatra::Delegator`-Mixin erweitert wurde.
|
2799
3055
|
|
2800
|
-
|
2801
3056
|
Schau am besten im Code nach: Hier ist [Sinatra::Delegator
|
2802
3057
|
mixin](http://github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb#L1064
|
2803
3058
|
) definiert und wird in den [globalen Namespace
|
2804
|
-
eingebunden](http://github.com/sinatra/sinatra/blob/master/lib/sinatra/main.rb
|
3059
|
+
eingebunden](http://github.com/sinatra/sinatra/blob/master/lib/sinatra/main.rb).
|
2805
3060
|
|
2806
3061
|
## Kommandozeile
|
2807
3062
|
|
2808
3063
|
Sinatra-Anwendungen können direkt von der Kommandozeile aus gestartet werden:
|
2809
3064
|
|
2810
3065
|
```shell
|
2811
|
-
ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-h HOST] [-s HANDLER]
|
3066
|
+
ruby myapp.rb [-h] [-x] [-q] [-e ENVIRONMENT] [-p PORT] [-h HOST] [-s HANDLER]
|
2812
3067
|
```
|
2813
3068
|
|
2814
3069
|
Die Optionen sind:
|
@@ -2819,12 +3074,14 @@ Die Optionen sind:
|
|
2819
3074
|
-h # Host setzen (Standard ist 0.0.0.0)
|
2820
3075
|
-e # Umgebung setzen (Standard ist development)
|
2821
3076
|
-s # Rack-Server/Handler setzen (Standard ist thin)
|
2822
|
-
-
|
3077
|
+
-q # den lautlosen Server-Modus einschalten (Standard ist aus)
|
3078
|
+
-x # Mutex-Lock einschalten (Standard ist aus)
|
2823
3079
|
```
|
2824
3080
|
|
2825
3081
|
### Multi-threading
|
2826
3082
|
|
2827
|
-
_Paraphrasiert von [dieser Antwort auf StackOverflow][so-answer] von
|
3083
|
+
_Paraphrasiert von [dieser Antwort auf StackOverflow][so-answer] von
|
3084
|
+
Konstantin_
|
2828
3085
|
|
2829
3086
|
Sinatra erlegt kein Nebenläufigkeitsmodell auf, sondern überlässt dies dem
|
2830
3087
|
selbst gewählten Rack-Proxy (Server), so wie Thin, Puma oder WEBrick.
|
@@ -2863,42 +3120,38 @@ thin --threaded start
|
|
2863
3120
|
Die folgenden Versionen werden offiziell unterstützt:
|
2864
3121
|
|
2865
3122
|
<dl>
|
2866
|
-
<dt>Ruby
|
2867
|
-
<dd>
|
2868
|
-
|
2869
|
-
|
2870
|
-
|
2871
|
-
|
2872
|
-
<
|
2873
|
-
|
2874
|
-
|
2875
|
-
|
2876
|
-
<
|
2877
|
-
|
2878
|
-
|
2879
|
-
|
2880
|
-
|
2881
|
-
|
2882
|
-
|
2883
|
-
|
2884
|
-
|
2885
|
-
<dd>Rubinius (Version >= 2.x) wird offiziell unterstützt. Es wird empfohlen, den
|
2886
|
-
<a href="http://puma.io">Puma Server</a> zu installieren (<tt>gem install puma
|
2887
|
-
</tt>)</dd>
|
2888
|
-
|
2889
|
-
<dt>JRuby</dt>
|
2890
|
-
<dd>Aktuelle JRuby Versionen werden offiziell unterstützt. Es wird empfohlen,
|
2891
|
-
keine C-Erweiterungen zu verwenden und als Server Trinidad zu verwenden
|
2892
|
-
(<tt>gem install trinidad</tt>).</dd>
|
3123
|
+
<dt>Ruby 2.2</dt>
|
3124
|
+
<dd>
|
3125
|
+
2.2 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>
|
2893
3142
|
</dl>
|
2894
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
|
+
|
2895
3148
|
Die nachfolgend aufgeführten Ruby-Implementierungen werden offiziell nicht von
|
2896
3149
|
Sinatra unterstützt, funktionieren aber normalerweise:
|
2897
3150
|
|
2898
3151
|
* Ruby Enterprise Edition
|
2899
3152
|
* Ältere Versionen von JRuby und Rubinius
|
2900
|
-
* MacRuby
|
2901
|
-
* Ruby 1.9.0 und 1.9.1
|
3153
|
+
* MacRuby, Maglev, IronRuby
|
3154
|
+
* Ruby 1.9.0 und 1.9.1 (wird aber nicht empfohlen)
|
2902
3155
|
|
2903
3156
|
Nicht offiziell unterstützt bedeutet, dass wenn Sachen nicht funktionieren,
|
2904
3157
|
wir davon ausgehen, dass es nicht an Sinatra sondern an der jeweiligen
|
@@ -2908,10 +3161,11 @@ Im Rahmen unserer CI (Kontinuierlichen Integration) wird bereits ruby-head
|
|
2908
3161
|
(zukünftige Versionen von MRI) mit eingebunden. Es kann davon ausgegangen
|
2909
3162
|
werden, dass Sinatra MRI auch weiterhin vollständig unterstützen wird.
|
2910
3163
|
|
2911
|
-
Sinatra sollte auf jedem Betriebssystem laufen,
|
3164
|
+
Sinatra sollte auf jedem Betriebssystem laufen, das einen funktionierenden
|
2912
3165
|
Ruby-Interpreter aufweist.
|
2913
3166
|
|
2914
|
-
Sinatra läuft aktuell nicht unter Cardinal, SmallRuby, BlueRuby oder Ruby <=
|
3167
|
+
Sinatra läuft aktuell nicht unter Cardinal, SmallRuby, BlueRuby oder Ruby <=
|
3168
|
+
2.2.
|
2915
3169
|
|
2916
3170
|
## Der neuste Stand (The Bleeding Edge)
|
2917
3171
|
|
@@ -2944,7 +3198,6 @@ gem 'sinatra', :git => "git://github.com/sinatra/sinatra.git"
|
|
2944
3198
|
|
2945
3199
|
# evtl. andere Abhängigkeiten
|
2946
3200
|
gem 'haml' # z.B. wenn du Haml verwendest...
|
2947
|
-
gem 'activerecord', '~> 3.0' # ...oder ActiveRecord 3.x
|
2948
3201
|
```
|
2949
3202
|
|
2950
3203
|
Beachte: Hier sollten alle Abhängigkeiten eingetragen werden. Sinatras eigene,
|
@@ -2957,55 +3210,6 @@ Jetzt kannst du deine Applikation starten:
|
|
2957
3210
|
bundle exec ruby myapp.rb
|
2958
3211
|
```
|
2959
3212
|
|
2960
|
-
### Eigenes Repository
|
2961
|
-
Um auf dem neuesten Stand von Sinatras Code zu sein, kann eine lokale Kopie
|
2962
|
-
angelegt werden. Gestartet wird in der Anwendung mit dem `sinatra/lib`-Ordner
|
2963
|
-
im `LOAD_PATH`:
|
2964
|
-
|
2965
|
-
```shell
|
2966
|
-
cd myapp
|
2967
|
-
git clone git://github.com/sinatra/sinatra.git
|
2968
|
-
ruby -Isinatra/lib myapp.rb
|
2969
|
-
```
|
2970
|
-
|
2971
|
-
Alternativ kann der `sinatra/lib`-Ordner zum `LOAD_PATH` in der Anwendung
|
2972
|
-
hinzugefügt werden:
|
2973
|
-
|
2974
|
-
```ruby
|
2975
|
-
$LOAD_PATH.unshift File.dirname(__FILE__) + '/sinatra/lib'
|
2976
|
-
require 'rubygems'
|
2977
|
-
require 'sinatra'
|
2978
|
-
|
2979
|
-
get '/ueber' do
|
2980
|
-
"Ich laufe auf Version " + Sinatra::VERSION
|
2981
|
-
end
|
2982
|
-
```
|
2983
|
-
|
2984
|
-
Um Sinatra-Code von Zeit zu Zeit zu aktualisieren:
|
2985
|
-
|
2986
|
-
```shell
|
2987
|
-
cd myproject/sinatra
|
2988
|
-
git pull
|
2989
|
-
```
|
2990
|
-
|
2991
|
-
### Gem erstellen
|
2992
|
-
|
2993
|
-
Aus der eigenen lokalen Kopie kann nun auch ein globales Gem gebaut werden:
|
2994
|
-
|
2995
|
-
```shell
|
2996
|
-
git clone git://github.com/sinatra/sinatra.git
|
2997
|
-
cd sinatra
|
2998
|
-
rake sinatra.gemspec
|
2999
|
-
rake install
|
3000
|
-
```
|
3001
|
-
|
3002
|
-
Falls Gems als Root installiert werden sollen, sollte die letzte Zeile
|
3003
|
-
folgendermaßen lauten:
|
3004
|
-
|
3005
|
-
```shell
|
3006
|
-
sudo rake install
|
3007
|
-
```
|
3008
|
-
|
3009
3213
|
## Versions-Verfahren
|
3010
3214
|
|
3011
3215
|
Sinatra folgt dem sogenannten [Semantic Versioning](http://semver.org/), d.h.
|
@@ -3013,19 +3217,23 @@ SemVer und SemVerTag.
|
|
3013
3217
|
|
3014
3218
|
## Mehr
|
3015
3219
|
|
3016
|
-
*
|
3017
|
-
|
3018
|
-
*
|
3019
|
-
|
3020
|
-
*
|
3021
|
-
*
|
3022
|
-
*
|
3023
|
-
*
|
3024
|
-
|
3025
|
-
|
3026
|
-
*
|
3027
|
-
|
3028
|
-
*
|
3029
|
-
|
3030
|
-
|
3031
|
-
*
|
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)
|