sinatra 1.4.0.c → 1.4.0.d

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.

@@ -1,1056 +0,0 @@
1
- = Sinatra
2
- <i>注) 本文書は英語から翻訳したものであり、その内容が最新でない場合もあります。最新の情報はオリジナルの英語版を参照して下さい。</i>
3
-
4
- SinatraはRubyで下記のような最小労力で手早くウェブアプリケーションを作成するための{DSL}[http://ja.wikipedia.org/wiki/ドメイン固有言語]です。
5
-
6
- # myapp.rb
7
- require 'sinatra'
8
- get '/' do
9
- 'Hello world!'
10
- end
11
-
12
- gemをインストールして動かしてみる。
13
-
14
- gem install sinatra
15
- ruby myapp.rb
16
-
17
- http://localhost:4567 を見る。
18
-
19
- == ルート
20
-
21
- Sinatraでは、ルートはHTTPメソッドとURLマッチングパターンがペアになっています。
22
- ルートはブロックに結び付けられています。
23
-
24
- get '/' do
25
- .. 何か見せる ..
26
- end
27
-
28
- post '/' do
29
- .. 何か生成する ..
30
- end
31
-
32
- put '/' do
33
- .. 何か更新する ..
34
- end
35
-
36
- delete '/' do
37
- .. 何か削除する ..
38
- end
39
-
40
- ルートは定義された順番にマッチします。 リクエストに最初にマッチしたルートが呼び出されます。
41
-
42
- ルートのパターンは名前付きパラメータを含むことができ、
43
- <tt>params</tt>ハッシュで取得できます。
44
-
45
- get '/hello/:name' do
46
- # matches "GET /hello/foo" and "GET /hello/bar"
47
- # params[:name] is 'foo' or 'bar'
48
- "Hello #{params[:name]}!"
49
- end
50
-
51
- また、ブロックパラメータで名前付きパラメータにアクセスすることもできます。
52
-
53
- get '/hello/:name' do |n|
54
- "Hello #{n}!"
55
- end
56
-
57
- ルートパターンはsplat(またはワイルドカード)を含むこともでき、
58
- <tt>params[:splat]</tt> で取得できます。
59
-
60
- get '/say/*/to/*' do
61
- # matches /say/hello/to/world
62
- params[:splat] # => ["hello", "world"]
63
- end
64
-
65
- get '/download/*.*' do
66
- # matches /download/path/to/file.xml
67
- params[:splat] # => ["path/to/file", "xml"]
68
- end
69
-
70
- ブロックパラーメータを使用した場合:
71
-
72
- get '/download/*.*' do |path, ext|
73
- [path, ext] # => ["path/to/file", "xml"]
74
- end
75
-
76
- 正規表現を使ったルート:
77
-
78
- get %r{/hello/([\w]+)} do
79
- "Hello, #{params[:captures].first}!"
80
- end
81
-
82
- ブロックパラーメータを使用した場合:
83
-
84
- get %r{/hello/([\w]+)} do |c|
85
- "Hello, #{c}!"
86
- end
87
-
88
-
89
- === 条件
90
-
91
- ルートにはユーザエージェントのようなさまざまな条件を含めることができます。
92
-
93
- get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
94
- "You're using Songbird version #{params[:agent][0]}"
95
- end
96
-
97
- get '/foo' do
98
- # Matches non-songbird browsers
99
- end
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
-
153
- == 静的ファイル
154
-
155
- 静的ファイルは<tt>./public</tt>ディレクトリから配信されます。
156
- <tt>:public_folder</tt>オプションを指定することで別の場所を指定することができます。
157
-
158
- set :public_folder, File.dirname(__FILE__) + '/static'
159
-
160
- 注意: この静的ファイル用のディレクトリ名はURL中に含まれません。
161
- 例えば、<tt>./public/css/style.css</tt>は<tt>http://example.com/css/style.css</tt>でアクセスできます。
162
-
163
- == ビュー / テンプレート
164
-
165
- テンプレートは<tt>./views</tt>ディレクトリ下に配置されています。
166
- 他のディレクトリを使用する場合の例:
167
-
168
- set :views, File.dirname(__FILE__) + '/templates'
169
-
170
- テンプレートはシンボルを使用して参照させることを覚えておいて下さい。
171
- サブデレクトリでもこの場合は<tt>:'subdir/template'</tt>のようにします。
172
- レンダリングメソッドは文字列が渡されると、そのまま文字列を出力します。
173
-
174
- === Haml テンプレート
175
-
176
- hamlを使うにはhamlライブラリが必要です:
177
-
178
- # hamlを読み込みます
179
- require 'haml'
180
-
181
- get '/' do
182
- haml :index
183
- end
184
-
185
- <tt>./views/index.haml</tt>を表示します。
186
-
187
- {Haml's options}[http://haml.info/docs/yardoc/file.HAML_REFERENCE.html#options]
188
- はSinatraの設定でグローバルに設定することができます。
189
- {Options and Configurations}[http://www.sinatrarb.com/configuration.html],
190
- を参照してそれぞれ設定を上書きして下さい。
191
-
192
- set :haml, {:format => :html5 } # デフォルトのフォーマットは:xhtml
193
-
194
- get '/' do
195
- haml :index, :haml_options => {:format => :html4 } # 上書き
196
- end
197
-
198
-
199
- === Erb テンプレート
200
-
201
- # erbを読み込みます
202
- require 'erb'
203
-
204
- get '/' do
205
- erb :index
206
- end
207
-
208
- <tt>./views/index.erb</tt>を表示します。
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
-
223
- === Builder テンプレート
224
-
225
- builderを使うにはbuilderライブラリが必要です:
226
-
227
- # builderを読み込みます
228
- require 'builder'
229
-
230
- get '/' do
231
- builder :index
232
- end
233
-
234
- <tt>./views/index.builder</tt>を表示します。
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
-
249
- === Sass テンプレート
250
-
251
- Sassテンプレートを使うにはsassライブラリが必要です:
252
-
253
- # hamlかsassを読み込みます
254
- require 'sass'
255
-
256
- get '/stylesheet.css' do
257
- sass :stylesheet
258
- end
259
-
260
- <tt>./views/stylesheet.sass</tt>を表示します。
261
-
262
- {Sass' options}[http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#options]
263
- はSinatraの設定でグローバルに設定することができます。
264
- see {Options and Configurations}[http://www.sinatrarb.com/configuration.html],
265
- を参照してそれぞれ設定を上書きして下さい。
266
-
267
- set :sass, {:style => :compact } # デフォルトのSass styleは :nested
268
-
269
- get '/stylesheet.css' do
270
- sass :stylesheet, :sass_options => {:style => :expanded } # 上書き
271
- end
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
- === RABL テンプレート
430
-
431
- RABLテンプレートを使うにはrablライブラリが必要です:
432
-
433
- # rablを読み込みます
434
- require 'rabl'
435
-
436
- get '/' do
437
- rabl :index
438
- end
439
-
440
- <tt>./views/index.rabl</tt>を表示します。
441
-
442
- === Slim テンプレート
443
-
444
- Slimテンプレートを使うにはslimライブラリが必要です:
445
-
446
- # slimを読み込みます
447
- require 'slim'
448
-
449
- get '/' do
450
- slim :index
451
- end
452
-
453
- <tt>./views/index.slim</tt>を表示します。
454
-
455
- === Creole テンプレート
456
-
457
- Creoleテンプレートを使うにはcreoleライブラリが必要です:
458
-
459
- # creoleを読み込みます
460
- require 'creole'
461
-
462
- get '/' do
463
- creole :index
464
- end
465
-
466
- <tt>./views/index.creole</tt>を表示します。
467
-
468
- === CoffeeScript テンプレート
469
-
470
- CoffeeScriptテンプレートを表示するにはcoffee-scriptライブラリと`coffee`バイナリが必要です:
471
-
472
- # coffee-scriptを読み込みます
473
- require 'coffee-script'
474
-
475
- get '/application.js' do
476
- coffee :application
477
- end
478
-
479
- <tt>./views/application.coffee</tt>を表示します。
480
-
481
- === インラインテンプレート
482
-
483
- get '/' do
484
- haml '%div.title Hello World'
485
- end
486
-
487
- 文字列をテンプレートとして表示します。
488
-
489
- === テンプレート内で変数にアクセスする
490
-
491
- テンプレートはルートハンドラと同じコンテキストの中で評価されます。. ルートハンドラでセットされたインスタンス変数は
492
- テンプレート内で直接使うことができます。
493
-
494
- get '/:id' do
495
- @foo = Foo.find(params[:id])
496
- haml '%h1= @foo.name'
497
- end
498
-
499
- ローカル変数を明示的に定義することもできます。
500
-
501
- get '/:id' do
502
- foo = Foo.find(params[:id])
503
- haml '%h1= foo.name', :locals => { :foo => foo }
504
- end
505
-
506
- このやり方は他のテンプレート内で部分テンプレートとして表示する時に典型的に使用されます。
507
-
508
- === ファイル内テンプレート
509
-
510
- テンプレートはソースファイルの最後で定義することもできます。
511
-
512
- require 'rubygems'
513
- require 'sinatra'
514
-
515
- get '/' do
516
- haml :index
517
- end
518
-
519
- __END__
520
-
521
- @@ layout
522
- %html
523
- = yield
524
-
525
- @@ index
526
- %div.title Hello world!!!!!
527
-
528
- 注意: sinatraをrequireするファイル内で定義されたファイル内テンプレートは自動的に読み込まれます。
529
- 他のファイルで定義されているテンプレートを使うには <tt>enable :inline_templates</tt>を明示的に呼んでください。
530
-
531
- === 名前付きテンプレート
532
-
533
- テンプレートはトップレベルの<tt>template</tt>メソッドで定義することができます。
534
-
535
- template :layout do
536
- "%html\n =yield\n"
537
- end
538
-
539
- template :index do
540
- '%div.title Hello World!'
541
- end
542
-
543
- get '/' do
544
- haml :index
545
- end
546
-
547
- 「layout」というテンプレートが存在する場合、そのテンプレートファイルは他のテンプレートが
548
- 表示される度に使用されます。<tt>:layout => false</tt>することでlayoutsを無効にできます。
549
-
550
- get '/' do
551
- haml :index, :layout => !request.xhr?
552
- end
553
-
554
- == ヘルパー
555
-
556
- トップレベルの<tt>helpers</tt>を使用してルートハンドラやテンプレートで使うヘルパメソッドを
557
- 定義できます。
558
-
559
- helpers do
560
- def bar(name)
561
- "#{name}bar"
562
- end
563
- end
564
-
565
- get '/:name' do
566
- bar(params[:name])
567
- end
568
-
569
- == フィルタ
570
-
571
- beforeフィルタはリクエストされたコンテキストを実行する前に評価され、
572
- リクエストとレスポンスを変更することができます。フィルタ内でセットされた
573
- インスタンス変数はルーティングとテンプレートで使用できます。
574
-
575
- before do
576
- @note = 'Hi!'
577
- request.path_info = '/foo/bar/baz'
578
- end
579
-
580
- get '/foo/*' do
581
- @note #=> 'Hi!'
582
- params[:splat] #=> 'bar/baz'
583
- end
584
-
585
- afterフィルタは同じコンテキストにあるリクエストの後に評価され、
586
- 同じくリクエストとレスポンスを変更することができます。
587
- beforeフィルタとルートで設定されたインスタンス変数は、
588
- afterフィルタからアクセスすることができます:
589
-
590
- after do
591
- puts response.status
592
- end
593
-
594
- フィルタにはオプションとしてパターンを渡すことができ、
595
- この場合はリクエストのパスがパターンにマッチした場合のみフィルタが評価されます:
596
-
597
- before '/protected/*' do
598
- authenticate!
599
- end
600
-
601
- after '/create/:slug' do |slug|
602
- session[:last_slug] = slug
603
- end
604
-
605
- == 強制終了
606
-
607
- ルートかbeforeフィルタ内で直ちに実行を終了する方法:
608
-
609
- halt
610
-
611
- ステータスを指定することができます:
612
-
613
- halt 410
614
-
615
- body部を指定することもできます ...
616
-
617
- halt 'ここにbodyを書く'
618
-
619
- ステータスとbody部を指定する ...
620
-
621
- halt 401, '立ち去れ!'
622
-
623
- ヘッダを指定:
624
-
625
- halt 402, {'Content-Type' => 'text/plain'}, 'リベンジ'
626
-
627
- == パッシング(Passing)
628
-
629
- ルートは<tt>pass</tt>を使って次のルートに飛ばすことができます:
630
-
631
- get '/guess/:who' do
632
- pass unless params[:who] == 'Frank'
633
- "見つかっちゃった!"
634
- end
635
-
636
- get '/guess/*' do
637
- "はずれです!"
638
- end
639
-
640
- ルートブロックからすぐに抜け出し、次にマッチするルートを実行します。
641
- マッチするルートが見当たらない場合は404が返されます。
642
-
643
- == リクエストオブジェクトへのアクセス
644
-
645
- 受信するリクエストオブジェクトは、`request`メソッドを通じてリクエストレベル(フィルタ、ルート、エラーハンドラ)からアクセスすることができます:
646
-
647
- # アプリケーションが http://example.com/example で動作している場合
648
- get '/foo' do
649
- request.body # クライアントによって送信されたリクエストボディ(下記参照)
650
- request.scheme # "http"
651
- request.script_name # "/example"
652
- request.path_info # "/foo"
653
- request.port # 80
654
- request.request_method # "GET"
655
- request.query_string # ""
656
- request.content_length # request.bodyの長さ
657
- request.media_type # request.bodyのメディアタイプ
658
- request.host # "example.com"
659
- request.get? # true (他の動詞についても同様のメソッドあり)
660
- request.form_data? # false
661
- request["SOME_HEADER"] # SOME_HEADERヘッダの値
662
- request.referer # クライアントのリファラまたは'/'
663
- request.user_agent # ユーザエージェント (:agent 条件によって使用される)
664
- request.cookies # ブラウザクッキーのハッシュ
665
- request.xhr? # Ajaxリクエストかどうか
666
- request.url # "http://example.com/example/foo"
667
- request.path # "/example/foo"
668
- request.ip # クライアントのIPアドレス
669
- request.secure? # false
670
- request.env # Rackによって渡された生のenvハッシュ
671
- end
672
-
673
- <tt>script_name</tt>や<tt>path_info</tt>などのオプションは次のように利用することもできます:
674
-
675
- before { request.path_info = "/" }
676
-
677
- get "/" do
678
- "全てのリクエストはここに来る"
679
- end
680
-
681
- <tt>request.body</tt>はIOまたはStringIOのオブジェクトです:
682
-
683
- post "/api" do
684
- request.body.rewind # 既に読まれているときのため
685
- data = JSON.parse request.body.read
686
- "Hello #{data['name']}!"
687
- end
688
-
689
-
690
- == 設定
691
-
692
- どの環境でも起動時に1回だけ実行されます。
693
-
694
- configure do
695
- ...
696
- end
697
-
698
- 環境(RACK_ENV環境変数)が<tt>:production</tt>に設定されている時だけ実行する方法:
699
-
700
- configure :production do
701
- ...
702
- end
703
-
704
- 環境が<tt>:production</tt>か<tt>:test</tt>の場合に設定する方法:
705
-
706
- configure :production, :test do
707
- ...
708
- end
709
-
710
- == エラーハンドリング
711
-
712
- エラーハンドラーはルートコンテキストとbeforeフィルタ内で実行します。
713
- <tt>haml</tt>、<tt>erb</tt>、<tt>halt</tt>などを使うこともできます。
714
-
715
- === Not Found
716
-
717
- <tt>Sinatra::NotFound</tt>が起きた時か レスポンスのステータスコードが
718
- 404の時に<tt>not_found</tt>ハンドラーが発動します。
719
-
720
- not_found do
721
- 'ファイルが存在しません'
722
- end
723
-
724
- === エラー
725
-
726
- +error+ ハンドラーはルートブロックかbeforeフィルタ内で例外が発生した時はいつでも発動します。
727
- 例外オブジェクトはRack変数<tt>sinatra.error</tt>から取得できます。
728
-
729
- error do
730
- 'エラーが発生しました。 - ' + env['sinatra.error'].name
731
- end
732
-
733
- エラーをカスタマイズする場合は、
734
-
735
- error MyCustomError do
736
- 'エラーメッセージ...' + env['sinatra.error'].message
737
- end
738
-
739
- と書いておいて,下記のように呼び出します。
740
-
741
- get '/' do
742
- raise MyCustomError, '何かがまずかったようです'
743
- end
744
-
745
- そうするとこうなります:
746
-
747
- エラーメッセージ... 何かがまずかったようです
748
-
749
- あるいは、ステータスコードに対応するエラーハンドラを設定することもできます:
750
-
751
- error 403 do
752
- 'Access forbidden'
753
- end
754
-
755
- get '/secret' do
756
- 403
757
- end
758
-
759
- 範囲指定もできます:
760
-
761
- error 400..510 do
762
- 'Boom'
763
- end
764
-
765
-
766
- 開発環境として実行している場合、Sinatraは特別な<tt>not_found</tt>と<tt>error</tt>ハンドラーを
767
- インストールしています。
768
-
769
- == MIMEタイプ
770
-
771
- <tt>send_file</tt>か静的ファイルを使う時、Sinatraが理解でいないMIMEタイプがある場合があります。
772
- その時は +mime_type+ を使ってファイル拡張子毎に登録して下さい。
773
-
774
- mime_type :foo, 'text/foo'
775
-
776
- これはcontent_typeヘルパで利用することができます:
777
-
778
- content_type :foo
779
-
780
- == Rackミドルウェア
781
-
782
- SinatraはRack[http://rack.rubyforge.org/]というRubyのWEBフレームワーク用の
783
- 最小限の標準インターフェース 上で動作しています。Rack中でもアプリケーションデベロッパー
784
- 向けに一番興味深い機能はミドルウェア(サーバとアプリケーション間に介在し、モニタリング、HTTPリクエストとレスポンス
785
- の手動操作ができるなど、一般的な機能のいろいろなことを提供するもの)をサポートすることです。
786
-
787
- Sinatraではトップレベルの+use+ メソッドを使ってRackにパイプラインを構築します。
788
-
789
- require 'sinatra'
790
- require 'my_custom_middleware'
791
-
792
- use Rack::Lint
793
- use MyCustomMiddleware
794
-
795
- get '/hello' do
796
- 'Hello World'
797
- end
798
-
799
- <tt>use</tt> の意味は{Rack::Builder}[http://rack.rubyforge.org/doc/classes/Rack/Builder.html] DSLで定義されていることと全て一致します。
800
- 例えば +use+ メソッドはブロック構文のように複数の引数を受け取ることができます。
801
-
802
- use Rack::Auth::Basic do |username, password|
803
- username == 'admin' && password == 'secret'
804
- end
805
-
806
- Rackはログ、デバッギング、URLルーティング、認証、セッションなどいろいろな機能を備えた標準的ミドルウェアです。
807
- Sinatraはその多くのコンポーネントを自動で使うよう基本設定されているため、+use+で明示的に指定する必要はありません。
808
-
809
- == テスト
810
-
811
- SinatraでのテストはRack-basedのテストライブラリかフレームワークを使って書くことができます。
812
- {Rack::Test}[http://gitrdoc.com/brynary/rack-test] をおすすめします。やり方:
813
-
814
- require 'my_sinatra_app'
815
- require 'rack/test'
816
-
817
- class MyAppTest < Test::Unit::TestCase
818
- include Rack::Test::Methods
819
-
820
- def app
821
- Sinatra::Application
822
- end
823
-
824
- def test_my_default
825
- get '/'
826
- assert_equal 'Hello World!', last_response.body
827
- end
828
-
829
- def test_with_params
830
- get '/meet', :name => 'Frank'
831
- assert_equal 'Hello Frank!', last_response.body
832
- end
833
-
834
- def test_with_rack_env
835
- get '/', {}, 'HTTP_USER_AGENT' => 'Songbird'
836
- assert_equal "あなたはSongbirdを使ってますね!", last_response.body
837
- end
838
- end
839
-
840
- 注意: ビルトインのSinatra::TestモジュールとSinatra::TestHarnessクラスは
841
- 0.9.2リリース以降、廃止予定になっています。
842
-
843
- == Sinatra::Base - ミドルウェア、ライブラリ、 モジュラーアプリ
844
-
845
- トップレベル(グローバル領域)上でいろいろ定義していくのは軽量アプリならうまくいきますが、
846
- RackミドルウェアやRails metal、サーバのコンポーネントを含んだシンプルな
847
- ライブラリやSinatraの拡張プログラムを考慮するような場合はそうとは限りません。
848
- トップレベルのDSLがネームスペースを汚染したり、設定を変えてしまうこと(例:./publicや./view)がありえます。
849
- そこでSinatra::Baseの出番です。
850
-
851
- require 'sinatra/base'
852
-
853
- class MyApp < Sinatra::Base
854
- set :sessions, true
855
- set :foo, 'bar'
856
-
857
- get '/' do
858
- 'Hello world!'
859
- end
860
- end
861
-
862
- このMyAppは独立したRackコンポーネントで、RackミドルウェアやRackアプリケーション
863
- Rails metalとして使用することができます。<tt>config.ru</tt>ファイル内で +use+ か、または
864
- +run+ でこのクラスを指定するか、ライブラリとしてサーバコンポーネントをコントロールします。
865
-
866
- MyApp.run! :host => 'localhost', :port => 9090
867
-
868
- Sinatra::Baseのサブクラスで使えるメソッドはトップレベルのDSLを経由して確実に使うことができます。
869
- ほとんどのトップレベルで記述されたアプリは、以下の2点を修正することでSinatra::Baseコンポーネントに変えることができます。
870
-
871
- * +sinatra+の代わりに<tt>sinatra/base</tt>を読み込む
872
- (そうしない場合、SinatraのDSLメソッドの全てがメインネームスペースにインポートされます)
873
- * ルート、エラーハンドラー、フィルター、オプションをSinatra::Baseのサブクラスに書く
874
-
875
- <tt>Sinatra::Base</tt> はまっさらです。ビルトインサーバを含む、ほとんどのオプションがデフォルト
876
- で無効になっています。オプション詳細については{Options and Configuration}[http://sinatra.github.com/configuration.html]
877
- をご覧下さい。
878
-
879
- 補足: SinatraのトップレベルDSLはシンプルな委譲(delgation)システムで実装されています。
880
- <tt>Sinatra::Application</tt>クラス(Sinatra::Baseの特別なサブクラス)は、トップレベルに送られる
881
- :get、 :put、 :post、:delete、 :before、:error、:not_found、 :configure、:set messagesのこれら
882
- 全てを受け取ります。 詳細を閲覧されたい方はこちら(英語):
883
- {Sinatra::Delegator mixin}[http://github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb#L1064]
884
- {included into the main namespace}[http://github.com/sinatra/sinatra/blob/master/lib/sinatra/main.rb#L25].
885
-
886
- === Sinatraをミドルウェアとして利用する
887
-
888
- Sinatraは他のRackミドルウェアを利用することができるだけでなく、
889
- 全てのSinatraアプリケーションは、それ自体ミドルウェアとして別のRackエンドポイントの前に追加することが可能です。
890
-
891
- このエンドポイントには、別のSinatraアプリケーションまたは他のRackベースのアプリケーション(Rails/Ramaze/Camping/...)が用いられるでしょう。
892
-
893
- require 'sinatra/base'
894
-
895
- class LoginScreen < Sinatra::Base
896
- enable :sessions
897
-
898
- get('/login') { haml :login }
899
-
900
- post('/login') do
901
- if params[:name] = 'admin' and params[:password] = 'admin'
902
- session['user_name'] = params[:name]
903
- else
904
- redirect '/login'
905
- end
906
- end
907
- end
908
-
909
- class MyApp < Sinatra::Base
910
- # middleware will run before filters
911
- use LoginScreen
912
-
913
- before do
914
- unless session['user_name']
915
- halt "Access denied, please <a href='/login'>login</a>."
916
- end
917
- end
918
-
919
- get('/') { "Hello #{session['user_name']}." }
920
- end
921
-
922
- == スコープとバインディング
923
-
924
- 現在のスコープはどのメソッドや変数が利用可能かを決定します。
925
-
926
- === アプリケーション/クラスのスコープ
927
-
928
- 全てのSinatraアプリケーションはSinatra::Baseのサブクラスに相当します。
929
- もしトップレベルDSLを利用しているならば(<tt>require 'sinatra'</tt>)このクラスはSinatra::Applicationであり、
930
- そうでなければ、あなたが明示的に作成したサブクラスです。
931
- クラスレベルでは`get`や`before`のようなメソッドを持っています。
932
- しかし`request`オブジェクトや`session`には、全てのリクエストのために1つのアプリケーションクラスが存在するためアクセスできません。
933
-
934
- `set`によって作られたオプションはクラスレベルのメソッドです:
935
-
936
- class MyApp < Sinatra::Base
937
- # Hey, I'm in the application scope!
938
- set :foo, 42
939
- foo # => 42
940
-
941
- get '/foo' do
942
- # Hey, I'm no longer in the application scope!
943
- end
944
- end
945
-
946
- 次の場所ではアプリケーションスコープバインディングを持ちます:
947
-
948
- * アプリケーションのクラス本体
949
- * 拡張によって定義されたメソッド
950
- * `helpers`に渡されたブロック
951
- * `set`の値として使われるProcまたはブロック
952
-
953
- このスコープオブジェクト(クラス)は次のように利用できます:
954
-
955
- * configureブロックに渡されたオブジェクト経由(<tt>configure { |c| ... }</tt>)
956
- * リクエストスコープの中での`settings`
957
-
958
- === リクエスト/インスタンスのスコープ
959
-
960
- やってくるリクエストごとに、あなたのアプリケーションクラスの新しいインスタンスが作成され、全てのハンドラブロックがそのスコープで実行されます。
961
- このスコープの内側からは`request`や`session`オブジェクトにアクセスすることができ、`erb`や`haml`のような表示メソッドを呼び出すことができます。
962
- リクエストスコープの内側からは、`settings`ヘルパによってアプリケーションスコープにアクセスすることができます。
963
-
964
- class MyApp < Sinatra::Base
965
- # Hey, I'm in the application scope!
966
- get '/define_route/:name' do
967
- # Request scope for '/define_route/:name'
968
- @value = 42
969
-
970
- settings.get("/#{params[:name]}") do
971
- # Request scope for "/#{params[:name]}"
972
- @value # => nil (not the same request)
973
- end
974
-
975
- "Route defined!"
976
- end
977
- end
978
-
979
- 次の場所ではリクエストスコープバインディングを持ちます:
980
-
981
- * get/head/post/put/delete ブロック
982
- * before/after フィルタ
983
- * helper メソッド
984
- * テンプレート/ビュー
985
-
986
- === デリゲートスコープ
987
-
988
- デリゲートスコープは、単にクラススコープにメソッドを転送します。
989
- しかしながら、クラスのバインディングを持っていないため、クラススコープと全く同じふるまいをするわけではありません:
990
- 委譲すると明示的に示されたメソッドのみが利用可能であり、またクラススコープと変数/状態を共有することはできません(注: 異なった`self`を持っています)。
991
- <tt>Sinatra::Delegator.delegate :method_name</tt>を呼び出すことによってデリゲートするメソッドを明示的に追加することができます。
992
-
993
- 次の場所ではデリゲートスコープを持ちます:
994
-
995
- * もし<tt>require "sinatra"</tt>しているならば、トップレベルバインディング
996
- * `Sinatra::Delegator` mixinでextendされたオブジェクト
997
-
998
- コードをご覧ください: ここでは
999
- {Sinatra::Delegator mixin}[http://github.com/sinatra/sinatra/blob/ceac46f0bc129a6e994a06100aa854f606fe5992/lib/sinatra/base.rb#L1128]
1000
- は{main 名前空間にincludeされています}[http://github.com/sinatra/sinatra/blob/ceac46f0bc129a6e994a06100aa854f606fe5992/lib/sinatra/main.rb#L28].
1001
-
1002
- == コマンドライン
1003
-
1004
- Sinatraアプリケーションは直接実行できます。
1005
-
1006
- ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-o HOST] [-s HANDLER]
1007
-
1008
- オプション:
1009
-
1010
- -h # ヘルプ
1011
- -p # ポート指定(デフォルトは4567)
1012
- -o # ホスト指定(デフォルトは0.0.0.0)
1013
- -e # 環境を指定 (デフォルトはdevelopment)
1014
- -s # rackserver/handlerを指定 (デフォルトはthin)
1015
- -x # mutex lockを付ける (デフォルトはoff)
1016
-
1017
- == 最新開発版について
1018
-
1019
- Sinatraの開発版を使いたい場合は、ローカルに開発版を落として、
1020
- <tt>LOAD_PATH</tt>の<tt>sinatra/lib</tt>ディレクトリを指定して実行して下さい。
1021
-
1022
- cd myapp
1023
- git clone git://github.com/sinatra/sinatra.git
1024
- ruby -Isinatra/lib myapp.rb
1025
-
1026
- <tt>sinatra/lib</tt>ディレクトリをアプリケーションの<tt>LOAD_PATH</tt>に追加する方法もあります。
1027
-
1028
- $LOAD_PATH.unshift File.dirname(__FILE__) + '/sinatra/lib'
1029
- require 'rubygems'
1030
- require 'sinatra'
1031
-
1032
- get '/about' do
1033
- "今使ってるバージョンは" + Sinatra::VERSION
1034
- end
1035
-
1036
- Sinatraのソースを更新する方法:
1037
-
1038
- cd myproject/sinatra
1039
- git pull
1040
-
1041
- == その他
1042
-
1043
- 日本語サイト
1044
-
1045
- * {Greenbear Laboratory Rack日本語マニュアル}[http://mono.kmc.gr.jp/~yhara/w/?RackReferenceJa] - Rackの日本語マニュアル
1046
-
1047
- 英語サイト
1048
-
1049
- * {プロジェクトサイト}[http://sinatra.github.com/] - ドキュメント、
1050
- ニュース、他のリソースへのリンクがあります。
1051
- * {プロジェクトに参加(貢献)する}[http://sinatra.github.com/contributing.html] - バグレポート
1052
- パッチの送信、サポートなど
1053
- * {Issue tracker}[http://github.com/sinatra/sinatra/issues] - チケット管理とリリース計画
1054
- * {Twitter}[http://twitter.com/sinatra]
1055
- * {メーリングリスト}[http://groups.google.com/group/sinatrarb]
1056
- * {IRC: #sinatra}[irc://chat.freenode.net/#sinatra] on http://freenode.net