sinatra 1.4.4 → 1.4.5

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,1141 +0,0 @@
1
- # Sinatra
2
-
3
- *注)
4
- 本文書は英語から翻訳したものであり、その内容が最新でない場合もあります。最新の情報はオリジナルの英語版を参照して下さい。*
5
-
6
- [DSL](http://ja.wikipedia.org/wiki/ドメイン固有言語)です。
7
-
8
- # myapp.rb
9
- require 'sinatra'
10
- get '/' do
11
- 'Hello world!'
12
- end
13
-
14
- gemをインストールして動かしてみる。
15
-
16
- gem install sinatra
17
- ruby myapp.rb
18
-
19
- [localhost:4567](http://localhost:4567) を見る。
20
-
21
- ## ルート
22
-
23
- Sinatraでは、ルートはHTTPメソッドとURLマッチングパターンがペアになっています。
24
- ルートはブロックに結び付けられています。
25
-
26
- ``` ruby
27
- get '/' do
28
- .. 何か見せる ..
29
- end
30
-
31
- post '/' do
32
- .. 何か生成する ..
33
- end
34
-
35
- put '/' do
36
- .. 何か更新する ..
37
- end
38
-
39
- patch '/' do
40
- .. 何か修正する ..
41
- end
42
-
43
- delete '/' do
44
- .. 何か削除する ..
45
- end
46
-
47
- options '/' do
48
- .. 何か満たす ..
49
- end
50
-
51
- link '/' do
52
- .. 何かリンクを張る ..
53
- end
54
-
55
- unlink '/' do
56
- .. 何かアンリンクする ..
57
- end
58
- ```
59
-
60
- ルートは定義された順番にマッチします。
61
- リクエストに最初にマッチしたルートが呼び出されます。
62
-
63
- ルートのパターンは名前付きパラメータを含むことができ、
64
- `params`ハッシュで取得できます。
65
-
66
- ``` ruby
67
- get '/hello/:name' do
68
- # "GET /hello/foo" と "GET /hello/bar" にマッチ
69
- # params[:name] は 'foo' か 'bar'
70
- "Hello #{params[:name]}!"
71
- end
72
- ```
73
-
74
- また、ブロックパラメータで名前付きパラメータにアクセスすることもできます。
75
-
76
- ``` ruby
77
- get '/hello/:name' do |n|
78
- # "GET /hello/foo" と "GET /hello/bar" にマッチ
79
- # params[:name] は 'foo' か 'bar'
80
- # n が params[:name] を保持
81
- "Hello #{n}!"
82
- end
83
- ```
84
-
85
- ルートパターンはsplat(またはワイルドカード)を含むこともでき、
86
- `params[:splat]` で取得できます。
87
-
88
- ``` ruby
89
- get '/say/*/to/*' do
90
- # /say/hello/to/world にマッチ
91
- params[:splat] # => ["hello", "world"]
92
- end
93
-
94
- get '/download/*.*' do
95
- # /download/path/to/file.xml にマッチ
96
- params[:splat] # => ["path/to/file", "xml"]
97
- end
98
- ```
99
-
100
- ブロックパラーメータを使用した場合:
101
-
102
- ``` ruby
103
- get '/download/*.*' do |path, ext|
104
- [path, ext] # => ["path/to/file", "xml"]
105
- end
106
- ```
107
-
108
- 正規表現を使用した場合:
109
-
110
- ``` ruby
111
- get %r{/hello/([\w]+)} do
112
- "Hello, #{params[:captures].first}!"
113
- end
114
- ```
115
-
116
- ブロックパラーメータを使用した場合:
117
-
118
- ``` ruby
119
- get %r{/hello/([\w]+)} do |c|
120
- "Hello, #{c}!"
121
- end
122
- ```
123
-
124
- オプショナルパラメーターを使用した場合:
125
-
126
- ``` ruby
127
- get '/posts.?:format?' do
128
- # "GET /posts" と "GET /posts.json", "GET /posts.xml" の拡張子などにマッチ
129
- end
130
- ```
131
-
132
- ところで、ディレクトリトラバーサル保護機能を無効にしないと(下記参照)、
133
- ルートにマッチする前にリクエストパスが修正される可能性があります。
134
-
135
- ### 条件
136
-
137
- ルートにはユーザエージェントのようなさまざまな条件を含めることができます。
138
-
139
- get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
140
- "You're using Songbird version #{params[:agent][0]}"
141
- end
142
-
143
- get '/foo' do
144
- # Matches non-songbird browsers
145
- end
146
-
147
- ほかに`host_name`と`provides`条件が利用可能です:
148
-
149
- get '/', :host_name => /^admin\./ do
150
- "Admin Area, Access denied!"
151
- end
152
-
153
- get '/', :provides => 'html' do
154
- haml :index
155
- end
156
-
157
- get '/', :provides => ['rss', 'atom', 'xml'] do
158
- builder :feed
159
- end
160
-
161
- 独自の条件を定義することも簡単にできます:
162
-
163
- set(:probability) { |value| condition { rand <= value } }
164
-
165
- get '/win_a_car', :probability => 0.1 do
166
- "You won!"
167
- end
168
-
169
- get '/win_a_car' do
170
- "Sorry, you lost."
171
- end
172
-
173
- ### 戻り値
174
-
175
- ルートブロックの戻り値は、HTTPクライアントまたはRackスタックでの次のミドルウェアに渡されるレスポンスボディを決定します。
176
-
177
- これは大抵の場合、上の例のように文字列ですが、それ以外の値も使用することができます。
178
-
179
- Rackレスポンス、Rackボディオブジェクト、HTTPステータスコードのいずれかとして
180
- 妥当なオブジェクトであればどのようなオブジェクトでも返すことができます:
181
-
182
- - 3要素の配列:
183
- `[ステータス(Fixnum), ヘッダ(Hash), レスポンスボディ(#eachに応答する)]`
184
-
185
- - 2要素の配列:
186
- `[ステータス(Fixnum), レスポンスボディ(#eachに応答する)]`
187
-
188
- - `#each`に応答し、与えられたブロックに文字列を渡すオブジェクト
189
-
190
- - ステータスコードを表現するFixnum
191
-
192
- そのように、例えばストリーミングの例を簡単に実装することができます:
193
-
194
- class Stream
195
- def each
196
- 100.times { |i| yield "#{i}\n" }
197
- end
198
- end
199
-
200
- get('/') { Stream.new }
201
-
202
- ## 静的ファイル
203
-
204
- 静的ファイルは`./public`ディレクトリから配信されます。
205
- `:public_folder`オプションを指定することで別の場所を指定することができます。
206
-
207
- set :public_folder, File.dirname(__FILE__) + '/static'
208
-
209
- 注意: この静的ファイル用のディレクトリ名はURL中に含まれません。
210
- 例えば、`./public/css/style.css`は`http://example.com/css/style.css`でアクセスできます。
211
-
212
- ## ビュー / テンプレート
213
-
214
- テンプレートは`./views`ディレクトリ下に配置されています。
215
- 他のディレクトリを使用する場合の例:
216
-
217
- set :views, File.dirname(__FILE__) + '/templates'
218
-
219
- テンプレートはシンボルを使用して参照させることを覚えておいて下さい。
220
- サブデレクトリでもこの場合は`:'subdir/template'`のようにします。
221
- レンダリングメソッドは文字列が渡されると、そのまま文字列を出力します。
222
-
223
- ### Haml テンプレート
224
-
225
- hamlを使うにはhamlライブラリが必要です:
226
-
227
- # hamlを読み込みます
228
- require 'haml'
229
-
230
- get '/' do
231
- haml :index
232
- end
233
-
234
- `./views/index.haml`を表示します。
235
-
236
- [Haml’s
237
- options](http://haml.info/docs/yardoc/file.HAML_REFERENCE.html#options)
238
- はSinatraの設定でグローバルに設定することができます。 [Options and
239
- Configurations](http://www.sinatrarb.com/configuration.html),
240
- を参照してそれぞれ設定を上書きして下さい。
241
-
242
- set :haml, {:format => :html5 } # デフォルトのフォーマットは:xhtml
243
-
244
- get '/' do
245
- haml :index, :haml_options => {:format => :html4 } # 上書き
246
- end
247
-
248
- ### Erb テンプレート
249
-
250
- # erbを読み込みます
251
- require 'erb'
252
-
253
- get '/' do
254
- erb :index
255
- end
256
-
257
- `./views/index.erb`を表示します。
258
-
259
- ### Erubis
260
-
261
- erubisテンプレートを表示するには、erubisライブラリが必要です:
262
-
263
- # erubisを読み込みます
264
- require 'erubis'
265
-
266
- get '/' do
267
- erubis :index
268
- end
269
-
270
- `./views/index.erubis`を表示します。
271
-
272
- ### Builder テンプレート
273
-
274
- builderを使うにはbuilderライブラリが必要です:
275
-
276
- # builderを読み込みます
277
- require 'builder'
278
-
279
- get '/' do
280
- builder :index
281
- end
282
-
283
- `./views/index.builder`を表示します。
284
-
285
- ### 鋸 テンプレート
286
-
287
- 鋸を使うには鋸ライブラリが必要です:
288
-
289
- # 鋸を読み込みます
290
- require 'nokogiri'
291
-
292
- get '/' do
293
- nokogiri :index
294
- end
295
-
296
- `./views/index.nokogiri`を表示します。
297
-
298
- ### Sass テンプレート
299
-
300
- Sassテンプレートを使うにはsassライブラリが必要です:
301
-
302
- # hamlかsassを読み込みます
303
- require 'sass'
304
-
305
- get '/stylesheet.css' do
306
- sass :stylesheet
307
- end
308
-
309
- `./views/stylesheet.sass`を表示します。
310
-
311
- [Sass’
312
- options](http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#options)
313
- はSinatraの設定でグローバルに設定することができます。 see [Options and
314
- Configurations](http://www.sinatrarb.com/configuration.html),
315
- を参照してそれぞれ設定を上書きして下さい。
316
-
317
- set :sass, {:style => :compact } # デフォルトのSass styleは :nested
318
-
319
- get '/stylesheet.css' do
320
- sass :stylesheet, :sass_options => {:style => :expanded } # 上書き
321
- end
322
-
323
- ### Scss テンプレート
324
-
325
- Scssテンプレートを使うにはsassライブラリが必要です:
326
-
327
- # hamlかsassを読み込みます
328
- require 'sass'
329
-
330
- get '/stylesheet.css' do
331
- scss :stylesheet
332
- end
333
-
334
- `./views/stylesheet.scss`を表示します。
335
-
336
- [Sass’
337
- options](http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#options)
338
- はSinatraの設定でグローバルに設定することができます。 see [Options and
339
- Configurations](http://www.sinatrarb.com/configuration.html),
340
- を参照してそれぞれ設定を上書きして下さい。
341
-
342
- set :scss, :style => :compact # デフォルトのScss styleは:nested
343
-
344
- get '/stylesheet.css' do
345
- scss :stylesheet, :style => :expanded # 上書き
346
- end
347
-
348
- ### Less テンプレート
349
-
350
- Lessテンプレートを使うにはlessライブラリが必要です:
351
-
352
- # lessを読み込みます
353
- require 'less'
354
-
355
- get '/stylesheet.css' do
356
- less :stylesheet
357
- end
358
-
359
- `./views/stylesheet.less`を表示します。
360
-
361
- ### Liquid テンプレート
362
-
363
- Liquidテンプレートを使うにはliquidライブラリが必要です:
364
-
365
- # liquidを読み込みます
366
- require 'liquid'
367
-
368
- get '/' do
369
- liquid :index
370
- end
371
-
372
- `./views/index.liquid`を表示します。
373
-
374
- LiquidテンプレートからRubyのメソッド(`yield`を除く)を呼び出すことができないため、
375
- ほぼ全ての場合にlocalsを指定する必要があるでしょう:
376
-
377
- liquid :index, :locals => { :key => 'value' }
378
-
379
- ### Markdown テンプレート
380
-
381
- Markdownテンプレートを使うにはrdiscountライブラリが必要です:
382
-
383
- # rdiscountを読み込みます
384
- require "rdiscount"
385
-
386
- get '/' do
387
- markdown :index
388
- end
389
-
390
- `./views/index.markdown`を表示します。(`md`と`mkd`も妥当な拡張子です)
391
-
392
- markdownからメソッドを呼び出すことも、localsに変数を渡すこともできません。
393
- それゆえ、他のレンダリングエンジンとの組み合わせで使うのが普通です:
394
-
395
- erb :overview, :locals => { :text => markdown(:introduction) }
396
-
397
- 他のテンプレートからmarkdownメソッドを呼び出してもよいことに注意してください:
398
-
399
- %h1 Hello From Haml!
400
- %p= markdown(:greetings)
401
-
402
- ### Textile テンプレート
403
-
404
- Textileテンプレートを使うにはRedClothライブラリが必要です:
405
-
406
- # redclothを読み込みます
407
- require "redcloth"
408
-
409
- get '/' do
410
- textile :index
411
- end
412
-
413
- `./views/index.textile`を表示します。
414
-
415
- textileからメソッドを呼び出すことも、localsに変数を渡すこともできません。
416
- それゆえ、他のレンダリングエンジンとの組み合わせで使うのが普通です:
417
-
418
- erb :overview, :locals => { :text => textile(:introduction) }
419
-
420
- 他のテンプレートからtextileメソッドを呼び出してもよいことに注意してください:
421
-
422
- %h1 Hello From Haml!
423
- %p= textile(:greetings)
424
-
425
- ### RDoc テンプレート
426
-
427
- RDocテンプレートを使うにはRDocライブラリが必要です:
428
-
429
- # rdoc/markup/to_htmlを読み込みます
430
- require "rdoc"
431
- require "rdoc/markup/to_html"
432
-
433
- get '/' do
434
- rdoc :index
435
- end
436
-
437
- `./views/index.rdoc`を表示します。
438
-
439
- rdocからメソッドを呼び出すことも、localsに変数を渡すこともできません。
440
- それゆえ、他のレンダリングエンジンとの組み合わせで使うのが普通です:
441
-
442
- erb :overview, :locals => { :text => rdoc(:introduction) }
443
-
444
- 他のテンプレートからrdocメソッドを呼び出してもよいことに注意してください:
445
-
446
- %h1 Hello From Haml!
447
- %p= rdoc(:greetings)
448
-
449
- ### Radius テンプレート
450
-
451
- Radiusテンプレートを使うにはradiusライブラリが必要です:
452
-
453
- # radiusを読み込みます
454
- require 'radius'
455
-
456
- get '/' do
457
- radius :index
458
- end
459
-
460
- `./views/index.radius`を表示します。
461
-
462
- RadiusテンプレートからRubyのメソッド(`yield`を除く)を呼び出すことができないため、
463
- ほぼ全ての場合にlocalsを指定する必要があるでしょう:
464
-
465
- radius :index, :locals => { :key => 'value' }
466
-
467
- ### Markaby テンプレート
468
-
469
- Markabyテンプレートを使うにはmarkabyライブラリが必要です:
470
-
471
- # markabyを読み込みます
472
- require 'markaby'
473
-
474
- get '/' do
475
- markaby :index
476
- end
477
-
478
- `./views/index.mab`を表示します。
479
-
480
- ### RABL テンプレート
481
-
482
- RABLテンプレートを使うにはrablライブラリが必要です:
483
-
484
- # rablを読み込みます
485
- require 'rabl'
486
-
487
- get '/' do
488
- rabl :index
489
- end
490
-
491
- `./views/index.rabl`を表示します。
492
-
493
- ### Slim テンプレート
494
-
495
- Slimテンプレートを使うにはslimライブラリが必要です:
496
-
497
- # slimを読み込みます
498
- require 'slim'
499
-
500
- get '/' do
501
- slim :index
502
- end
503
-
504
- `./views/index.slim`を表示します。
505
-
506
- ### Creole テンプレート
507
-
508
- Creoleテンプレートを使うにはcreoleライブラリが必要です:
509
-
510
- # creoleを読み込みます
511
- require 'creole'
512
-
513
- get '/' do
514
- creole :index
515
- end
516
-
517
- `./views/index.creole`を表示します。
518
-
519
- ### CoffeeScript テンプレート
520
-
521
- CoffeeScriptテンプレートを表示するにはcoffee-scriptライブラリと\`coffee\`バイナリが必要です:
522
-
523
- # coffee-scriptを読み込みます
524
- require 'coffee-script'
525
-
526
- get '/application.js' do
527
- coffee :application
528
- end
529
-
530
- `./views/application.coffee`を表示します。
531
-
532
- ### インラインテンプレート
533
-
534
- get '/' do
535
- haml '%div.title Hello World'
536
- end
537
-
538
- 文字列をテンプレートとして表示します。
539
-
540
- ### テンプレート内で変数にアクセスする
541
-
542
- テンプレートはルートハンドラと同じコンテキストの中で評価されます。.
543
- ルートハンドラでセットされたインスタンス変数は
544
- テンプレート内で直接使うことができます。
545
-
546
- get '/:id' do
547
- @foo = Foo.find(params[:id])
548
- haml '%h1= @foo.name'
549
- end
550
-
551
- ローカル変数を明示的に定義することもできます。
552
-
553
- get '/:id' do
554
- foo = Foo.find(params[:id])
555
- haml '%h1= foo.name', :locals => { :foo => foo }
556
- end
557
-
558
- このやり方は他のテンプレート内で部分テンプレートとして表示する時に典型的に使用されます。
559
-
560
- ### ファイル内テンプレート
561
-
562
- テンプレートはソースファイルの最後で定義することもできます。
563
-
564
- require 'rubygems'
565
- require 'sinatra'
566
-
567
- get '/' do
568
- haml :index
569
- end
570
-
571
- __END__
572
-
573
- @@ layout
574
- %html
575
- = yield
576
-
577
- @@ index
578
- %div.title Hello world!!!!!
579
-
580
- 注意:
581
- sinatraをrequireするファイル内で定義されたファイル内テンプレートは自動的に読み込まれます。
582
- 他のファイルで定義されているテンプレートを使うには
583
- `enable :inline_templates`を明示的に呼んでください。
584
-
585
- ### 名前付きテンプレート
586
-
587
- テンプレートはトップレベルの`template`メソッドで定義することができます。
588
-
589
- template :layout do
590
- "%html\n =yield\n"
591
- end
592
-
593
- template :index do
594
- '%div.title Hello World!'
595
- end
596
-
597
- get '/' do
598
- haml :index
599
- end
600
-
601
- 「layout」というテンプレートが存在する場合、そのテンプレートファイルは他のテンプレートが
602
- 表示される度に使用されます。`:layout => false`することでlayoutsを無効にできます。
603
-
604
- get '/' do
605
- haml :index, :layout => !request.xhr?
606
- end
607
-
608
- ## ヘルパー
609
-
610
- トップレベルの`helpers`を使用してルートハンドラやテンプレートで使うヘルパメソッドを
611
- 定義できます。
612
-
613
- helpers do
614
- def bar(name)
615
- "#{name}bar"
616
- end
617
- end
618
-
619
- get '/:name' do
620
- bar(params[:name])
621
- end
622
-
623
- ## フィルタ
624
-
625
- beforeフィルタはリクエストされたコンテキストを実行する前に評価され、
626
- リクエストとレスポンスを変更することができます。フィルタ内でセットされた
627
- インスタンス変数はルーティングとテンプレートで使用できます。
628
-
629
- before do
630
- @note = 'Hi!'
631
- request.path_info = '/foo/bar/baz'
632
- end
633
-
634
- get '/foo/*' do
635
- @note #=> 'Hi!'
636
- params[:splat] #=> 'bar/baz'
637
- end
638
-
639
- afterフィルタは同じコンテキストにあるリクエストの後に評価され、
640
- 同じくリクエストとレスポンスを変更することができます。
641
- beforeフィルタとルートで設定されたインスタンス変数は、
642
- afterフィルタからアクセスすることができます:
643
-
644
- after do
645
- puts response.status
646
- end
647
-
648
- フィルタにはオプションとしてパターンを渡すことができ、
649
- この場合はリクエストのパスがパターンにマッチした場合のみフィルタが評価されます:
650
-
651
- before '/protected/*' do
652
- authenticate!
653
- end
654
-
655
- after '/create/:slug' do |slug|
656
- session[:last_slug] = slug
657
- end
658
-
659
- ## 強制終了
660
-
661
- ルートかbeforeフィルタ内で直ちに実行を終了する方法:
662
-
663
- halt
664
-
665
- ステータスを指定することができます:
666
-
667
- halt 410
668
-
669
- body部を指定することもできます …
670
-
671
- halt 'ここにbodyを書く'
672
-
673
- ステータスとbody部を指定する …
674
-
675
- halt 401, '立ち去れ!'
676
-
677
- ヘッダを指定:
678
-
679
- halt 402, {'Content-Type' => 'text/plain'}, 'リベンジ'
680
-
681
- ## パッシング(Passing)
682
-
683
- ルートは`pass`を使って次のルートに飛ばすことができます:
684
-
685
- get '/guess/:who' do
686
- pass unless params[:who] == 'Frank'
687
- "見つかっちゃった!"
688
- end
689
-
690
- get '/guess/*' do
691
- "はずれです!"
692
- end
693
-
694
- ルートブロックからすぐに抜け出し、次にマッチするルートを実行します。
695
- マッチするルートが見当たらない場合は404が返されます。
696
-
697
- ## リクエストオブジェクトへのアクセス
698
-
699
- 受信するリクエストオブジェクトは、\`request\`メソッドを通じてリクエストレベル(フィルタ、ルート、エラーハンドラ)からアクセスすることができます:
700
-
701
- # アプリケーションが http://example.com/example で動作している場合
702
- get '/foo' do
703
- request.body # クライアントによって送信されたリクエストボディ(下記参照)
704
- request.scheme # "http"
705
- request.script_name # "/example"
706
- request.path_info # "/foo"
707
- request.port # 80
708
- request.request_method # "GET"
709
- request.query_string # ""
710
- request.content_length # request.bodyの長さ
711
- request.media_type # request.bodyのメディアタイプ
712
- request.host # "example.com"
713
- request.get? # true (他の動詞についても同様のメソッドあり)
714
- request.form_data? # false
715
- request["SOME_HEADER"] # SOME_HEADERヘッダの値
716
- request.referer # クライアントのリファラまたは'/'
717
- request.user_agent # ユーザエージェント (:agent 条件によって使用される)
718
- request.cookies # ブラウザクッキーのハッシュ
719
- request.xhr? # Ajaxリクエストかどうか
720
- request.url # "http://example.com/example/foo"
721
- request.path # "/example/foo"
722
- request.ip # クライアントのIPアドレス
723
- request.secure? # false
724
- request.env # Rackによって渡された生のenvハッシュ
725
- end
726
-
727
- `script_name`や`path_info`などのオプションは次のように利用することもできます:
728
-
729
- before { request.path_info = "/" }
730
-
731
- get "/" do
732
- "全てのリクエストはここに来る"
733
- end
734
-
735
- `request.body`はIOまたはStringIOのオブジェクトです:
736
-
737
- post "/api" do
738
- request.body.rewind # 既に読まれているときのため
739
- data = JSON.parse request.body.read
740
- "Hello #{data['name']}!"
741
- end
742
-
743
- ## 設定
744
-
745
- どの環境でも起動時に1回だけ実行されます。
746
-
747
- configure do
748
- ...
749
- end
750
-
751
- 環境(RACK\_ENV環境変数)が`:production`に設定されている時だけ実行する方法:
752
-
753
- configure :production do
754
- ...
755
- end
756
-
757
- 環境が`:production`か`:test`の場合に設定する方法:
758
-
759
- configure :production, :test do
760
- ...
761
- end
762
-
763
- ## エラーハンドリング
764
-
765
- エラーハンドラーはルートコンテキストとbeforeフィルタ内で実行します。
766
- `haml`、`erb`、`halt`などを使うこともできます。
767
-
768
- ### Not Found
769
-
770
- `Sinatra::NotFound`が起きた時か レスポンスのステータスコードが
771
- 404の時に`not_found`ハンドラーが発動します。
772
-
773
- not_found do
774
- 'ファイルが存在しません'
775
- end
776
-
777
- ### エラー
778
-
779
- `error`
780
- ハンドラーはルートブロックかbeforeフィルタ内で例外が発生した時はいつでも発動します。
781
- 例外オブジェクトはRack変数`sinatra.error`から取得できます。
782
-
783
- error do
784
- 'エラーが発生しました。 - ' + env['sinatra.error'].name
785
- end
786
-
787
- エラーをカスタマイズする場合は、
788
-
789
- error MyCustomError do
790
- 'エラーメッセージ...' + env['sinatra.error'].message
791
- end
792
-
793
- と書いておいて,下記のように呼び出します。
794
-
795
- get '/' do
796
- raise MyCustomError, '何かがまずかったようです'
797
- end
798
-
799
- そうするとこうなります:
800
-
801
- エラーメッセージ... 何かがまずかったようです
802
-
803
- あるいは、ステータスコードに対応するエラーハンドラを設定することもできます:
804
-
805
- error 403 do
806
- 'Access forbidden'
807
- end
808
-
809
- get '/secret' do
810
- 403
811
- end
812
-
813
- 範囲指定もできます:
814
-
815
- error 400..510 do
816
- 'Boom'
817
- end
818
-
819
- 開発環境として実行している場合、Sinatraは特別な`not_found`と`error`ハンドラーを
820
- インストールしています。
821
-
822
- ## MIMEタイプ
823
-
824
- `send_file`か静的ファイルを使う時、Sinatraが理解でいないMIMEタイプがある場合があります。
825
- その時は `mime_type` を使ってファイル拡張子毎に登録して下さい。
826
-
827
- mime_type :foo, 'text/foo'
828
-
829
- これはcontent\_typeヘルパで利用することができます:
830
-
831
- content_type :foo
832
-
833
- ## Rackミドルウェア
834
-
835
- [SinatraはRack](http://rack.rubyforge.org/)フレームワーク用の
836
- 最小限の標準インターフェース
837
- 上で動作しています。Rack中でもアプリケーションデベロッパー
838
- 向けに一番興味深い機能はミドルウェア(サーバとアプリケーション間に介在し、モニタリング、HTTPリクエストとレスポンス
839
- の手動操作ができるなど、一般的な機能のいろいろなことを提供するもの)をサポートすることです。
840
-
841
- Sinatraではトップレベルの`use`
842
- メソッドを使ってRackにパイプラインを構築します。
843
-
844
- require 'sinatra'
845
- require 'my_custom_middleware'
846
-
847
- use Rack::Lint
848
- use MyCustomMiddleware
849
-
850
- get '/hello' do
851
- 'Hello World'
852
- end
853
-
854
- `use`
855
- [Rack::Builder](http://rack.rubyforge.org/doc/classes/Rack/Builder.html)
856
- DSLで定義されていることと全て一致します。 例えば `use`
857
- メソッドはブロック構文のように複数の引数を受け取ることができます。
858
-
859
- use Rack::Auth::Basic do |username, password|
860
- username == 'admin' && password == 'secret'
861
- end
862
-
863
- Rackはログ、デバッギング、URLルーティング、認証、セッションなどいろいろな機能を備えた標準的ミドルウェアです。
864
- Sinatraはその多くのコンポーネントを自動で使うよう基本設定されているため、`use`で明示的に指定する必要はありません。
865
-
866
- ## テスト
867
-
868
- SinatraでのテストはRack-basedのテストライブラリかフレームワークを使って書くことができます。
869
- [Rack::Test](http://gitrdoc.com/brynary/rack-test)
870
- をおすすめします。やり方:
871
-
872
- require 'my_sinatra_app'
873
- require 'rack/test'
874
-
875
- class MyAppTest < Test::Unit::TestCase
876
- include Rack::Test::Methods
877
-
878
- def app
879
- Sinatra::Application
880
- end
881
-
882
- def test_my_default
883
- get '/'
884
- assert_equal 'Hello World!', last_response.body
885
- end
886
-
887
- def test_with_params
888
- get '/meet', :name => 'Frank'
889
- assert_equal 'Hello Frank!', last_response.body
890
- end
891
-
892
- def test_with_rack_env
893
- get '/', {}, 'HTTP_USER_AGENT' => 'Songbird'
894
- assert_equal "あなたはSongbirdを使ってますね!", last_response.body
895
- end
896
- end
897
-
898
- 注意: ビルトインのSinatra::TestモジュールとSinatra::TestHarnessクラスは
899
- 0.9.2リリース以降、廃止予定になっています。
900
-
901
- ## Sinatra::Base - ミドルウェア、ライブラリ、 モジュラーアプリ
902
-
903
- トップレベル(グローバル領域)上でいろいろ定義していくのは軽量アプリならうまくいきますが、
904
- RackミドルウェアやRails metal、サーバのコンポーネントを含んだシンプルな
905
- ライブラリやSinatraの拡張プログラムを考慮するような場合はそうとは限りません。
906
- トップレベルのDSLがネームスペースを汚染したり、設定を変えてしまうこと(例:./publicや./view)がありえます。
907
- そこでSinatra::Baseの出番です。
908
-
909
- require 'sinatra/base'
910
-
911
- class MyApp < Sinatra::Base
912
- set :sessions, true
913
- set :foo, 'bar'
914
-
915
- get '/' do
916
- 'Hello world!'
917
- end
918
- end
919
-
920
- このMyAppは独立したRackコンポーネントで、RackミドルウェアやRackアプリケーション
921
- Rails metalとして使用することができます。`config.ru`ファイル内で `use`
922
- か、または `run`
923
- でこのクラスを指定するか、ライブラリとしてサーバコンポーネントをコントロールします。
924
-
925
- MyApp.run! :host => 'localhost', :port => 9090
926
-
927
- Sinatra::Baseのサブクラスで使えるメソッドはトップレベルのDSLを経由して確実に使うことができます。
928
- ほとんどのトップレベルで記述されたアプリは、以下の2点を修正することでSinatra::Baseコンポーネントに変えることができます。
929
-
930
- - `sinatra`の代わりに`sinatra/base`を読み込む
931
-
932
- (そうしない場合、SinatraのDSLメソッドの全てがメインネームスペースにインポートされます)
933
-
934
- - ルート、エラーハンドラー、フィルター、オプションをSinatra::Baseのサブクラスに書く
935
-
936
- `Sinatra::Base`
937
- はまっさらです。ビルトインサーバを含む、ほとんどのオプションがデフォルト
938
- で無効になっています。オプション詳細については[Options and
939
- Configuration](http://sinatra.github.com/configuration.html)
940
- をご覧下さい。
941
-
942
- 補足:
943
- SinatraのトップレベルDSLはシンプルな委譲(delgation)システムで実装されています。
944
- `Sinatra::Application`クラス(Sinatra::Baseの特別なサブクラス)は、トップレベルに送られる
945
- :get、 :put、 :post、:delete、 :before、:error、:not\_found、
946
- :configure、:set messagesのこれら 全てを受け取ります。
947
- 詳細を閲覧されたい方はこちら(英語): [Sinatra::Delegator
948
- mixin](http://github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb#L1064)
949
- [included into the main
950
- namespace](http://github.com/sinatra/sinatra/blob/master/lib/sinatra/main.rb#L25).
951
-
952
- ### Sinatraをミドルウェアとして利用する
953
-
954
- Sinatraは他のRackミドルウェアを利用することができるだけでなく、
955
- 全てのSinatraアプリケーションは、それ自体ミドルウェアとして別のRackエンドポイントの前に追加することが可能です。
956
-
957
- このエンドポイントには、別のSinatraアプリケーションまたは他のRackベースのアプリケーション(Rails/Ramaze/Camping/…)が用いられるでしょう。
958
-
959
- require 'sinatra/base'
960
-
961
- class LoginScreen < Sinatra::Base
962
- enable :sessions
963
-
964
- get('/login') { haml :login }
965
-
966
- post('/login') do
967
- if params[:name] = 'admin' and params[:password] = 'admin'
968
- session['user_name'] = params[:name]
969
- else
970
- redirect '/login'
971
- end
972
- end
973
- end
974
-
975
- class MyApp < Sinatra::Base
976
- # middleware will run before filters
977
- use LoginScreen
978
-
979
- before do
980
- unless session['user_name']
981
- halt "Access denied, please <a href='/login'>login</a>."
982
- end
983
- end
984
-
985
- get('/') { "Hello #{session['user_name']}." }
986
- end
987
-
988
- ## スコープとバインディング
989
-
990
- 現在のスコープはどのメソッドや変数が利用可能かを決定します。
991
-
992
- ### アプリケーション/クラスのスコープ
993
-
994
- 全てのSinatraアプリケーションはSinatra::Baseのサブクラスに相当します。
995
- もしトップレベルDSLを利用しているならば(`require 'sinatra'`)このクラスはSinatra::Applicationであり、
996
- そうでなければ、あなたが明示的に作成したサブクラスです。
997
- クラスレベルでは\`get\`や\`before\`のようなメソッドを持っています。
998
- しかし\`request\`オブジェクトや\`session\`には、全てのリクエストのために1つのアプリケーションクラスが存在するためアクセスできません。
999
-
1000
- \`set\`によって作られたオプションはクラスレベルのメソッドです:
1001
-
1002
- class MyApp < Sinatra::Base
1003
- # Hey, I'm in the application scope!
1004
- set :foo, 42
1005
- foo # => 42
1006
-
1007
- get '/foo' do
1008
- # Hey, I'm no longer in the application scope!
1009
- end
1010
- end
1011
-
1012
- 次の場所ではアプリケーションスコープバインディングを持ちます:
1013
-
1014
- - アプリケーションのクラス本体
1015
-
1016
- - 拡張によって定義されたメソッド
1017
-
1018
- - \`helpers\`に渡されたブロック
1019
-
1020
- - \`set\`の値として使われるProcまたはブロック
1021
-
1022
- このスコープオブジェクト(クラス)は次のように利用できます:
1023
-
1024
- - configureブロックに渡されたオブジェクト経由(`configure { |c| ... }`)
1025
-
1026
- - リクエストスコープの中での\`settings\`
1027
-
1028
- ### リクエスト/インスタンスのスコープ
1029
-
1030
- やってくるリクエストごとに、あなたのアプリケーションクラスの新しいインスタンスが作成され、全てのハンドラブロックがそのスコープで実行されます。
1031
- このスコープの内側からは\`request\`や\`session\`オブジェクトにアクセスすることができ、\`erb\`や\`haml\`のような表示メソッドを呼び出すことができます。
1032
- リクエストスコープの内側からは、\`settings\`ヘルパによってアプリケーションスコープにアクセスすることができます。
1033
-
1034
- class MyApp < Sinatra::Base
1035
- # Hey, I'm in the application scope!
1036
- get '/define_route/:name' do
1037
- # Request scope for '/define_route/:name'
1038
- @value = 42
1039
-
1040
- settings.get("/#{params[:name]}") do
1041
- # Request scope for "/#{params[:name]}"
1042
- @value # => nil (not the same request)
1043
- end
1044
-
1045
- "Route defined!"
1046
- end
1047
- end
1048
-
1049
- 次の場所ではリクエストスコープバインディングを持ちます:
1050
-
1051
- - get/head/post/put/delete ブロック
1052
-
1053
- - before/after フィルタ
1054
-
1055
- - helper メソッド
1056
-
1057
- - テンプレート/ビュー
1058
-
1059
- ### デリゲートスコープ
1060
-
1061
- デリゲートスコープは、単にクラススコープにメソッドを転送します。
1062
- しかしながら、クラスのバインディングを持っていないため、クラススコープと全く同じふるまいをするわけではありません:
1063
- 委譲すると明示的に示されたメソッドのみが利用可能であり、またクラススコープと変数/状態を共有することはできません(注:
1064
- 異なった\`self\`を持っています)。
1065
- `Sinatra::Delegator.delegate :method_name`を呼び出すことによってデリゲートするメソッドを明示的に追加することができます。
1066
-
1067
- 次の場所ではデリゲートスコープを持ちます:
1068
-
1069
- - もし`require "sinatra"`しているならば、トップレベルバインディング
1070
-
1071
- - \`Sinatra::Delegator\` mixinでextendされたオブジェクト
1072
-
1073
- コードをご覧ください: ここでは [Sinatra::Delegator
1074
- mixin](http://github.com/sinatra/sinatra/blob/ceac46f0bc129a6e994a06100aa854f606fe5992/lib/sinatra/base.rb#L1128)
1075
- は[main
1076
- 名前空間にincludeされています](http://github.com/sinatra/sinatra/blob/ceac46f0bc129a6e994a06100aa854f606fe5992/lib/sinatra/main.rb#L28).
1077
-
1078
- ## コマンドライン
1079
-
1080
- Sinatraアプリケーションは直接実行できます。
1081
-
1082
- ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-o HOST] [-s HANDLER]
1083
-
1084
- オプション:
1085
-
1086
- -h # ヘルプ
1087
- -p # ポート指定(デフォルトは4567)
1088
- -o # ホスト指定(デフォルトは0.0.0.0)
1089
- -e # 環境を指定 (デフォルトはdevelopment)
1090
- -s # rackserver/handlerを指定 (デフォルトはthin)
1091
- -x # mutex lockを付ける (デフォルトはoff)
1092
-
1093
- ## 最新開発版について
1094
-
1095
- Sinatraの開発版を使いたい場合は、ローカルに開発版を落として、
1096
- `LOAD_PATH`の`sinatra/lib`ディレクトリを指定して実行して下さい。
1097
-
1098
- cd myapp
1099
- git clone git://github.com/sinatra/sinatra.git
1100
- ruby -Isinatra/lib myapp.rb
1101
-
1102
- `sinatra/lib`ディレクトリをアプリケーションの`LOAD_PATH`に追加する方法もあります。
1103
-
1104
- $LOAD_PATH.unshift File.dirname(__FILE__) + '/sinatra/lib'
1105
- require 'rubygems'
1106
- require 'sinatra'
1107
-
1108
- get '/about' do
1109
- "今使ってるバージョンは" + Sinatra::VERSION
1110
- end
1111
-
1112
- Sinatraのソースを更新する方法:
1113
-
1114
- cd myproject/sinatra
1115
- git pull
1116
-
1117
- ## その他
1118
-
1119
- 日本語サイト
1120
-
1121
- - [Greenbear Laboratory
1122
- Rack日本語マニュアル](http://mono.kmc.gr.jp/~yhara/w/?RackReferenceJa)
1123
- - Rackの日本語マニュアル
1124
-
1125
- 英語サイト
1126
-
1127
- - [プロジェクトサイト](http://sinatra.github.com/) - ドキュメント、
1128
- ニュース、他のリソースへのリンクがあります。
1129
-
1130
- - [プロジェクトに参加(貢献)する](http://sinatra.github.com/contributing.html)
1131
- - バグレポート パッチの送信、サポートなど
1132
-
1133
- - [Issue tracker](http://github.com/sinatra/sinatra/issues) -
1134
- チケット管理とリリース計画
1135
-
1136
- - [Twitter](http://twitter.com/sinatra)
1137
-
1138
- - [メーリングリスト](http://groups.google.com/group/sinatrarb)
1139
-
1140
- - [IRC: \#sinatra](irc://chat.freenode.net/#sinatra) on
1141
- [freenode.net](http://freenode.net)