sinatra-base 1.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.yardopts +4 -0
- data/AUTHORS +15 -0
- data/CHANGES +524 -1
- data/Gemfile +82 -0
- data/LICENSE +1 -1
- data/README.de.rdoc +2093 -0
- data/README.es.rdoc +2091 -0
- data/README.fr.rdoc +2116 -0
- data/README.hu.rdoc +607 -0
- data/README.jp.rdoc +514 -23
- data/README.pt-br.rdoc +647 -0
- data/README.pt-pt.rdoc +646 -0
- data/README.rdoc +1580 -205
- data/README.ru.rdoc +2015 -0
- data/README.zh.rdoc +1816 -0
- data/Rakefile +110 -44
- data/examples/chat.rb +61 -0
- data/examples/simple.rb +3 -0
- data/examples/stream.ru +26 -0
- data/lib/sinatra.rb +0 -3
- data/lib/sinatra/base.rb +923 -393
- data/lib/sinatra/main.rb +9 -7
- data/lib/sinatra/showexceptions.rb +37 -4
- data/lib/sinatra/version.rb +3 -0
- data/sinatra-base.gemspec +15 -91
- data/test/base_test.rb +2 -2
- data/test/builder_test.rb +32 -2
- data/test/coffee_test.rb +92 -0
- data/test/contest.rb +62 -28
- data/test/creole_test.rb +65 -0
- data/test/delegator_test.rb +162 -0
- data/test/encoding_test.rb +20 -0
- data/test/erb_test.rb +25 -2
- data/test/extensions_test.rb +1 -1
- data/test/filter_test.rb +226 -8
- data/test/haml_test.rb +8 -2
- data/test/helper.rb +47 -0
- data/test/helpers_test.rb +1287 -80
- data/test/integration/app.rb +62 -0
- data/test/integration_helper.rb +208 -0
- data/test/integration_test.rb +82 -0
- data/test/less_test.rb +36 -6
- data/test/liquid_test.rb +59 -0
- data/test/mapped_error_test.rb +84 -7
- data/test/markaby_test.rb +80 -0
- data/test/markdown_test.rb +81 -0
- data/test/middleware_test.rb +1 -1
- data/test/nokogiri_test.rb +69 -0
- data/test/rack_test.rb +45 -0
- data/test/radius_test.rb +59 -0
- data/test/rdoc_test.rb +66 -0
- data/test/readme_test.rb +136 -0
- data/test/request_test.rb +13 -1
- data/test/response_test.rb +21 -2
- data/test/result_test.rb +5 -5
- data/test/route_added_hook_test.rb +1 -1
- data/test/routing_test.rb +328 -13
- data/test/sass_test.rb +48 -18
- data/test/scss_test.rb +88 -0
- data/test/server_test.rb +4 -3
- data/test/settings_test.rb +191 -21
- data/test/sinatra_test.rb +5 -1
- data/test/slim_test.rb +88 -0
- data/test/static_test.rb +89 -5
- data/test/streaming_test.rb +140 -0
- data/test/templates_test.rb +143 -4
- data/test/textile_test.rb +65 -0
- data/test/views/a/in_a.str +1 -0
- data/test/views/ascii.erb +2 -0
- data/test/views/b/in_b.str +1 -0
- data/test/views/calc.html.erb +1 -0
- data/test/views/explicitly_nested.str +1 -0
- data/test/views/hello.coffee +1 -0
- data/test/views/hello.creole +1 -0
- data/test/views/hello.liquid +1 -0
- data/test/views/hello.mab +1 -0
- data/test/views/hello.md +1 -0
- data/test/views/hello.nokogiri +1 -0
- data/test/views/hello.radius +1 -0
- data/test/views/hello.rdoc +1 -0
- data/test/views/hello.sass +1 -1
- data/test/views/hello.scss +3 -0
- data/test/views/hello.slim +1 -0
- data/test/views/hello.str +1 -0
- data/test/views/hello.textile +1 -0
- data/test/views/hello.yajl +1 -0
- data/test/views/layout2.liquid +2 -0
- data/test/views/layout2.mab +2 -0
- data/test/views/layout2.nokogiri +3 -0
- data/test/views/layout2.radius +2 -0
- data/test/views/layout2.slim +3 -0
- data/test/views/layout2.str +2 -0
- data/test/views/nested.str +1 -0
- data/test/views/utf8.erb +2 -0
- data/test/yajl_test.rb +80 -0
- metadata +126 -91
- data/lib/sinatra/tilt.rb +0 -746
- data/test/erubis_test.rb +0 -82
- data/test/views/error.erubis +0 -3
- data/test/views/hello.erubis +0 -1
- data/test/views/layout2.erubis +0 -2
data/README.jp.rdoc
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
= Sinatra
|
2
|
+
<i>注) 本文書は英語から翻訳したものであり、その内容が最新でない場合もあります。最新の情報はオリジナルの英語版を参照して下さい。</i>
|
2
3
|
|
3
4
|
SinatraはRubyで下記のような最小労力で手早くウェブアプリケーションを作成するためのDSLです。
|
4
5
|
|
5
6
|
# myapp.rb
|
6
|
-
require 'rubygems'
|
7
7
|
require 'sinatra'
|
8
8
|
get '/' do
|
9
9
|
'Hello world!'
|
@@ -11,8 +11,8 @@ SinatraはRubyで下記のような最小労力で手早くウェブアプリケ
|
|
11
11
|
|
12
12
|
gemをインストールして動かしてみる。
|
13
13
|
|
14
|
-
|
15
|
-
ruby myapp.rb
|
14
|
+
gem install sinatra
|
15
|
+
ruby -rubygems myapp.rb
|
16
16
|
|
17
17
|
http://localhost:4567 を見る。
|
18
18
|
|
@@ -67,6 +67,12 @@ Sinatraでは、ルートはHTTPメソッドとURLマッチングパターンが
|
|
67
67
|
params[:splat] # => ["path/to/file", "xml"]
|
68
68
|
end
|
69
69
|
|
70
|
+
ブロックパラーメータを使用した場合:
|
71
|
+
|
72
|
+
get '/download/*.*' do |path, ext|
|
73
|
+
[path, ext] # => ["path/to/file", "xml"]
|
74
|
+
end
|
75
|
+
|
70
76
|
正規表現を使ったルート:
|
71
77
|
|
72
78
|
get %r{/hello/([\w]+)} do
|
@@ -79,6 +85,9 @@ Sinatraでは、ルートはHTTPメソッドとURLマッチングパターンが
|
|
79
85
|
"Hello, #{c}!"
|
80
86
|
end
|
81
87
|
|
88
|
+
|
89
|
+
=== 条件
|
90
|
+
|
82
91
|
ルートにはユーザエージェントのようなさまざまな条件を含めることができます。
|
83
92
|
|
84
93
|
get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
|
@@ -89,12 +98,64 @@ Sinatraでは、ルートはHTTPメソッドとURLマッチングパターンが
|
|
89
98
|
# Matches non-songbird browsers
|
90
99
|
end
|
91
100
|
|
101
|
+
ほかに+host_name+と+provides+条件が利用可能です:
|
102
|
+
|
103
|
+
get '/', :host_name => /^admin\./ do
|
104
|
+
"Admin Area, Access denied!"
|
105
|
+
end
|
106
|
+
|
107
|
+
get '/', :provides => 'html' do
|
108
|
+
haml :index
|
109
|
+
end
|
110
|
+
|
111
|
+
get '/', :provides => ['rss', 'atom', 'xml'] do
|
112
|
+
builder :feed
|
113
|
+
end
|
114
|
+
|
115
|
+
独自の条件を定義することも簡単にできます:
|
116
|
+
|
117
|
+
set(:probability) { |value| condition { rand <= value } }
|
118
|
+
|
119
|
+
get '/win_a_car', :probability => 0.1 do
|
120
|
+
"You won!"
|
121
|
+
end
|
122
|
+
|
123
|
+
get '/win_a_car' do
|
124
|
+
"Sorry, you lost."
|
125
|
+
end
|
126
|
+
|
127
|
+
|
128
|
+
=== 戻り値
|
129
|
+
|
130
|
+
ルートブロックの戻り値は、HTTPクライアントまたはRackスタックでの次のミドルウェアに渡されるレスポンスボディを決定します。
|
131
|
+
|
132
|
+
これは大抵の場合、上の例のように文字列ですが、それ以外の値も使用することができます。
|
133
|
+
|
134
|
+
Rackレスポンス、Rackボディオブジェクト、HTTPステータスコードのいずれかとして
|
135
|
+
妥当なオブジェクトであればどのようなオブジェクトでも返すことができます:
|
136
|
+
|
137
|
+
* 3要素の配列: <tt>[ステータス(Fixnum), ヘッダ(Hash), レスポンスボディ(#eachに応答する)]</tt>
|
138
|
+
* 2要素の配列: <tt>[ステータス(Fixnum), レスポンスボディ(#eachに応答する)]</tt>
|
139
|
+
* <tt>#each</tt>に応答し、与えられたブロックに文字列を渡すオブジェクト
|
140
|
+
* ステータスコードを表現するFixnum
|
141
|
+
|
142
|
+
そのように、例えばストリーミングの例を簡単に実装することができます:
|
143
|
+
|
144
|
+
class Stream
|
145
|
+
def each
|
146
|
+
100.times { |i| yield "#{i}\n" }
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
get('/') { Stream.new }
|
151
|
+
|
152
|
+
|
92
153
|
== 静的ファイル
|
93
154
|
|
94
155
|
静的ファイルは<tt>./public</tt>ディレクトリから配信されます。
|
95
|
-
<tt>:
|
156
|
+
<tt>:public_folder</tt>オプションを指定することで別の場所を指定することができます。
|
96
157
|
|
97
|
-
set :
|
158
|
+
set :public_folder, File.dirname(__FILE__) + '/static'
|
98
159
|
|
99
160
|
注意: この静的ファイル用のディレクトリ名はURL中に含まれません。
|
100
161
|
例えば、<tt>./public/css/style.css</tt>は<tt>http://example.com/css/style.css</tt>でアクセスできます。
|
@@ -114,7 +175,7 @@ Sinatraでは、ルートはHTTPメソッドとURLマッチングパターンが
|
|
114
175
|
|
115
176
|
hamlを使うにはhamlライブラリが必要です:
|
116
177
|
|
117
|
-
|
178
|
+
# hamlを読み込みます
|
118
179
|
require 'haml'
|
119
180
|
|
120
181
|
get '/' do
|
@@ -123,7 +184,7 @@ hamlを使うにはhamlライブラリが必要です:
|
|
123
184
|
|
124
185
|
<tt>./views/index.haml</tt>を表示します。
|
125
186
|
|
126
|
-
{Haml's options}[http://haml.
|
187
|
+
{Haml's options}[http://haml-lang.com/docs/yardoc/file.HAML_REFERENCE.html#options]
|
127
188
|
はSinatraの設定でグローバルに設定することができます。
|
128
189
|
{Options and Configurations}[http://www.sinatrarb.com/configuration.html],
|
129
190
|
を参照してそれぞれ設定を上書きして下さい。
|
@@ -137,7 +198,7 @@ hamlを使うにはhamlライブラリが必要です:
|
|
137
198
|
|
138
199
|
=== Erb テンプレート
|
139
200
|
|
140
|
-
|
201
|
+
# erbを読み込みます
|
141
202
|
require 'erb'
|
142
203
|
|
143
204
|
get '/' do
|
@@ -146,35 +207,59 @@ hamlを使うにはhamlライブラリが必要です:
|
|
146
207
|
|
147
208
|
<tt>./views/index.erb</tt>を表示します。
|
148
209
|
|
210
|
+
=== Erubis
|
211
|
+
|
212
|
+
erubisテンプレートを表示するには、erubisライブラリが必要です:
|
213
|
+
|
214
|
+
# erubisを読み込みます
|
215
|
+
require 'erubis'
|
216
|
+
|
217
|
+
get '/' do
|
218
|
+
erubis :index
|
219
|
+
end
|
220
|
+
|
221
|
+
<tt>./views/index.erubis</tt>を表示します。
|
222
|
+
|
149
223
|
=== Builder テンプレート
|
150
224
|
|
151
225
|
builderを使うにはbuilderライブラリが必要です:
|
152
226
|
|
153
|
-
|
227
|
+
# builderを読み込みます
|
154
228
|
require 'builder'
|
155
229
|
|
156
230
|
get '/' do
|
157
|
-
content_type 'application/xml', :charset => 'utf-8'
|
158
231
|
builder :index
|
159
232
|
end
|
160
233
|
|
161
234
|
<tt>./views/index.builder</tt>を表示します。
|
162
235
|
|
236
|
+
=== 鋸 テンプレート
|
237
|
+
|
238
|
+
鋸を使うには鋸ライブラリが必要です:
|
239
|
+
|
240
|
+
# 鋸を読み込みます
|
241
|
+
require 'nokogiri'
|
242
|
+
|
243
|
+
get '/' do
|
244
|
+
nokogiri :index
|
245
|
+
end
|
246
|
+
|
247
|
+
<tt>./views/index.nokogiri</tt>を表示します。
|
248
|
+
|
163
249
|
=== Sass テンプレート
|
164
250
|
|
165
251
|
Sassテンプレートを使うにはsassライブラリが必要です:
|
166
252
|
|
167
|
-
|
253
|
+
# hamlかsassを読み込みます
|
168
254
|
require 'sass'
|
169
255
|
|
170
256
|
get '/stylesheet.css' do
|
171
|
-
content_type 'text/css', :charset => 'utf-8'
|
172
257
|
sass :stylesheet
|
173
258
|
end
|
174
259
|
|
175
260
|
<tt>./views/stylesheet.sass</tt>を表示します。
|
176
261
|
|
177
|
-
{Sass' options}[http://
|
262
|
+
{Sass' options}[http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#options]
|
178
263
|
はSinatraの設定でグローバルに設定することができます。
|
179
264
|
see {Options and Configurations}[http://www.sinatrarb.com/configuration.html],
|
180
265
|
を参照してそれぞれ設定を上書きして下さい。
|
@@ -182,10 +267,203 @@ see {Options and Configurations}[http://www.sinatrarb.com/configuration.html],
|
|
182
267
|
set :sass, {:style => :compact } # デフォルトのSass styleは :nested
|
183
268
|
|
184
269
|
get '/stylesheet.css' do
|
185
|
-
content_type 'text/css', :charset => 'utf-8'
|
186
270
|
sass :stylesheet, :sass_options => {:style => :expanded } # 上書き
|
187
271
|
end
|
188
272
|
|
273
|
+
=== Scss テンプレート
|
274
|
+
|
275
|
+
Scssテンプレートを使うにはsassライブラリが必要です:
|
276
|
+
|
277
|
+
# hamlかsassを読み込みます
|
278
|
+
require 'sass'
|
279
|
+
|
280
|
+
get '/stylesheet.css' do
|
281
|
+
scss :stylesheet
|
282
|
+
end
|
283
|
+
|
284
|
+
<tt>./views/stylesheet.scss</tt>を表示します。
|
285
|
+
|
286
|
+
{Sass' options}[http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#options]
|
287
|
+
はSinatraの設定でグローバルに設定することができます。
|
288
|
+
see {Options and Configurations}[http://www.sinatrarb.com/configuration.html],
|
289
|
+
を参照してそれぞれ設定を上書きして下さい。
|
290
|
+
|
291
|
+
set :scss, :style => :compact # デフォルトのScss styleは:nested
|
292
|
+
|
293
|
+
get '/stylesheet.css' do
|
294
|
+
scss :stylesheet, :style => :expanded # 上書き
|
295
|
+
end
|
296
|
+
|
297
|
+
=== Less テンプレート
|
298
|
+
|
299
|
+
Lessテンプレートを使うにはlessライブラリが必要です:
|
300
|
+
|
301
|
+
# lessを読み込みます
|
302
|
+
require 'less'
|
303
|
+
|
304
|
+
get '/stylesheet.css' do
|
305
|
+
less :stylesheet
|
306
|
+
end
|
307
|
+
|
308
|
+
<tt>./views/stylesheet.less</tt>を表示します。
|
309
|
+
|
310
|
+
=== Liquid テンプレート
|
311
|
+
|
312
|
+
Liquidテンプレートを使うにはliquidライブラリが必要です:
|
313
|
+
|
314
|
+
# liquidを読み込みます
|
315
|
+
require 'liquid'
|
316
|
+
|
317
|
+
get '/' do
|
318
|
+
liquid :index
|
319
|
+
end
|
320
|
+
|
321
|
+
<tt>./views/index.liquid</tt>を表示します。
|
322
|
+
|
323
|
+
LiquidテンプレートからRubyのメソッド(+yield+を除く)を呼び出すことができないため、
|
324
|
+
ほぼ全ての場合にlocalsを指定する必要があるでしょう:
|
325
|
+
|
326
|
+
liquid :index, :locals => { :key => 'value' }
|
327
|
+
|
328
|
+
=== Markdown テンプレート
|
329
|
+
|
330
|
+
Markdownテンプレートを使うにはrdiscountライブラリが必要です:
|
331
|
+
|
332
|
+
# rdiscountを読み込みます
|
333
|
+
require "rdiscount"
|
334
|
+
|
335
|
+
get '/' do
|
336
|
+
markdown :index
|
337
|
+
end
|
338
|
+
|
339
|
+
<tt>./views/index.markdown</tt>を表示します。(+md+と+mkd+も妥当な拡張子です)
|
340
|
+
|
341
|
+
markdownからメソッドを呼び出すことも、localsに変数を渡すこともできません。
|
342
|
+
それゆえ、他のレンダリングエンジンとの組み合わせで使うのが普通です:
|
343
|
+
|
344
|
+
erb :overview, :locals => { :text => markdown(:introduction) }
|
345
|
+
|
346
|
+
他のテンプレートからmarkdownメソッドを呼び出してもよいことに注意してください:
|
347
|
+
|
348
|
+
%h1 Hello From Haml!
|
349
|
+
%p= markdown(:greetings)
|
350
|
+
|
351
|
+
=== Textile テンプレート
|
352
|
+
|
353
|
+
Textileテンプレートを使うにはRedClothライブラリが必要です:
|
354
|
+
|
355
|
+
# redclothを読み込みます
|
356
|
+
require "redcloth"
|
357
|
+
|
358
|
+
get '/' do
|
359
|
+
textile :index
|
360
|
+
end
|
361
|
+
|
362
|
+
<tt>./views/index.textile</tt>を表示します。
|
363
|
+
|
364
|
+
textileからメソッドを呼び出すことも、localsに変数を渡すこともできません。
|
365
|
+
それゆえ、他のレンダリングエンジンとの組み合わせで使うのが普通です:
|
366
|
+
|
367
|
+
erb :overview, :locals => { :text => textile(:introduction) }
|
368
|
+
|
369
|
+
他のテンプレートからtextileメソッドを呼び出してもよいことに注意してください:
|
370
|
+
|
371
|
+
%h1 Hello From Haml!
|
372
|
+
%p= textile(:greetings)
|
373
|
+
|
374
|
+
=== RDoc テンプレート
|
375
|
+
|
376
|
+
RDocテンプレートを使うにはRDocライブラリが必要です:
|
377
|
+
|
378
|
+
# rdoc/markup/to_htmlを読み込みます
|
379
|
+
require "rdoc"
|
380
|
+
require "rdoc/markup/to_html"
|
381
|
+
|
382
|
+
get '/' do
|
383
|
+
rdoc :index
|
384
|
+
end
|
385
|
+
|
386
|
+
<tt>./views/index.rdoc</tt>を表示します。
|
387
|
+
|
388
|
+
rdocからメソッドを呼び出すことも、localsに変数を渡すこともできません。
|
389
|
+
それゆえ、他のレンダリングエンジンとの組み合わせで使うのが普通です:
|
390
|
+
|
391
|
+
erb :overview, :locals => { :text => rdoc(:introduction) }
|
392
|
+
|
393
|
+
他のテンプレートからrdocメソッドを呼び出してもよいことに注意してください:
|
394
|
+
|
395
|
+
%h1 Hello From Haml!
|
396
|
+
%p= rdoc(:greetings)
|
397
|
+
|
398
|
+
=== Radius テンプレート
|
399
|
+
|
400
|
+
Radiusテンプレートを使うにはradiusライブラリが必要です:
|
401
|
+
|
402
|
+
# radiusを読み込みます
|
403
|
+
require 'radius'
|
404
|
+
|
405
|
+
get '/' do
|
406
|
+
radius :index
|
407
|
+
end
|
408
|
+
|
409
|
+
<tt>./views/index.radius</tt>を表示します。
|
410
|
+
|
411
|
+
RadiusテンプレートからRubyのメソッド(+yield+を除く)を呼び出すことができないため、
|
412
|
+
ほぼ全ての場合にlocalsを指定する必要があるでしょう:
|
413
|
+
|
414
|
+
radius :index, :locals => { :key => 'value' }
|
415
|
+
|
416
|
+
=== Markaby テンプレート
|
417
|
+
|
418
|
+
Markabyテンプレートを使うにはmarkabyライブラリが必要です:
|
419
|
+
|
420
|
+
# markabyを読み込みます
|
421
|
+
require 'markaby'
|
422
|
+
|
423
|
+
get '/' do
|
424
|
+
markaby :index
|
425
|
+
end
|
426
|
+
|
427
|
+
<tt>./views/index.mab</tt>を表示します。
|
428
|
+
|
429
|
+
=== Slim テンプレート
|
430
|
+
|
431
|
+
Slimテンプレートを使うにはslimライブラリが必要です:
|
432
|
+
|
433
|
+
# slimを読み込みます
|
434
|
+
require 'slim'
|
435
|
+
|
436
|
+
get '/' do
|
437
|
+
slim :index
|
438
|
+
end
|
439
|
+
|
440
|
+
<tt>./views/index.slim</tt>を表示します。
|
441
|
+
|
442
|
+
=== Creole テンプレート
|
443
|
+
|
444
|
+
Creoleテンプレートを使うにはcreoleライブラリが必要です:
|
445
|
+
|
446
|
+
# creoleを読み込みます
|
447
|
+
require 'creole'
|
448
|
+
|
449
|
+
get '/' do
|
450
|
+
creole :index
|
451
|
+
end
|
452
|
+
|
453
|
+
<tt>./views/index.creole</tt>を表示します。
|
454
|
+
|
455
|
+
=== CoffeeScript テンプレート
|
456
|
+
|
457
|
+
CoffeeScriptテンプレートを表示するにはcoffee-scriptライブラリと`coffee`バイナリが必要です:
|
458
|
+
|
459
|
+
# coffee-scriptを読み込みます
|
460
|
+
require 'coffee-script'
|
461
|
+
|
462
|
+
get '/application.js' do
|
463
|
+
coffee :application
|
464
|
+
end
|
465
|
+
|
466
|
+
<tt>./views/application.coffee</tt>を表示します。
|
189
467
|
|
190
468
|
=== インラインテンプレート
|
191
469
|
|
@@ -235,7 +513,7 @@ see {Options and Configurations}[http://www.sinatrarb.com/configuration.html],
|
|
235
513
|
%div.title Hello world!!!!!
|
236
514
|
|
237
515
|
注意: sinatraをrequireするファイル内で定義されたファイル内テンプレートは自動的に読み込まれます。
|
238
|
-
他のファイルで定義されているテンプレートを使うには <tt>
|
516
|
+
他のファイルで定義されているテンプレートを使うには <tt>enable :inline_templates</tt>を明示的に呼んでください。
|
239
517
|
|
240
518
|
=== 名前付きテンプレート
|
241
519
|
|
@@ -254,7 +532,7 @@ see {Options and Configurations}[http://www.sinatrarb.com/configuration.html],
|
|
254
532
|
end
|
255
533
|
|
256
534
|
「layout」というテンプレートが存在する場合、そのテンプレートファイルは他のテンプレートが
|
257
|
-
表示される度に使用されます。<tt>:layout => false</tt
|
535
|
+
表示される度に使用されます。<tt>:layout => false</tt>することでlayoutsを無効にできます。
|
258
536
|
|
259
537
|
get '/' do
|
260
538
|
haml :index, :layout => !request.xhr?
|
@@ -291,12 +569,36 @@ beforeフィルタはリクエストされたコンテキストを実行する
|
|
291
569
|
params[:splat] #=> 'bar/baz'
|
292
570
|
end
|
293
571
|
|
572
|
+
afterフィルタは同じコンテキストにあるリクエストの後に評価され、
|
573
|
+
同じくリクエストとレスポンスを変更することができます。
|
574
|
+
beforeフィルタとルートで設定されたインスタンス変数は、
|
575
|
+
afterフィルタからアクセスすることができます:
|
576
|
+
|
577
|
+
after do
|
578
|
+
puts response.status
|
579
|
+
end
|
580
|
+
|
581
|
+
フィルタにはオプションとしてパターンを渡すことができ、
|
582
|
+
この場合はリクエストのパスがパターンにマッチした場合のみフィルタが評価されます:
|
583
|
+
|
584
|
+
before '/protected/*' do
|
585
|
+
authenticate!
|
586
|
+
end
|
587
|
+
|
588
|
+
after '/create/:slug' do |slug|
|
589
|
+
session[:last_slug] = slug
|
590
|
+
end
|
591
|
+
|
294
592
|
== 強制終了
|
295
593
|
|
296
594
|
ルートかbeforeフィルタ内で直ちに実行を終了する方法:
|
297
595
|
|
298
596
|
halt
|
299
597
|
|
598
|
+
ステータスを指定することができます:
|
599
|
+
|
600
|
+
halt 410
|
601
|
+
|
300
602
|
body部を指定することもできます ...
|
301
603
|
|
302
604
|
halt 'ここにbodyを書く'
|
@@ -305,6 +607,10 @@ body部を指定することもできます ...
|
|
305
607
|
|
306
608
|
halt 401, '立ち去れ!'
|
307
609
|
|
610
|
+
ヘッダを指定:
|
611
|
+
|
612
|
+
halt 402, {'Content-Type' => 'text/plain'}, 'リベンジ'
|
613
|
+
|
308
614
|
== パッシング(Passing)
|
309
615
|
|
310
616
|
ルートは<tt>pass</tt>を使って次のルートに飛ばすことができます:
|
@@ -321,6 +627,53 @@ body部を指定することもできます ...
|
|
321
627
|
ルートブロックからすぐに抜け出し、次にマッチするルートを実行します。
|
322
628
|
マッチするルートが見当たらない場合は404が返されます。
|
323
629
|
|
630
|
+
== リクエストオブジェクトへのアクセス
|
631
|
+
|
632
|
+
受信するリクエストオブジェクトは、`request`メソッドを通じてリクエストレベル(フィルタ、ルート、エラーハンドラ)からアクセスすることができます:
|
633
|
+
|
634
|
+
# アプリケーションが http://example.com/example で動作している場合
|
635
|
+
get '/foo' do
|
636
|
+
request.body # クライアントによって送信されたリクエストボディ(下記参照)
|
637
|
+
request.scheme # "http"
|
638
|
+
request.script_name # "/example"
|
639
|
+
request.path_info # "/foo"
|
640
|
+
request.port # 80
|
641
|
+
request.request_method # "GET"
|
642
|
+
request.query_string # ""
|
643
|
+
request.content_length # request.bodyの長さ
|
644
|
+
request.media_type # request.bodyのメディアタイプ
|
645
|
+
request.host # "example.com"
|
646
|
+
request.get? # true (他の動詞についても同様のメソッドあり)
|
647
|
+
request.form_data? # false
|
648
|
+
request["SOME_HEADER"] # SOME_HEADERヘッダの値
|
649
|
+
request.referer # クライアントのリファラまたは'/'
|
650
|
+
request.user_agent # ユーザエージェント (:agent 条件によって使用される)
|
651
|
+
request.cookies # ブラウザクッキーのハッシュ
|
652
|
+
request.xhr? # Ajaxリクエストかどうか
|
653
|
+
request.url # "http://example.com/example/foo"
|
654
|
+
request.path # "/example/foo"
|
655
|
+
request.ip # クライアントのIPアドレス
|
656
|
+
request.secure? # false
|
657
|
+
request.env # Rackによって渡された生のenvハッシュ
|
658
|
+
end
|
659
|
+
|
660
|
+
<tt>script_name</tt>や<tt>path_info</tt>などのオプションは次のように利用することもできます:
|
661
|
+
|
662
|
+
before { request.path_info = "/" }
|
663
|
+
|
664
|
+
get "/" do
|
665
|
+
"全てのリクエストはここに来る"
|
666
|
+
end
|
667
|
+
|
668
|
+
<tt>request.body</tt>はIOまたはStringIOのオブジェクトです:
|
669
|
+
|
670
|
+
post "/api" do
|
671
|
+
request.body.rewind # 既に読まれているときのため
|
672
|
+
data = JSON.parse request.body.read
|
673
|
+
"Hello #{data['name']}!"
|
674
|
+
end
|
675
|
+
|
676
|
+
|
324
677
|
== 設定
|
325
678
|
|
326
679
|
どの環境でも起動時に1回だけ実行されます。
|
@@ -329,13 +682,13 @@ body部を指定することもできます ...
|
|
329
682
|
...
|
330
683
|
end
|
331
684
|
|
332
|
-
|
685
|
+
環境(RACK_ENV環境変数)が<tt>:production</tt>に設定されている時だけ実行する方法:
|
333
686
|
|
334
687
|
configure :production do
|
335
688
|
...
|
336
689
|
end
|
337
690
|
|
338
|
-
|
691
|
+
環境が<tt>:production</tt>か<tt>:test</tt>の場合に設定する方法:
|
339
692
|
|
340
693
|
configure :production, :test do
|
341
694
|
...
|
@@ -358,7 +711,7 @@ body部を指定することもできます ...
|
|
358
711
|
=== エラー
|
359
712
|
|
360
713
|
+error+ ハンドラーはルートブロックかbeforeフィルタ内で例外が発生した時はいつでも発動します。
|
361
|
-
|
714
|
+
例外オブジェクトはRack変数<tt>sinatra.error</tt>から取得できます。
|
362
715
|
|
363
716
|
error do
|
364
717
|
'エラーが発生しました。 - ' + env['sinatra.error'].name
|
@@ -367,7 +720,7 @@ block or before filter. 例外オブジェクトはRack変数<tt>sinatra.error</
|
|
367
720
|
エラーをカスタマイズする場合は、
|
368
721
|
|
369
722
|
error MyCustomError do
|
370
|
-
'エラーメッセージ...' +
|
723
|
+
'エラーメッセージ...' + env['sinatra.error'].message
|
371
724
|
end
|
372
725
|
|
373
726
|
と書いておいて,下記のように呼び出します。
|
@@ -380,6 +733,23 @@ block or before filter. 例外オブジェクトはRack変数<tt>sinatra.error</
|
|
380
733
|
|
381
734
|
エラーメッセージ... 何かがまずかったようです
|
382
735
|
|
736
|
+
あるいは、ステータスコードに対応するエラーハンドラを設定することもできます:
|
737
|
+
|
738
|
+
error 403 do
|
739
|
+
'Access forbidden'
|
740
|
+
end
|
741
|
+
|
742
|
+
get '/secret' do
|
743
|
+
403
|
744
|
+
end
|
745
|
+
|
746
|
+
範囲指定もできます:
|
747
|
+
|
748
|
+
error 400..510 do
|
749
|
+
'Boom'
|
750
|
+
end
|
751
|
+
|
752
|
+
|
383
753
|
開発環境として実行している場合、Sinatraは特別な<tt>not_found</tt>と<tt>error</tt>ハンドラーを
|
384
754
|
インストールしています。
|
385
755
|
|
@@ -390,6 +760,10 @@ block or before filter. 例外オブジェクトはRack変数<tt>sinatra.error</
|
|
390
760
|
|
391
761
|
mime_type :foo, 'text/foo'
|
392
762
|
|
763
|
+
これはcontent_typeヘルパで利用することができます:
|
764
|
+
|
765
|
+
content_type :foo
|
766
|
+
|
393
767
|
== Rackミドルウェア
|
394
768
|
|
395
769
|
SinatraはRack[http://rack.rubyforge.org/]というRubyのWEBフレームワーク用の
|
@@ -496,16 +870,133 @@ Sinatra::Baseのサブクラスで使えるメソッドはトップレベルのD
|
|
496
870
|
{Sinatra::Delegator mixin}[http://github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb#L1064]
|
497
871
|
{included into the main namespace}[http://github.com/sinatra/sinatra/blob/master/lib/sinatra/main.rb#L25].
|
498
872
|
|
873
|
+
=== Sinatraをミドルウェアとして利用する
|
874
|
+
|
875
|
+
Sinatraは他のRackミドルウェアを利用することができるだけでなく、
|
876
|
+
全てのSinatraアプリケーションは、それ自体ミドルウェアとして別のRackエンドポイントの前に追加することが可能です。
|
877
|
+
|
878
|
+
このエンドポイントには、別のSinatraアプリケーションまたは他のRackベースのアプリケーション(Rails/Ramaze/Camping/...)が用いられるでしょう。
|
879
|
+
|
880
|
+
require 'sinatra/base'
|
881
|
+
|
882
|
+
class LoginScreen < Sinatra::Base
|
883
|
+
enable :sessions
|
884
|
+
|
885
|
+
get('/login') { haml :login }
|
886
|
+
|
887
|
+
post('/login') do
|
888
|
+
if params[:name] = 'admin' and params[:password] = 'admin'
|
889
|
+
session['user_name'] = params[:name]
|
890
|
+
else
|
891
|
+
redirect '/login'
|
892
|
+
end
|
893
|
+
end
|
894
|
+
end
|
895
|
+
|
896
|
+
class MyApp < Sinatra::Base
|
897
|
+
# middleware will run before filters
|
898
|
+
use LoginScreen
|
899
|
+
|
900
|
+
before do
|
901
|
+
unless session['user_name']
|
902
|
+
halt "Access denied, please <a href='/login'>login</a>."
|
903
|
+
end
|
904
|
+
end
|
905
|
+
|
906
|
+
get('/') { "Hello #{session['user_name']}." }
|
907
|
+
end
|
908
|
+
|
909
|
+
== スコープとバインディング
|
910
|
+
|
911
|
+
現在のスコープはどのメソッドや変数が利用可能かを決定します。
|
912
|
+
|
913
|
+
=== アプリケーション/クラスのスコープ
|
914
|
+
|
915
|
+
全てのSinatraアプリケーションはSinatra::Baseのサブクラスに相当します。
|
916
|
+
もしトップレベルDSLを利用しているならば(<tt>require 'sinatra'</tt>)このクラスはSinatra::Applicationであり、
|
917
|
+
そうでなければ、あなたが明示的に作成したサブクラスです。
|
918
|
+
クラスレベルでは`get`や`before`のようなメソッドを持っています。
|
919
|
+
しかし`request`オブジェクトや`session`には、全てのリクエストのために1つのアプリケーションクラスが存在するためアクセスできません。
|
920
|
+
|
921
|
+
`set`によって作られたオプションはクラスレベルのメソッドです:
|
922
|
+
|
923
|
+
class MyApp < Sinatra::Base
|
924
|
+
# Hey, I'm in the application scope!
|
925
|
+
set :foo, 42
|
926
|
+
foo # => 42
|
927
|
+
|
928
|
+
get '/foo' do
|
929
|
+
# Hey, I'm no longer in the application scope!
|
930
|
+
end
|
931
|
+
end
|
932
|
+
|
933
|
+
次の場所ではアプリケーションスコープバインディングを持ちます:
|
934
|
+
|
935
|
+
* アプリケーションのクラス本体
|
936
|
+
* 拡張によって定義されたメソッド
|
937
|
+
* `helpers`に渡されたブロック
|
938
|
+
* `set`の値として使われるProcまたはブロック
|
939
|
+
|
940
|
+
このスコープオブジェクト(クラス)は次のように利用できます:
|
941
|
+
|
942
|
+
* configureブロックに渡されたオブジェクト経由(<tt>configure { |c| ... }</tt>)
|
943
|
+
* リクエストスコープの中での`settings`
|
944
|
+
|
945
|
+
=== リクエスト/インスタンスのスコープ
|
946
|
+
|
947
|
+
やってくるリクエストごとに、あなたのアプリケーションクラスの新しいインスタンスが作成され、全てのハンドラブロックがそのスコープで実行されます。
|
948
|
+
このスコープの内側からは`request`や`session`オブジェクトにアクセスすることができ、`erb`や`haml`のような表示メソッドを呼び出すことができます。
|
949
|
+
リクエストスコープの内側からは、`settings`ヘルパによってアプリケーションスコープにアクセスすることができます。
|
950
|
+
|
951
|
+
class MyApp < Sinatra::Base
|
952
|
+
# Hey, I'm in the application scope!
|
953
|
+
get '/define_route/:name' do
|
954
|
+
# Request scope for '/define_route/:name'
|
955
|
+
@value = 42
|
956
|
+
|
957
|
+
settings.get("/#{params[:name]}") do
|
958
|
+
# Request scope for "/#{params[:name]}"
|
959
|
+
@value # => nil (not the same request)
|
960
|
+
end
|
961
|
+
|
962
|
+
"Route defined!"
|
963
|
+
end
|
964
|
+
end
|
965
|
+
|
966
|
+
次の場所ではリクエストスコープバインディングを持ちます:
|
967
|
+
|
968
|
+
* get/head/post/put/delete ブロック
|
969
|
+
* before/after フィルタ
|
970
|
+
* helper メソッド
|
971
|
+
* テンプレート/ビュー
|
972
|
+
|
973
|
+
=== デリゲートスコープ
|
974
|
+
|
975
|
+
デリゲートスコープは、単にクラススコープにメソッドを転送します。
|
976
|
+
しかしながら、クラスのバインディングを持っていないため、クラススコープと全く同じふるまいをするわけではありません:
|
977
|
+
委譲すると明示的に示されたメソッドのみが利用可能であり、またクラススコープと変数/状態を共有することはできません(注: 異なった`self`を持っています)。
|
978
|
+
<tt>Sinatra::Delegator.delegate :method_name</tt>を呼び出すことによってデリゲートするメソッドを明示的に追加することができます。
|
979
|
+
|
980
|
+
次の場所ではデリゲートスコープを持ちます:
|
981
|
+
|
982
|
+
* もし<tt>require "sinatra"</tt>しているならば、トップレベルバインディング
|
983
|
+
* `Sinatra::Delegator` mixinでextendされたオブジェクト
|
984
|
+
|
985
|
+
コードをご覧ください: ここでは
|
986
|
+
{Sinatra::Delegator mixin}[http://github.com/sinatra/sinatra/blob/ceac46f0bc129a6e994a06100aa854f606fe5992/lib/sinatra/base.rb#L1128]
|
987
|
+
は{main 名前空間にincludeされています}[http://github.com/sinatra/sinatra/blob/ceac46f0bc129a6e994a06100aa854f606fe5992/lib/sinatra/main.rb#L28].
|
988
|
+
|
499
989
|
== コマンドライン
|
500
990
|
|
501
991
|
Sinatraアプリケーションは直接実行できます。
|
502
992
|
|
503
|
-
ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-s HANDLER]
|
993
|
+
ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-o HOST] [-s HANDLER]
|
504
994
|
|
505
995
|
オプション:
|
506
996
|
|
507
997
|
-h # ヘルプ
|
508
998
|
-p # ポート指定(デフォルトは4567)
|
999
|
+
-o # ホスト指定(デフォルトは0.0.0.0)
|
509
1000
|
-e # 環境を指定 (デフォルトはdevelopment)
|
510
1001
|
-s # rackserver/handlerを指定 (デフォルトはthin)
|
511
1002
|
-x # mutex lockを付ける (デフォルトはoff)
|
@@ -519,7 +1010,7 @@ Sinatraの開発版を使いたい場合は、ローカルに開発版を落と
|
|
519
1010
|
git clone git://github.com/sinatra/sinatra.git
|
520
1011
|
ruby -Isinatra/lib myapp.rb
|
521
1012
|
|
522
|
-
<tt>sinatra/lib</tt
|
1013
|
+
<tt>sinatra/lib</tt>ディレクトリをアプリケーションの<tt>LOAD_PATH</tt>に追加する方法もあります。
|
523
1014
|
|
524
1015
|
$LOAD_PATH.unshift File.dirname(__FILE__) + '/sinatra/lib'
|
525
1016
|
require 'rubygems'
|
@@ -546,7 +1037,7 @@ Sinatraのソースを更新する方法:
|
|
546
1037
|
ニュース、他のリソースへのリンクがあります。
|
547
1038
|
* {プロジェクトに参加(貢献)する}[http://sinatra.github.com/contributing.html] - バグレポート
|
548
1039
|
パッチの送信、サポートなど
|
549
|
-
* {
|
1040
|
+
* {Issue tracker}[http://github.com/sinatra/sinatra/issues] - チケット管理とリリース計画
|
550
1041
|
* {Twitter}[http://twitter.com/sinatra]
|
551
1042
|
* {メーリングリスト}[http://groups.google.com/group/sinatrarb]
|
552
1043
|
* {IRC: #sinatra}[irc://chat.freenode.net/#sinatra] on http://freenode.net
|