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