sinatra 2.1.0 → 4.1.1

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/README.ja.md DELETED
@@ -1,2814 +0,0 @@
1
- # Sinatra
2
-
3
- *注)
4
- 本文書は英語から翻訳したものであり、その内容が最新でない場合もあります。最新の情報はオリジナルの英語版を参照してください。*
5
-
6
- Sinatraは最小の労力でRubyによるWebアプリケーションを手早く作るための[DSL](https://ja.wikipedia.org/wiki/メインページドメイン固有言語)です。
7
-
8
- ```ruby
9
- # myapp.rb
10
- require 'sinatra'
11
-
12
- get '/' do
13
- 'Hello world!'
14
- end
15
- ```
16
-
17
- gemをインストールし、
18
-
19
- ```shell
20
- gem install sinatra
21
- ```
22
-
23
- 次のように実行します。
24
-
25
- ```shell
26
- ruby myapp.rb
27
- ```
28
-
29
- [http://localhost:4567](http://localhost:4567) を開きます。
30
-
31
- ThinがあればSinatraはこれを利用するので、`gem install thin`することをお薦めします。
32
-
33
- ## 目次
34
-
35
- * [Sinatra](#sinatra)
36
- * [目次](#目次)
37
- * [ルーティング(Routes)](#ルーティングroutes)
38
- * [条件(Conditions)](#条件conditions)
39
- * [戻り値(Return Values)](#戻り値return-values)
40
- * [カスタムルーティングマッチャー(Custom Route Matchers)](#カスタムルーティングマッチャーcustom-route-matchers)
41
- * [静的ファイル(Static Files)](#静的ファイルstatic-files)
42
- * [ビュー / テンプレート(Views / Templates)](#ビュー--テンプレートviews--templates)
43
- * [リテラルテンプレート(Literal Templates)](#リテラルテンプレートliteral-templates)
44
- * [利用可能なテンプレート言語](#利用可能なテンプレート言語)
45
- * [Haml テンプレート](#haml-テンプレート)
46
- * [Erb テンプレート](#erb-テンプレート)
47
- * [Builder テンプレート](#builder-テンプレート)
48
- * [Nokogiri テンプレート](#nokogiri-テンプレート)
49
- * [Sass テンプレート](#sass-テンプレート)
50
- * [SCSS テンプレート](#scss-テンプレート)
51
- * [Less テンプレート](#less-テンプレート)
52
- * [Liquid テンプレート](#liquid-テンプレート)
53
- * [Markdown テンプレート](#markdown-テンプレート)
54
- * [Textile テンプレート](#textile-テンプレート)
55
- * [RDoc テンプレート](#rdoc-テンプレート)
56
- * [AsciiDoc テンプレート](#asciidoc-テンプレート)
57
- * [Radius テンプレート](#radius-テンプレート)
58
- * [Markaby テンプレート](#markaby-テンプレート)
59
- * [RABL テンプレート](#rabl-テンプレート)
60
- * [Slim テンプレート](#slim-テンプレート)
61
- * [Creole テンプレート](#creole-テンプレート)
62
- * [MediaWiki テンプレート](#mediawiki-テンプレート)
63
- * [CoffeeScript テンプレート](#coffeescript-テンプレート)
64
- * [Stylus テンプレート](#stylus-テンプレート)
65
- * [Yajl テンプレート](#yajl-テンプレート)
66
- * [WLang テンプレート](#wlang-テンプレート)
67
- * [テンプレート内での変数へのアクセス](#テンプレート内での変数へのアクセス)
68
- * [`yield`を伴うテンプレートとネストしたレイアウト](#yieldを伴うテンプレートとネストしたレイアウト)
69
- * [インラインテンプレート(Inline Templates)](#インラインテンプレートinline-templates)
70
- * [名前付きテンプレート(Named Templates)](#名前付きテンプレートnamed-templates)
71
- * [ファイル拡張子の関連付け](#ファイル拡張子の関連付け)
72
- * [オリジナルテンプレートエンジンの追加](#オリジナルテンプレートエンジンの追加)
73
- * [カスタムロジックを使用したテンプレートの探索](#カスタムロジックを使用したテンプレートの探索)
74
- * [フィルタ(Filters)](#フィルタfilters)
75
- * [ヘルパー(Helpers)](#ヘルパーhelpers)
76
- * [セッションの使用](#セッションの使用)
77
- * [セッションミドルウェアの選択](#セッションミドルウェアの選択)
78
- * [停止(Halting)](#停止halting)
79
- * [パッシング(Passing)](#パッシングpassing)
80
- * [別ルーティングの誘発](#別ルーティングの誘発)
81
- * [ボディ、ステータスコードおよびヘッダの設定](#ボディステータスコードおよびヘッダの設定)
82
- * [ストリーミングレスポンス(Streaming Responses)](#ストリーミングレスポンスstreaming-responses)
83
- * [ロギング(Logging)](#ロギングlogging)
84
- * [MIMEタイプ(Mime Types)](#mimeタイプmime-types)
85
- * [URLの生成](#urlの生成)
86
- * [ブラウザリダイレクト(Browser Redirect)](#ブラウザリダイレクトbrowser-redirect)
87
- * [キャッシュ制御(Cache Control)](#キャッシュ制御cache-control)
88
- * [ファイルの送信](#ファイルの送信)
89
- * [リクエストオブジェクトへのアクセス](#リクエストオブジェクトへのアクセス)
90
- * [アタッチメント(Attachments)](#アタッチメントattachments)
91
- * [日付と時刻の取り扱い](#日付と時刻の取り扱い)
92
- * [テンプレートファイルの探索](#テンプレートファイルの探索)
93
- * [コンフィギュレーション(Configuration)](#コンフィギュレーションconfiguration)
94
- * [攻撃防御に対する設定](#攻撃防御に対する設定)
95
- * [利用可能な設定](#利用可能な設定)
96
- * [環境設定(Environments)](#環境設定environments)
97
- * [エラーハンドリング(Error Handling)](#エラーハンドリングerror-handling)
98
- * [Not Found](#not-found)
99
- * [エラー(Error)](#エラーerror)
100
- * [Rackミドルウェア(Rack Middleware)](#rackミドルウェアrack-middleware)
101
- * [テスト(Testing)](#テストtesting)
102
- * [Sinatra::Base - ミドルウェア、ライブラリおよびモジュラーアプリ](#sinatrabase---ミドルウェアライブラリおよびモジュラーアプリ)
103
- * [モジュラースタイル vs クラッシックスタイル](#モジュラースタイル-vs-クラッシックスタイル)
104
- * [モジュラーアプリケーションの提供](#モジュラーアプリケーションの提供)
105
- * [config.ruを用いたクラッシックスタイルアプリケーションの使用](#configruを用いたクラッシックスタイルアプリケーションの使用)
106
- * [config.ruはいつ使うのか?](#configruはいつ使うのか)
107
- * [Sinatraのミドルウェアとしての利用](#sinatraのミドルウェアとしての利用)
108
- * [動的なアプリケーションの生成](#動的なアプリケーションの生成)
109
- * [スコープとバインディング(Scopes and Binding)](#スコープとバインディングscopes-and-binding)
110
- * [アプリケーション/クラスのスコープ](#アプリケーションクラスのスコープ)
111
- * [リクエスト/インスタンスのスコープ](#リクエストインスタンスのスコープ)
112
- * [デリゲートスコープ](#デリゲートスコープ)
113
- * [コマンドライン](#コマンドライン)
114
- * [マルチスレッド](#マルチスレッド)
115
- * [必要環境](#必要環境)
116
- * [最新開発版](#最新開発版)
117
- * [Bundlerを使う場合](#bundlerを使う場合)
118
- * [直接組み込む場合](#直接組み込む場合)
119
- * [グローバル環境にインストールする場合](#グローバル環境にインストールする場合)
120
- * [バージョニング(Versioning)](#バージョニングversioning)
121
- * [参考文献](#参考文献)
122
-
123
- ## ルーティング(Routes)
124
-
125
- Sinatraでは、ルーティングはHTTPメソッドとURLマッチングパターンがペアになっています。
126
- ルーティングはブロックに結び付けられています。
127
-
128
- ```ruby
129
- get '/' do
130
- .. 何か見せる ..
131
- end
132
-
133
- post '/' do
134
- .. 何か生成する ..
135
- end
136
-
137
- put '/' do
138
- .. 何か更新する ..
139
- end
140
-
141
- patch '/' do
142
- .. 何か修正する ..
143
- end
144
-
145
- delete '/' do
146
- .. 何か削除する ..
147
- end
148
-
149
- options '/' do
150
- .. 何か満たす ..
151
- end
152
-
153
- link '/' do
154
- .. 何かリンクを張る ..
155
- end
156
-
157
- unlink '/' do
158
- .. 何かアンリンクする ..
159
- end
160
- ```
161
-
162
- ルーティングは定義された順番にマッチします。
163
- リクエストに最初にマッチしたルーティングが呼び出されます。
164
-
165
- トレイリングスラッシュを付けたルートは、そうでないルートと異なったものになります。
166
-
167
- ```ruby
168
- get '/foo' do
169
- # Does not match "GET /foo/"
170
- end
171
- ```
172
-
173
- ルーティングのパターンは名前付きパラメータを含むことができ、
174
- `params`ハッシュで取得できます。
175
-
176
- ```ruby
177
- get '/hello/:name' do
178
- # "GET /hello/foo" と "GET /hello/bar" にマッチ
179
- # params['name'] は 'foo' か 'bar'
180
- "Hello #{params['name']}!"
181
- end
182
- ```
183
-
184
- また、ブロックパラメータで名前付きパラメータにアクセスすることもできます。
185
-
186
- ```ruby
187
- get '/hello/:name' do |n|
188
- # "GET /hello/foo" と "GET /hello/bar" にマッチ
189
- # params['name'] は 'foo' か 'bar'
190
- # n が params['name'] を保持
191
- "Hello #{n}!"
192
- end
193
- ```
194
-
195
- ルーティングパターンはアスタリスク(すなわちワイルドカード)を含むこともでき、
196
- `params['splat']` で取得できます。
197
-
198
- ```ruby
199
- get '/say/*/to/*' do
200
- # /say/hello/to/world にマッチ
201
- params['splat'] # => ["hello", "world"]
202
- end
203
-
204
- get '/download/*.*' do
205
- # /download/path/to/file.xml にマッチ
206
- params['splat'] # => ["path/to/file", "xml"]
207
- end
208
- ```
209
-
210
- ここで、ブロックパラメータを使うこともできます。
211
-
212
- ```ruby
213
- get '/download/*.*' do |path, ext|
214
- [path, ext] # => ["path/to/file", "xml"]
215
- end
216
- ```
217
-
218
- ルーティングを正規表現にマッチさせることもできます。
219
-
220
- ```ruby
221
- get /\/hello\/([\w]+)/ do
222
- "Hello, #{params['captures'].first}!"
223
- end
224
- ```
225
-
226
- ここでも、ブロックパラメータが使えます。
227
-
228
- ```ruby
229
- get %r{/hello/([\w]+)} do |c|
230
- "Hello, #{c}!"
231
- end
232
- ```
233
-
234
- ルーティングパターンは、オプショナルパラメータを取ることもできます。
235
-
236
- ```ruby
237
- get '/posts/:format?' do
238
- # "GET /posts/" と "GET /posts/json", "GET /posts/xml" の拡張子などにマッチ
239
- end
240
- ```
241
-
242
- ところで、ディレクトリトラバーサル攻撃防御設定を無効にしないと(下記参照)、
243
- ルーティングにマッチする前にリクエストパスが修正される可能性があります。
244
-
245
- ## 条件(Conditions)
246
-
247
- ルーティングにはユーザエージェントのようなさまざまな条件を含めることができます。
248
-
249
- ```ruby
250
- get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
251
- "Songbirdのバージョン #{params['agent'][0]}を使ってます。"
252
- end
253
-
254
- get '/foo' do
255
- # Songbird以外のブラウザにマッチ
256
- end
257
- ```
258
-
259
- ほかに`host_name`と`provides`条件が利用可能です。
260
-
261
- ```ruby
262
- get '/', :host_name => /^admin\./ do
263
- "Adminエリアです。アクセスを拒否します!"
264
- end
265
-
266
- get '/', :provides => 'html' do
267
- haml :index
268
- end
269
-
270
- get '/', :provides => ['rss', 'atom', 'xml'] do
271
- builder :feed
272
- end
273
- ```
274
-
275
- 独自の条件を定義することも簡単にできます。
276
-
277
- ```ruby
278
- set(:probability) { |value| condition { rand <= value } }
279
-
280
- get '/win_a_car', :probability => 0.1 do
281
- "あなたの勝ちです!"
282
- end
283
-
284
- get '/win_a_car' do
285
- "残念、あなたの負けです。"
286
- end
287
- ```
288
-
289
- 複数の値を取る条件には、アスタリスクを使います。
290
-
291
- ```ruby
292
- set(:auth) do |*roles| # <- ここでアスタリスクを使う
293
- condition do
294
- unless logged_in? && roles.any? {|role| current_user.in_role? role }
295
- redirect "/login/", 303
296
- end
297
- end
298
- end
299
-
300
- get "/my/account/", :auth => [:user, :admin] do
301
- "アカウントの詳細"
302
- end
303
-
304
- get "/only/admin/", :auth => :admin do
305
- "ここは管理者だけ!"
306
- end
307
- ```
308
-
309
- ## 戻り値(Return Values)
310
-
311
- ルーティングブロックの戻り値は、HTTPクライアントまたはRackスタックでの次のミドルウェアに渡されるレスポンスボディを決定します。
312
-
313
- これは大抵の場合、上の例のように文字列ですが、それ以外の値も使用することができます。
314
-
315
- Rackレスポンス、Rackボディオブジェクト、HTTPステータスコードのいずれかとして妥当なオブジェクトであればどのようなオブジェクトでも返すことができます。
316
-
317
- * 3つの要素を含む配列:
318
- `[ステータス(Integer), ヘッダ(Hash), レスポンスボディ(#eachに応答する)]`
319
- * 2つの要素を含む配列:
320
- `[ステータス(Integer), レスポンスボディ(#eachに応答する)]`
321
- * `#each`に応答するオブジェクト。通常はそのまま何も返さないが、
322
- 与えられたブロックに文字列を渡す。
323
- * ステータスコードを表現する整数(Integer)
324
-
325
- これにより、例えばストリーミングを簡単に実装することができます。
326
-
327
- ```ruby
328
- class Stream
329
- def each
330
- 100.times { |i| yield "#{i}\n" }
331
- end
332
- end
333
-
334
- get('/') { Stream.new }
335
- ```
336
-
337
- 後述する`stream`ヘルパーメソッドを使って、定型パターンを減らしつつストリーミングロジックをルーティングに埋め込むこともできます。
338
-
339
- ## カスタムルーティングマッチャー(Custom Route Matchers)
340
-
341
- 先述のようにSinatraはルーティングマッチャーとして、文字列パターンと正規表現を使うことをビルトインでサポートしています。しかしこれに留まらず、独自のマッチャーを簡単に定義することもできるのです。
342
-
343
- ```ruby
344
- class AllButPattern
345
- Match = Struct.new(:captures)
346
-
347
- def initialize(except)
348
- @except = except
349
- @captures = Match.new([])
350
- end
351
-
352
- def match(str)
353
- @captures unless @except === str
354
- end
355
- end
356
-
357
- def all_but(pattern)
358
- AllButPattern.new(pattern)
359
- end
360
-
361
- get all_but("/index") do
362
- # ...
363
- end
364
- ```
365
-
366
- ノート: この例はオーバースペックであり、以下のようにも書くことができます。
367
-
368
- ```ruby
369
- get // do
370
- pass if request.path_info == "/index"
371
- # ...
372
- end
373
- ```
374
-
375
- または、否定先読みを使って:
376
-
377
- ```ruby
378
- get %r{(?!/index)} do
379
- # ...
380
- end
381
- ```
382
-
383
- ## 静的ファイル(Static Files)
384
-
385
- 静的ファイルは`./public`ディレクトリから配信されます。
386
- `:public_folder`オプションを指定することで別の場所を指定することができます。
387
-
388
- ```ruby
389
- set :public_folder, __dir__ + '/static'
390
- ```
391
-
392
- ノート: この静的ファイル用のディレクトリ名はURL中に含まれません。
393
- 例えば、`./public/css/style.css`は`http://example.com/css/style.css`でアクセスできます。
394
-
395
- `Cache-Control`の設定をヘッダーへ追加するには`:static_cache_control`の設定(下記参照)を加えてください。
396
-
397
- ## ビュー / テンプレート(Views / Templates)
398
-
399
- 各テンプレート言語はそれ自身のレンダリングメソッドを通して展開されます。それらのメソッドは単に文字列を返します。
400
-
401
- ```ruby
402
- get '/' do
403
- erb :index
404
- end
405
- ```
406
-
407
- これは、`views/index.erb`をレンダリングします。
408
-
409
- テンプレート名を渡す代わりに、直接そのテンプレートの中身を渡すこともできます。
410
-
411
- ```ruby
412
- get '/' do
413
- code = "<%= Time.now %>"
414
- erb code
415
- end
416
- ```
417
-
418
- テンプレートのレイアウトは第2引数のハッシュ形式のオプションをもとに表示されます。
419
-
420
- ```ruby
421
- get '/' do
422
- erb :index, :layout => :post
423
- end
424
- ```
425
-
426
- これは、`views/post.erb`内に埋め込まれた`views/index.erb`をレンダリングします(デフォルトは`views/layout.erb`があればそれになります)。
427
-
428
- Sinatraが理解できないオプションは、テンプレートエンジンに渡されることになります。
429
-
430
- ```ruby
431
- get '/' do
432
- haml :index, :format => :html5
433
- end
434
- ```
435
-
436
- テンプレート言語ごとにオプションをセットすることもできます。
437
-
438
- ```ruby
439
- set :haml, :format => :html5
440
-
441
- get '/' do
442
- haml :index
443
- end
444
- ```
445
-
446
- レンダリングメソッドに渡されたオプションは`set`で設定されたオプションを上書きします。
447
-
448
- 利用可能なオプション:
449
-
450
- <dl>
451
- <dt>locals</dt>
452
- <dd>
453
- ドキュメントに渡されるローカルのリスト。パーシャルに便利。
454
- 例: <tt>erb "<%= foo %>", :locals => {:foo => "bar"}</tt>
455
- </dd>
456
-
457
- <dt>default_encoding</dt>
458
- <dd>
459
- 文字エンコーディングが確実でない場合に指定。デフォルトは、<tt>settings.default_encoding</tt>。
460
- </dd>
461
-
462
- <dt>views</dt>
463
- <dd>
464
- テンプレートを読み出すビューのディレクトリ。デフォルトは、<tt>settings.views</tt>。
465
- </dd>
466
-
467
- <dt>layout</dt>
468
- <dd>
469
- レイアウトを使うかの指定(<tt>true</tt> または <tt>false</tt>)。値がシンボルの場合は、使用するテンプレートが指定される。例: <tt>erb :index, :layout => !request.xhr?</tt>
470
- </dd>
471
-
472
- <dt>content_type</dt>
473
- <dd>
474
- テンプレートが生成するContent-Type。デフォルトはテンプレート言語ごとに異なる。
475
- </dd>
476
-
477
- <dt>scope</dt>
478
- <dd>
479
- テンプレートをレンダリングするときのスコープ。デフォルトは、アプリケーションのインスタンス。これを変更した場合、インスタンス変数およびヘルパーメソッドが利用できなくなる。
480
- </dd>
481
-
482
- <dt>layout_engine</dt>
483
- <dd>
484
- レイアウトをレンダリングするために使用するテンプレートエンジン。レイアウトをサポートしない言語で有用。デフォルトはテンプレートに使われるエンジン。例: <tt>set :rdoc, :layout_engine => :erb</tt>
485
- </dd>
486
-
487
- <dt>layout_options</dt>
488
- <dd>
489
- レイアウトをレンダリングするときだけに使う特別なオプション。例:
490
- <tt>set :rdoc, :layout_options => { :views => 'views/layouts' }</tt>
491
- </dd>
492
- </dl>
493
-
494
- テンプレートは`./views`ディレクトリ下に配置されています。
495
- 他のディレクトリを使用する場合の例:
496
-
497
- ```ruby
498
- set :views, settings.root + '/templates'
499
- ```
500
-
501
- テンプレートの参照は、テンプレートがサブディレクトリ内にある場合でも常にシンボルで指定することを覚えておいてください。
502
- (これは`:'subdir/template'`または`'subdir/template'.to_sym`のように指定することを意味します。)
503
- レンダリングメソッドにシンボルではなく文字列を渡してしまうと、そのまま文字列として出力してしまいます。
504
-
505
- ### リテラルテンプレート(Literal Templates)
506
-
507
- ```ruby
508
- get '/' do
509
- haml '%div.title Hello World'
510
- end
511
- ```
512
-
513
- これはテンプレート文字列をレンダリングしています。
514
- テンプレート文字列に関連するファイルパスや行数を`:path`や`:line`オプションで指定することで、バックトレースを明確にすることができます。
515
-
516
- ```ruby
517
- get '/' do
518
- haml '%div.title Hello World', :path => 'examples/file.haml', :line => 3
519
- end
520
- ```
521
-
522
- ### 利用可能なテンプレート言語
523
-
524
- いくつかの言語には複数の実装があります。使用する(そしてスレッドセーフにする)実装を指定するには、それを最初にrequireしてください。
525
-
526
- ```ruby
527
- require 'rdiscount' # または require 'bluecloth'
528
- get('/') { markdown :index }
529
- ```
530
-
531
- #### Haml テンプレート
532
-
533
- <table>
534
- <tr>
535
- <td>依存</td>
536
- <td><a href="http://haml.info/" title="haml">haml</a></td>
537
- </tr>
538
- <tr>
539
- <td>ファイル拡張子</td>
540
- <td><tt>.haml</tt></td>
541
- </tr>
542
- <tr>
543
- <td>例</td>
544
- <td><tt>haml :index, :format => :html5</tt></td>
545
- </tr>
546
- </table>
547
-
548
- #### Erb テンプレート
549
-
550
- <table>
551
- <tr>
552
- <td>依存</td>
553
- <td>
554
- <a href="https://github.com/jeremyevans/erubi" title="erubi">erubi</a>
555
- または <a href="http://www.kuwata-lab.com/erubis/" title="erubis">erubis</a>
556
- または erb (Rubyに同梱)
557
- </td>
558
- </tr>
559
- <tr>
560
- <td>ファイル拡張子</td>
561
- <td><tt>.erb</tt>, <tt>.rhtml</tt> または <tt>.erubi</tt> (Erubiだけ) または<tt>.erubis</tt> (Erubisだけ)</td>
562
- </tr>
563
- <tr>
564
- <td>例</td>
565
- <td><tt>erb :index</tt></td>
566
- </tr>
567
- </table>
568
-
569
- #### Builder テンプレート
570
-
571
- <table>
572
- <tr>
573
- <td>依存</td>
574
- <td>
575
- <a href="https://github.com/jimweirich/builder" title="builder">builder</a>
576
- </td>
577
- </tr>
578
- <tr>
579
- <td>ファイル拡張子</td>
580
- <td><tt>.builder</tt></td>
581
- </tr>
582
- <tr>
583
- <td>例</td>
584
- <td><tt>builder { |xml| xml.em "hi" }</tt></td>
585
- </tr>
586
- </table>
587
-
588
- インラインテンプレート用にブロックを取ることもできます(例を参照)。
589
-
590
- #### Nokogiri テンプレート
591
-
592
- <table>
593
- <tr>
594
- <td>依存</td>
595
- <td><a href="http://www.nokogiri.org/" title="nokogiri">nokogiri</a></td>
596
- </tr>
597
- <tr>
598
- <td>ファイル拡張子</td>
599
- <td><tt>.nokogiri</tt></td>
600
- </tr>
601
- <tr>
602
- <td>例</td>
603
- <td><tt>nokogiri { |xml| xml.em "hi" }</tt></td>
604
- </tr>
605
- </table>
606
-
607
- インラインテンプレート用にブロックを取ることもできます(例を参照)。
608
-
609
- #### Sass テンプレート
610
-
611
- <table>
612
- <tr>
613
- <td>依存</td>
614
- <td><a href="https://sass-lang.com/" title="sass">sass</a></td>
615
- </tr>
616
- <tr>
617
- <td>ファイル拡張子</td>
618
- <td><tt>.sass</tt></td>
619
- </tr>
620
- <tr>
621
- <td>例</td>
622
- <td><tt>sass :stylesheet, :style => :expanded</tt></td>
623
- </tr>
624
- </table>
625
-
626
- #### Scss テンプレート
627
-
628
- <table>
629
- <tr>
630
- <td>依存</td>
631
- <td><a href="https://sass-lang.com/" title="sass">sass</a></td>
632
- </tr>
633
- <tr>
634
- <td>ファイル拡張子</td>
635
- <td><tt>.scss</tt></td>
636
- </tr>
637
- <tr>
638
- <td>例</td>
639
- <td><tt>scss :stylesheet, :style => :expanded</tt></td>
640
- </tr>
641
- </table>
642
-
643
- #### Less テンプレート
644
-
645
- <table>
646
- <tr>
647
- <td>依存</td>
648
- <td><a href="http://lesscss.org/" title="less">less</a></td>
649
- </tr>
650
- <tr>
651
- <td>ファイル拡張子</td>
652
- <td><tt>.less</tt></td>
653
- </tr>
654
- <tr>
655
- <td>例</td>
656
- <td><tt>less :stylesheet</tt></td>
657
- </tr>
658
- </table>
659
-
660
- #### Liquid テンプレート
661
-
662
- <table>
663
- <tr>
664
- <td>依存</td>
665
- <td><a href="https://shopify.github.io/liquid/" title="liquid">liquid</a></td>
666
- </tr>
667
- <tr>
668
- <td>ファイル拡張子</td>
669
- <td><tt>.liquid</tt></td>
670
- </tr>
671
- <tr>
672
- <td>例</td>
673
- <td><tt>liquid :index, :locals => { :key => 'value' }</tt></td>
674
- </tr>
675
- </table>
676
-
677
- LiquidテンプレートからRubyのメソッド(`yield`を除く)を呼び出すことができないため、ほぼ全ての場合にlocalsを指定する必要があるでしょう。
678
-
679
- #### Markdown テンプレート
680
-
681
- <table>
682
- <tr>
683
- <td>依存</td>
684
- <td>
685
- 次の何れか:
686
- <a href="https://github.com/davidfstr/rdiscount" title="RDiscount">RDiscount</a>,
687
- <a href="https://github.com/vmg/redcarpet" title="RedCarpet">RedCarpet</a>,
688
- <a href="https://github.com/ged/bluecloth" title="bluecloth">BlueCloth</a>,
689
- <a href="https://kramdown.gettalong.org/" title="kramdown">kramdown</a>,
690
- <a href="https://github.com/bhollis/maruku" title="maruku">maruku</a>
691
- </td>
692
- </tr>
693
- <tr>
694
- <td>ファイル拡張子</td>
695
- <td><tt>.markdown</tt>, <tt>.mkd</tt> and <tt>.md</tt></td>
696
- </tr>
697
- <tr>
698
- <td>例</td>
699
- <td><tt>markdown :index, :layout_engine => :erb</tt></td>
700
- </tr>
701
- </table>
702
-
703
- Markdownからメソッドを呼び出すことも、localsに変数を渡すこともできません。
704
- それゆえ、他のレンダリングエンジンとの組み合わせで使うのが普通です。
705
-
706
- ```ruby
707
- erb :overview, :locals => { :text => markdown(:introduction) }
708
- ```
709
-
710
- ノート: 他のテンプレート内で`markdown`メソッドを呼び出せます。
711
-
712
- ```ruby
713
- %h1 Hello From Haml!
714
- %p= markdown(:greetings)
715
- ```
716
-
717
- MarkdownからはRubyを呼ぶことができないので、Markdownで書かれたレイアウトを使うことはできません。しかしながら、`:layout_engine`オプションを渡すことでテンプレートのものとは異なるレンダリングエンジンをレイアウトのために使うことができます。
718
-
719
- #### Textile テンプレート
720
-
721
- <table>
722
- <tr>
723
- <td>依存</td>
724
- <td><a href="http://redcloth.org/" title="RedCloth">RedCloth</a></td>
725
- </tr>
726
- <tr>
727
- <td>ファイル拡張子</td>
728
- <td><tt>.textile</tt></td>
729
- </tr>
730
- <tr>
731
- <td>例</td>
732
- <td><tt>textile :index, :layout_engine => :erb</tt></td>
733
- </tr>
734
- </table>
735
-
736
- Textileからメソッドを呼び出すことも、localsに変数を渡すこともできません。
737
- それゆえ、他のレンダリングエンジンとの組み合わせで使うのが普通です。
738
-
739
- ```ruby
740
- erb :overview, :locals => { :text => textile(:introduction) }
741
- ```
742
-
743
- ノート: 他のテンプレート内で`textile`メソッドを呼び出せます。
744
-
745
- ```ruby
746
- %h1 Hello From Haml!
747
- %p= textile(:greetings)
748
- ```
749
-
750
- TexttileからはRubyを呼ぶことができないので、Textileで書かれたレイアウトを使うことはできません。しかしながら、`:layout_engine`オプションを渡すことでテンプレートのものとは異なるレンダリングエンジンをレイアウトのために使うことができます。
751
-
752
- #### RDoc テンプレート
753
-
754
- <table>
755
- <tr>
756
- <td>依存</td>
757
- <td><a href="http://rdoc.sourceforge.net/" title="RDoc">RDoc</a></td>
758
- </tr>
759
- <tr>
760
- <td>ファイル拡張子</td>
761
- <td><tt>.rdoc</tt></td>
762
- </tr>
763
- <tr>
764
- <td>例</td>
765
- <td><tt>rdoc :README, :layout_engine => :erb</tt></td>
766
- </tr>
767
- </table>
768
-
769
- RDocからメソッドを呼び出すことも、localsに変数を渡すこともできません。
770
- それゆえ、他のレンダリングエンジンとの組み合わせで使うのが普通です。
771
-
772
- ```ruby
773
- erb :overview, :locals => { :text => rdoc(:introduction) }
774
- ```
775
-
776
- ノート: 他のテンプレート内で`rdoc`メソッドを呼び出せます。
777
-
778
- ```ruby
779
- %h1 Hello From Haml!
780
- %p= rdoc(:greetings)
781
- ```
782
-
783
- RDocからはRubyを呼ぶことができないので、RDocで書かれたレイアウトを使うことはできません。しかしながら、`:layout_engine`オプションを渡すことでテンプレートのものとは異なるレンダリングエンジンをレイアウトのために使うことができます。
784
-
785
- #### AsciiDoc テンプレート
786
-
787
- <table>
788
- <tr>
789
- <td>依存</td>
790
- <td><a href="https://asciidoctor.org/" title="Asciidoctor">Asciidoctor</a></td>
791
- </tr>
792
- <tr>
793
- <td>ファイル拡張子</td>
794
- <td><tt>.asciidoc</tt>, <tt>.adoc</tt> and <tt>.ad</tt></td>
795
- </tr>
796
- <tr>
797
- <td>例</td>
798
- <td><tt>asciidoc :README, :layout_engine => :erb</tt></td>
799
- </tr>
800
- </table>
801
-
802
- AsciiDocテンプレートからRubyのメソッドを直接呼び出すことができないため、ほぼ全ての場合にlocalsを指定する必要があるでしょう。
803
-
804
- #### Radius テンプレート
805
-
806
- <table>
807
- <tr>
808
- <td>依存</td>
809
- <td><a href="https://github.com/jlong/radius" title="Radius">Radius</a></td>
810
- </tr>
811
- <tr>
812
- <td>ファイル拡張子</td>
813
- <td><tt>.radius</tt></td>
814
- </tr>
815
- <tr>
816
- <td>例</td>
817
- <td><tt>radius :index, :locals => { :key => 'value' }</tt></td>
818
- </tr>
819
- </table>
820
-
821
- RadiusテンプレートからRubyのメソッドを直接呼び出すことができないため、ほぼ全ての場合にlocalsを指定する必要があるでしょう。
822
-
823
- #### Markaby テンプレート
824
-
825
- <table>
826
- <tr>
827
- <td>依存</td>
828
- <td><a href="https://markaby.github.io/" title="Markaby">Markaby</a></td>
829
- </tr>
830
- <tr>
831
- <td>ファイル拡張子</td>
832
- <td><tt>.mab</tt></td>
833
- </tr>
834
- <tr>
835
- <td>例</td>
836
- <td><tt>markaby { h1 "Welcome!" }</tt></td>
837
- </tr>
838
- </table>
839
-
840
- インラインテンプレート用にブロックを取ることもできます(例を参照)。
841
-
842
- #### RABL テンプレート
843
-
844
- <table>
845
- <tr>
846
- <td>依存</td>
847
- <td><a href="https://github.com/nesquena/rabl" title="Rabl">Rabl</a></td>
848
- </tr>
849
- <tr>
850
- <td>ファイル拡張子</td>
851
- <td><tt>.rabl</tt></td>
852
- </tr>
853
- <tr>
854
- <td>例</td>
855
- <td><tt>rabl :index</tt></td>
856
- </tr>
857
- </table>
858
-
859
- #### Slim テンプレート
860
-
861
- <table>
862
- <tr>
863
- <td>依存</td>
864
- <td><a href="http://slim-lang.com/" title="Slim Lang">Slim Lang</a></td>
865
- </tr>
866
- <tr>
867
- <td>ファイル拡張子</td>
868
- <td><tt>.slim</tt></td>
869
- </tr>
870
- <tr>
871
- <td>例</td>
872
- <td><tt>slim :index</tt></td>
873
- </tr>
874
- </table>
875
-
876
- #### Creole テンプレート
877
-
878
- <table>
879
- <tr>
880
- <td>依存</td>
881
- <td><a href="https://github.com/minad/creole" title="Creole">Creole</a></td>
882
- </tr>
883
- <tr>
884
- <td>ファイル拡張子</td>
885
- <td><tt>.creole</tt></td>
886
- </tr>
887
- <tr>
888
- <td>例</td>
889
- <td><tt>creole :wiki, :layout_engine => :erb</tt></td>
890
- </tr>
891
- </table>
892
-
893
- Creoleからメソッドを呼び出すことも、localsに変数を渡すこともできません。
894
- それゆえ、他のレンダリングエンジンとの組み合わせで使うのが普通です。
895
-
896
- ```ruby
897
- erb :overview, :locals => { :text => creole(:introduction) }
898
- ```
899
-
900
- ノート: 他のテンプレート内で`creole`メソッドを呼び出せます。
901
-
902
- ```ruby
903
- %h1 Hello From Haml!
904
- %p= creole(:greetings)
905
- ```
906
-
907
- CreoleからはRubyを呼ぶことができないので、Creoleで書かれたレイアウトを使うことはできません。しかしながら、`:layout_engine`オプションを渡すことでテンプレートのものとは異なるレンダリングエンジンをレイアウトのために使うことができます。
908
-
909
- #### MediaWiki テンプレート
910
-
911
- <table>
912
- <tr>
913
- <td>依存</td>
914
- <td><a href="https://github.com/nricciar/wikicloth" title="WikiCloth">WikiCloth</a></td>
915
- </tr>
916
- <tr>
917
- <td>ファイル拡張子</td>
918
- <td><tt>.mediawiki</tt> および <tt>.mw</tt></td>
919
- </tr>
920
- <tr>
921
- <td>例</td>
922
- <td><tt>mediawiki :wiki, :layout_engine => :erb</tt></td>
923
- </tr>
924
- </table>
925
-
926
- MediaWikiのテンプレートは直接メソッドから呼び出したり、ローカル変数を通すことはできません。それゆえに、通常は別のレンダリングエンジンと組み合わせて利用します。
927
-
928
- ```ruby
929
- erb :overview, :locals => { :text => mediawiki(:introduction) }
930
- ```
931
-
932
- ノート: 他のテンプレートから部分的に`mediawiki`メソッドを呼び出すことも可能です。
933
-
934
- #### CoffeeScript テンプレート
935
-
936
- <table>
937
- <tr>
938
- <td>依存</td>
939
- <td>
940
- <a href="https://github.com/josh/ruby-coffee-script" title="Ruby CoffeeScript">
941
- CoffeeScript
942
- </a> および
943
- <a href="https://github.com/sstephenson/execjs/blob/master/README.md#readme" title="ExecJS">
944
- JavaScriptの起動方法
945
- </a>
946
- </td>
947
- </tr>
948
- <tr>
949
- <td>ファイル拡張子</td>
950
- <td><tt>.coffee</tt></td>
951
- </tr>
952
- <tr>
953
- <td>例</td>
954
- <td><tt>coffee :index</tt></td>
955
- </tr>
956
- </table>
957
-
958
- #### Stylus テンプレート
959
-
960
- <table>
961
- <tr>
962
- <td>依存</td>
963
- <td>
964
- <a href="https://github.com/forgecrafted/ruby-stylus" title="Ruby Stylus">
965
- Stylus
966
- </a> および
967
- <a href="https://github.com/sstephenson/execjs/blob/master/README.md#readme" title="ExecJS">
968
- JavaScriptの起動方法
969
- </a>
970
- </td>
971
- </tr>
972
- <tr>
973
- <td>ファイル拡張子</td>
974
- <td><tt>.styl</tt></td>
975
- </tr>
976
- <tr>
977
- <td>例</td>
978
- <td><tt>stylus :index</tt></td>
979
- </tr>
980
- </table>
981
-
982
- Stylusテンプレートを使えるようにする前に、まず`stylus`と`stylus/tilt`を読み込む必要があります。
983
-
984
- ```ruby
985
- require 'sinatra'
986
- require 'stylus'
987
- require 'stylus/tilt'
988
-
989
- get '/' do
990
- stylus :example
991
- end
992
- ```
993
-
994
- #### Yajl テンプレート
995
-
996
- <table>
997
- <tr>
998
- <td>依存</td>
999
- <td><a href="https://github.com/brianmario/yajl-ruby" title="yajl-ruby">yajl-ruby</a></td>
1000
- </tr>
1001
- <tr>
1002
- <td>ファイル拡張子</td>
1003
- <td><tt>.yajl</tt></td>
1004
- </tr>
1005
- <tr>
1006
- <td>例</td>
1007
- <td>
1008
- <tt>
1009
- yajl :index,
1010
- :locals => { :key => 'qux' },
1011
- :callback => 'present',
1012
- :variable => 'resource'
1013
- </tt>
1014
- </td>
1015
- </tr>
1016
- </table>
1017
-
1018
- テンプレートのソースはRubyの文字列として評価され、その結果のJSON変数は`#to_json`を使って変換されます。
1019
-
1020
- ```ruby
1021
- json = { :foo => 'bar' }
1022
- json[:baz] = key
1023
- ```
1024
-
1025
- `:callback`および`:variable`オプションは、レンダリングされたオブジェクトを装飾するために使うことができます。
1026
-
1027
- ```ruby
1028
- var resource = {"foo":"bar","baz":"qux"}; present(resource);
1029
- ```
1030
-
1031
- #### WLang テンプレート
1032
-
1033
- <table>
1034
- <tr>
1035
- <td>依存</td>
1036
- <td><a href="https://github.com/blambeau/wlang/" title="wlang">wlang</a></td>
1037
- </tr>
1038
- <tr>
1039
- <td>ファイル拡張子</td>
1040
- <td><tt>.wlang</tt></td>
1041
- </tr>
1042
- <tr>
1043
- <td>例</td>
1044
- <td><tt>wlang :index, :locals => { :key => 'value' }</tt></td>
1045
- </tr>
1046
- </table>
1047
-
1048
- WLang内でのRubyメソッドの呼び出しは一般的ではないので、ほとんどの場合にlocalsを指定する必要があるでしょう。しかしながら、WLangで書かれたレイアウトは`yield`をサポートしています。
1049
-
1050
- ### テンプレート内での変数へのアクセス
1051
-
1052
- テンプレートはルーティングハンドラと同じコンテキストの中で評価されます。ルーティングハンドラでセットされたインスタンス変数はテンプレート内で直接使うことができます。
1053
-
1054
- ```ruby
1055
- get '/:id' do
1056
- @foo = Foo.find(params['id'])
1057
- haml '%h1= @foo.name'
1058
- end
1059
- ```
1060
-
1061
- また、ローカル変数のハッシュで明示的に指定することもできます。
1062
-
1063
- ```ruby
1064
- get '/:id' do
1065
- foo = Foo.find(params['id'])
1066
- haml '%h1= bar.name', :locals => { :bar => foo }
1067
- end
1068
- ```
1069
-
1070
- これは他のテンプレート内で部分テンプレートとして表示する典型的な手法です。
1071
-
1072
- ### `yield`を伴うテンプレートとネストしたレイアウト
1073
-
1074
- レイアウトは通常、`yield`を呼ぶ単なるテンプレートに過ぎません。
1075
- そのようなテンプレートは、既に説明した`:template`オプションを通して使われるか、または次のようなブロックを伴ってレンダリングされます。
1076
-
1077
- ```ruby
1078
- erb :post, :layout => false do
1079
- erb :index
1080
- end
1081
- ```
1082
-
1083
- このコードは、`erb :index, :layout => :post`とほぼ等価です。
1084
-
1085
- レンダリングメソッドにブロックを渡すスタイルは、ネストしたレイアウトを作るために最も役立ちます。
1086
-
1087
- ```ruby
1088
- erb :main_layout, :layout => false do
1089
- erb :admin_layout do
1090
- erb :user
1091
- end
1092
- end
1093
- ```
1094
-
1095
- これはまた次のより短いコードでも達成できます。
1096
-
1097
- ```ruby
1098
- erb :admin_layout, :layout => :main_layout do
1099
- erb :user
1100
- end
1101
- ```
1102
-
1103
- 現在、次のレンダリングメソッドがブロックを取れます: `erb`, `haml`,
1104
- `liquid`, `slim `, `wlang`。
1105
- また汎用の`render`メソッドもブロックを取れます。
1106
-
1107
- ### インラインテンプレート(Inline Templates)
1108
-
1109
- テンプレートはソースファイルの最後で定義することもできます。
1110
-
1111
- ```ruby
1112
- require 'sinatra'
1113
-
1114
- get '/' do
1115
- haml :index
1116
- end
1117
-
1118
- __END__
1119
-
1120
- @@ layout
1121
- %html
1122
- = yield
1123
-
1124
- @@ index
1125
- %div.title Hello world!!!!!
1126
- ```
1127
-
1128
- ノート: Sinatraをrequireするソースファイル内で定義されたインラインテンプレートは自動的に読み込まれます。他のソースファイル内にインラインテンプレートがある場合には`enable :inline_templates`を明示的に呼んでください。
1129
-
1130
- ### 名前付きテンプレート(Named Templates)
1131
-
1132
- テンプレートはトップレベルの`template`メソッドで定義することもできます。
1133
-
1134
- ```ruby
1135
- template :layout do
1136
- "%html\n =yield\n"
1137
- end
1138
-
1139
- template :index do
1140
- '%div.title Hello World!'
1141
- end
1142
-
1143
- get '/' do
1144
- haml :index
1145
- end
1146
- ```
1147
-
1148
- 「layout」という名前のテンプレートが存在する場合は、そのテンプレートファイルは他のテンプレートがレンダリングされる度に使用されます。`:layout => false`で個別に、または`set :haml, :layout => false`でデフォルトとして、レイアウトを無効にすることができます。
1149
-
1150
- ```ruby
1151
- get '/' do
1152
- haml :index, :layout => !request.xhr?
1153
- end
1154
- ```
1155
-
1156
- ### ファイル拡張子の関連付け
1157
-
1158
- 任意のテンプレートエンジンにファイル拡張子を関連付ける場合は、`Tilt.register`を使います。例えば、Textileテンプレートに`tt`というファイル拡張子を使いたい場合は、以下のようにします。
1159
-
1160
- ```ruby
1161
- Tilt.register :tt, Tilt[:textile]
1162
- ```
1163
-
1164
- ### オリジナルテンプレートエンジンの追加
1165
-
1166
- まず、Tiltでそのエンジンを登録し、次にレンダリングメソッドを作ります。
1167
-
1168
- ```ruby
1169
- Tilt.register :myat, MyAwesomeTemplateEngine
1170
-
1171
- helpers do
1172
- def myat(*args) render(:myat, *args) end
1173
- end
1174
-
1175
- get '/' do
1176
- myat :index
1177
- end
1178
- ```
1179
-
1180
- これは、`./views/index.myat`をレンダリングします。Tiltについての詳細は、https://github.com/rtomayko/tilt を参照してください。
1181
-
1182
- ### カスタムロジックを使用したテンプレートの探索
1183
-
1184
- オリジナルテンプレートの検索メカニズムを実装するためには、`#find_template`メソッドを実装します。
1185
-
1186
- ```ruby
1187
- configure do
1188
- set :views [ './views/a', './views/b' ]
1189
- end
1190
-
1191
- def find_template(views, name, engine, &block)
1192
- Array(views).each do |v|
1193
- super(v, name, engine, &block)
1194
- end
1195
- end
1196
- ```
1197
-
1198
- ## フィルタ(Filters)
1199
-
1200
- beforeフィルタは、リクエストのルーティングと同じコンテキストで各リクエストの前に評価され、それによってリクエストとレスポンスを変更可能にします。フィルタ内でセットされたインスタンス変数はルーティングとテンプレートからアクセスすることができます。
1201
-
1202
- ```ruby
1203
- before do
1204
- @note = 'Hi!'
1205
- request.path_info = '/foo/bar/baz'
1206
- end
1207
-
1208
- get '/foo/*' do
1209
- @note #=> 'Hi!'
1210
- params['splat'] #=> 'bar/baz'
1211
- end
1212
- ```
1213
-
1214
- afterフィルタは、リクエストのルーティングと同じコンテキストで各リクエストの後に評価され、それによってこれもリクエストとレスポンスを変更可能にします。beforeフィルタとルーティング内でセットされたインスタンス変数はafterフィルタからアクセスすることができます。
1215
-
1216
- ```ruby
1217
- after do
1218
- puts response.status
1219
- end
1220
- ```
1221
-
1222
- ノート: `body`メソッドを使わずにルーティングから文字列を返すだけの場合、その内容はafterフィルタでまだ利用できず、その後に生成されることになります。
1223
-
1224
- フィルタにはオプションとしてパターンを渡すことができ、この場合はリクエストのパスがパターンにマッチした場合にのみフィルタが評価されるようになります。
1225
-
1226
- ```ruby
1227
- before '/protected/*' do
1228
- authenticate!
1229
- end
1230
-
1231
- after '/create/:slug' do |slug|
1232
- session[:last_slug] = slug
1233
- end
1234
- ```
1235
-
1236
- ルーティング同様、フィルタもまた条件を取ることができます。
1237
-
1238
- ```ruby
1239
- before :agent => /Songbird/ do
1240
- # ...
1241
- end
1242
-
1243
- after '/blog/*', :host_name => 'example.com' do
1244
- # ...
1245
- end
1246
- ```
1247
-
1248
- ## ヘルパー(Helpers)
1249
-
1250
- トップレベルの`helpers`メソッドを使用してルーティングハンドラやテンプレートで使うヘルパーメソッドを定義できます。
1251
-
1252
- ```ruby
1253
- helpers do
1254
- def bar(name)
1255
- "#{name}bar"
1256
- end
1257
- end
1258
-
1259
- get '/:name' do
1260
- bar(params['name'])
1261
- end
1262
- ```
1263
-
1264
- あるいは、ヘルパーメソッドをモジュール内で個別に定義することもできます。
1265
-
1266
- ```ruby
1267
- module FooUtils
1268
- def foo(name) "#{name}foo" end
1269
- end
1270
-
1271
- module BarUtils
1272
- def bar(name) "#{name}bar" end
1273
- end
1274
-
1275
- helpers FooUtils, BarUtils
1276
- ```
1277
-
1278
- その効果は、アプリケーションクラスにモジュールをインクルードするのと同じです。
1279
-
1280
- ### セッションの使用
1281
-
1282
- セッションはリクエスト間での状態維持のために使用されます。セッションを有効化すると、ユーザセッションごとに一つのセッションハッシュが与えられます。
1283
-
1284
- ```ruby
1285
- enable :sessions
1286
-
1287
- get '/' do
1288
- "value = " << session[:value].inspect
1289
- end
1290
-
1291
- get '/:value' do
1292
- session[:value] = params['value']
1293
- end
1294
- ```
1295
-
1296
- ノート: `enable :sessions`は実際にはすべてのデータをクッキーに保持します。これは必ずしも期待通りのものにならないかもしれません(例えば、大量のデータを保持することでトラフィックが増大するなど)。Rackセッションミドルウェアの利用が可能であり、その場合は`enable :sessions`を呼ばずに、選択したミドルウェアを他のミドルウェアのときと同じようにして取り込んでください。
1297
-
1298
- ```ruby
1299
- use Rack::Session::Pool, :expire_after => 2592000
1300
-
1301
- get '/' do
1302
- "value = " << session[:value].inspect
1303
- end
1304
-
1305
- get '/:value' do
1306
- session[:value] = params['value']
1307
- end
1308
- ```
1309
-
1310
- セキュリティ向上のため、クッキー内のセッションデータはセッション秘密鍵(session secret)で署名されます。Sinatraによりランダムな秘密鍵が個別に生成されます。しかし、この秘密鍵はアプリケーションの立ち上げごとに変わってしまうので、すべてのアプリケーションのインスタンスで共有できる秘密鍵をセットしたくなるかもしれません。
1311
-
1312
- ```ruby
1313
- set :session_secret, 'super secret'
1314
- ```
1315
-
1316
- 更に、設定変更をしたい場合は、`sessions`の設定においてオプションハッシュを保持することもできます。
1317
-
1318
- ```ruby
1319
- set :sessions, :domain => 'foo.com'
1320
- ```
1321
-
1322
- foo.comのサブドメイン上のアプリ間でセッションを共有化したいときは、代わりにドメインの前に *.* を付けます。
1323
-
1324
- ```ruby
1325
- set :sessions, :domain => '.foo.com'
1326
- ```
1327
-
1328
- #### セッションミドルウェアの選択
1329
-
1330
- `enable :sessions`とすることで、クッキー内の全てのデータを実際に保存してしまうことに注意してください。
1331
- これは、あなたが望む挙動ではない(例えば、大量のデータを保存することでトラフィックが増大してしまう)かもしれません。
1332
- あなたは、次のいずれかの方法によって、任意のRackセッションミドルウェアを使用することができます。
1333
-
1334
- ```ruby
1335
- enable :sessions
1336
- set :session_store, Rack::Session::Pool
1337
- ```
1338
-
1339
- オプションのハッシュを設定するためには、次のようにします。
1340
-
1341
- ```ruby
1342
- set :sessions, :expire_after => 2592000
1343
- set :session_store, Rack::Session::Pool
1344
- ```
1345
-
1346
- 他の方法は`enable :sessions`を**しない**で、他のミドルウェアの選択と同様にあなた自身でミドルウェアを選択することです。
1347
-
1348
- この方法を選択する場合は、セッションベースの保護は**デフォルトで有効にならない**ということに注意することが重要です。
1349
-
1350
- これを満たすためのRackミドルウェアを追加することが必要になります。
1351
-
1352
- ```ruby
1353
- use Rack::Session::Pool, :expire_after => 2592000
1354
- use Rack::Protection::RemoteToken
1355
- use Rack::Protection::SessionHijacking
1356
- ```
1357
-
1358
- より詳しい情報は、「攻撃防御に対する設定」の項を参照してください。
1359
-
1360
- ### 停止(Halting)
1361
-
1362
- フィルタまたはルーティング内で直ちにリクエストを止める場合
1363
-
1364
- ```ruby
1365
- halt
1366
- ```
1367
-
1368
- この際、ステータスを指定することもできます。
1369
-
1370
- ```ruby
1371
- halt 410
1372
- ```
1373
-
1374
- body部を指定することも、
1375
-
1376
- ```ruby
1377
- halt 'ここにbodyを書く'
1378
- ```
1379
-
1380
- ステータスとbody部を指定することも、
1381
-
1382
- ```ruby
1383
- halt 401, '立ち去れ!'
1384
- ```
1385
-
1386
- ヘッダを付けることもできます。
1387
-
1388
- ```ruby
1389
- halt 402, {'Content-Type' => 'text/plain'}, 'リベンジ'
1390
- ```
1391
-
1392
- もちろん、テンプレートを`halt`に結びつけることも可能です。
1393
-
1394
- ```ruby
1395
- halt erb(:error)
1396
- ```
1397
-
1398
- ### パッシング(Passing)
1399
-
1400
- ルーティングは`pass`を使って次のルーティングに飛ばすことができます。
1401
-
1402
- ```ruby
1403
- get '/guess/:who' do
1404
- pass unless params['who'] == 'Frank'
1405
- "見つかっちゃった!"
1406
- end
1407
-
1408
- get '/guess/*' do
1409
- "はずれです!"
1410
- end
1411
- ```
1412
-
1413
- ルーティングブロックからすぐに抜け出し、次にマッチするルーティングを実行します。マッチするルーティングが見当たらない場合は404が返されます。
1414
-
1415
- ### 別ルーティングの誘発
1416
-
1417
- `pass`を使ってルーティングを飛ばすのではなく、他のルーティングを呼んだ結果を得たいという場合があります。
1418
- これは`call`を使用することで実現できます。
1419
-
1420
- ```ruby
1421
- get '/foo' do
1422
- status, headers, body = call env.merge("PATH_INFO" => '/bar')
1423
- [status, headers, body.map(&:upcase)]
1424
- end
1425
-
1426
- get '/bar' do
1427
- "bar"
1428
- end
1429
- ```
1430
-
1431
- ノート: 先の例において、テストを楽にしパフォーマンスを改善するには、`"bar"`を単にヘルパーに移し、`/foo`および`/bar`から使えるようにしたほうが良いです。
1432
-
1433
- リクエストが、その複製物でない同じアプリケーションのインスタンスに送られるようにしたいときは、`call`に代えて`call!`を使ってください。
1434
-
1435
- `call`についての詳細はRackの仕様を参照してください。
1436
-
1437
- ### ボディ、ステータスコードおよびヘッダの設定
1438
-
1439
- ステータスコードおよびレスポンスボディを、ルーティングブロックの戻り値にセットすることが可能であり、これは推奨されています。しかし、あるケースでは実行フローの任意のタイミングでボディをセットしたくなるかもしれません。`body`ヘルパーメソッドを使えばそれができます。そうすると、それ以降、ボディにアクセスするためにそのメソッドを使うことができるようになります。
1440
-
1441
- ```ruby
1442
- get '/foo' do
1443
- body "bar"
1444
- end
1445
-
1446
- after do
1447
- puts body
1448
- end
1449
- ```
1450
-
1451
- また、`body`にはブロックを渡すことができ、これはRackハンドラにより実行されることになります(これはストリーミングを実装するのに使われます。"戻り値"の項を参照してください。)
1452
-
1453
- ボディと同様に、ステータスコードおよびヘッダもセットできます。
1454
-
1455
- ```ruby
1456
- get '/foo' do
1457
- status 418
1458
- headers \
1459
- "Allow" => "BREW, POST, GET, PROPFIND, WHEN",
1460
- "Refresh" => "Refresh: 20; https://www.ietf.org/rfc/rfc2324.txt"
1461
- body "I'm a tea pot!"
1462
- end
1463
- ```
1464
-
1465
- 引数を伴わない`body`、`headers`、`status`などは、それらの現在の値にアクセスするために使えます。
1466
-
1467
- ### ストリーミングレスポンス(Streaming Responses)
1468
-
1469
- レスポンスボディの部分を未だ生成している段階で、データを送り出したいということがあります。極端な例では、クライアントがコネクションを閉じるまでデータを送り続けたいことがあります。`stream`ヘルパーを使えば、独自ラッパーを作る必要はありません。
1470
-
1471
- ```ruby
1472
- get '/' do
1473
- stream do |out|
1474
- out << "それは伝 -\n"
1475
- sleep 0.5
1476
- out << " (少し待つ) \n"
1477
- sleep 1
1478
- out << "- 説になる!\n"
1479
- end
1480
- end
1481
- ```
1482
-
1483
- これはストリーミングAPI、[Server Sent Events](https://w3c.github.io/eventsource/)の実装を可能にし、[WebSockets](https://en.wikipedia.org/wiki/WebSocket)の土台に使うことができます。また、一部のコンテンツが遅いリソースに依存しているときに、スループットを上げるために使うこともできます。
1484
-
1485
- ノート: ストリーミングの挙動、特に並行リクエスト(cuncurrent requests)の数は、アプリケーションを提供するのに使われるWebサーバに強く依存します。いくつかのサーバは、ストリーミングを全くサポートしません。サーバがストリーミングをサポートしない場合、ボディは`stream`に渡されたブロックの実行が終了した後、一度に全部送られることになります。ストリーミングは、Shotgunを使った場合は全く動作しません。
1486
-
1487
- オプション引数が`keep_open`にセットされている場合、ストリームオブジェクト上で`close`は呼ばれず、実行フローの任意の遅れたタイミングでユーザがこれを閉じることを可能にします。これはThinやRainbowsのようなイベント型サーバ上でしか機能しません。他のサーバでは依然ストリームは閉じられます。
1488
-
1489
- ```ruby
1490
- # ロングポーリング
1491
-
1492
- set :server, :thin
1493
- connections = []
1494
-
1495
- get '/subscribe' do
1496
- # サーバイベントにおけるクライアントの関心を登録
1497
- stream(:keep_open) do |out|
1498
- connections << out
1499
- # 死んでいるコネクションを排除
1500
- connections.reject!(&:closed?)
1501
- end
1502
- end
1503
-
1504
- post '/message' do
1505
- connections.each do |out|
1506
- # クライアントへ新規メッセージ到着の通知
1507
- out << params['message'] << "\n"
1508
-
1509
- # クライアントへの再接続の指示
1510
- out.close
1511
- end
1512
-
1513
- # 肯定応答
1514
- "message received"
1515
- end
1516
- ```
1517
-
1518
- クライアントはソケットに書き込もうとしている接続を閉じることも可能です。そのため、記述しようとする前に`out.closed?`をチェックすることを勧めます。
1519
-
1520
- ### ロギング(Logging)
1521
-
1522
- リクエストスコープにおいて、`logger`ヘルパーは`Logger`インスタンスを作り出します。
1523
-
1524
- ```ruby
1525
- get '/' do
1526
- logger.info "loading data"
1527
- # ...
1528
- end
1529
- ```
1530
-
1531
- このロガーは、自動でRackハンドラのロギング設定を参照します。ロギングが無効(disabled)にされている場合、このメソッドはダミーオブジェクトを返すので、ルーティングやフィルタにおいて特に心配することはありません。
1532
-
1533
- ノート: ロギングは、`Sinatra::Application`に対してのみデフォルトで有効にされているので、`Sinatra::Base`を継承している場合は、ユーザがこれを有効化する必要があります。
1534
-
1535
- ```ruby
1536
- class MyApp < Sinatra::Base
1537
- configure :production, :development do
1538
- enable :logging
1539
- end
1540
- end
1541
- ```
1542
-
1543
- ロギングミドルウェアが設定されてしまうのを避けるには、`logging`設定を`nil`にセットします。しかしこの場合、`logger`が`nil`を返すことを忘れないように。よくあるユースケースは、オリジナルのロガーをセットしたいときです。Sinatraは、とにかく`env['rack.logger']`で見つかるものを使います。
1544
-
1545
- ### MIMEタイプ(Mime Types)
1546
-
1547
- `send_file`か静的ファイルを使う時、SinatraがMIMEタイプを理解できない場合があります。その時は `mime_type` を使ってファイル拡張子毎に登録してください。
1548
-
1549
- ```ruby
1550
- configure do
1551
- mime_type :foo, 'text/foo'
1552
- end
1553
- ```
1554
-
1555
- これは`content_type`ヘルパーで利用することができます:
1556
-
1557
- ```ruby
1558
- get '/' do
1559
- content_type :foo
1560
- "foo foo foo"
1561
- end
1562
- ```
1563
-
1564
- ### URLの生成
1565
-
1566
- URLを生成するためには`url`ヘルパーメソッドが使えます。Hamlではこのようにします。
1567
-
1568
- ```ruby
1569
- %a{:href => url('/foo')} foo
1570
- ```
1571
-
1572
- これはリバースプロキシおよびRackルーティングを、それらがあれば考慮に入れます。
1573
-
1574
- このメソッドには`to`というエイリアスがあります(以下の例を参照)。
1575
-
1576
- ### ブラウザリダイレクト(Browser Redirect)
1577
-
1578
- `redirect` ヘルパーメソッドを使うことで、ブラウザをリダイレクトさせることができます。
1579
-
1580
- ```ruby
1581
- get '/foo' do
1582
- redirect to('/bar')
1583
- end
1584
- ```
1585
-
1586
- 他に追加されるパラメータは、`halt`に渡される引数と同様に取り扱われます。
1587
-
1588
- ```ruby
1589
- redirect to('/bar'), 303
1590
- redirect 'https://www.google.com/', 'wrong place, buddy'
1591
- ```
1592
-
1593
- また、`redirect back`を使えば、簡単にユーザが来たページへ戻るリダイレクトを作れます。
1594
-
1595
- ```ruby
1596
- get '/foo' do
1597
- "<a href='/bar'>do something</a>"
1598
- end
1599
-
1600
- get '/bar' do
1601
- do_something
1602
- redirect back
1603
- end
1604
- ```
1605
-
1606
- redirectに引数を渡すには、それをクエリーに追加するか、
1607
-
1608
- ```ruby
1609
- redirect to('/bar?sum=42')
1610
- ```
1611
-
1612
- または、セッションを使います。
1613
-
1614
- ```ruby
1615
- enable :sessions
1616
-
1617
- get '/foo' do
1618
- session[:secret] = 'foo'
1619
- redirect to('/bar')
1620
- end
1621
-
1622
- get '/bar' do
1623
- session[:secret]
1624
- end
1625
- ```
1626
-
1627
- ### キャッシュ制御(Cache Control)
1628
-
1629
- ヘッダを正しく設定することが、適切なHTTPキャッシングのための基礎となります。
1630
-
1631
- キャッシュ制御ヘッダ(Cache-Control header)は、次のように簡単に設定できます。
1632
-
1633
- ```ruby
1634
- get '/' do
1635
- cache_control :public
1636
- "キャッシュしました!"
1637
- end
1638
- ```
1639
-
1640
- ヒント: キャッシングをbeforeフィルタ内で設定します。
1641
-
1642
- ```ruby
1643
- before do
1644
- cache_control :public, :must_revalidate, :max_age => 60
1645
- end
1646
- ```
1647
-
1648
- `expires`ヘルパーを対応するヘッダに使っている場合は、キャッシュ制御は自動で設定されます。
1649
-
1650
- ```ruby
1651
- before do
1652
- expires 500, :public, :must_revalidate
1653
- end
1654
- ```
1655
-
1656
- キャッシュを適切に使うために、`etag`または`last_modified`を使うことを検討してください。これらのヘルパーを、重い仕事をさせる *前* に呼ぶことを推奨します。そうすれば、クライアントが既にキャッシュに最新版を持っている場合はレスポンスを直ちに破棄するようになります。
1657
-
1658
- ```ruby
1659
- get '/article/:id' do
1660
- @article = Article.find params['id']
1661
- last_modified @article.updated_at
1662
- etag @article.sha1
1663
- erb :article
1664
- end
1665
- ```
1666
-
1667
- また、[weak ETag](https://ja.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation)を使うこともできます。
1668
-
1669
- ```ruby
1670
- etag @article.sha1, :weak
1671
- ```
1672
-
1673
- これらのヘルパーは、キャッシングをしてくれませんが、必要な情報をキャッシュに与えてくれます。もし手早いリバースプロキシキャッシングの解決策をお探しなら、 [rack-cache](https://github.com/rtomayko/rack-cache)を試してください。
1674
-
1675
- ```ruby
1676
- require "rack/cache"
1677
- require "sinatra"
1678
-
1679
- use Rack::Cache
1680
-
1681
- get '/' do
1682
- cache_control :public, :max_age => 36000
1683
- sleep 5
1684
- "hello"
1685
- end
1686
- ```
1687
-
1688
- `:static_cache_control`設定(以下を参照)を、キャッシュ制御ヘッダ情報を静的ファイルに追加するために使ってください。
1689
-
1690
- RFC 2616によれば、アプリケーションは、If-MatchまたはIf-None-Matchヘッダが`*`に設定されている場合には、要求されたリソースが既に存在するか否かに応じて、異なる振る舞いをすべきとなっています。Sinatraは、getのような安全なリクエストおよびputのような冪等なリクエストは既に存在しているものとして仮定し、一方で、他のリソース(例えば、postリクエスト)は新たなリソースとして取り扱われるよう仮定します。この振る舞いは、`:new_resource`オプションを渡すことで変更できます。
1691
-
1692
- ```ruby
1693
- get '/create' do
1694
- etag '', :new_resource => true
1695
- Article.create
1696
- erb :new_article
1697
- end
1698
- ```
1699
-
1700
- ここでもWeak ETagを使いたい場合は、`:kind`オプションを渡してください。
1701
-
1702
- ```ruby
1703
- etag '', :new_resource => true, :kind => :weak
1704
- ```
1705
-
1706
- ### ファイルの送信
1707
-
1708
- ファイルを送信するには、`send_file`ヘルパーメソッドを使います。
1709
-
1710
- ```ruby
1711
- get '/' do
1712
- send_file 'foo.png'
1713
- end
1714
- ```
1715
-
1716
- これはオプションを取ることもできます。
1717
-
1718
- ```ruby
1719
- send_file 'foo.png', :type => :jpg
1720
- ```
1721
-
1722
- オプション一覧
1723
-
1724
- <dl>
1725
- <dt>filename</dt>
1726
- <dd>ファイル名。デフォルトは実際のファイル名。</dd>
1727
-
1728
- <dt>last_modified</dt>
1729
- <dd>Last-Modifiedヘッダの値。デフォルトはファイルのmtime。</dd>
1730
-
1731
- <dt>type</dt>
1732
- <dd>コンテンツの種類。設定がない場合、ファイル拡張子から類推される。</dd>
1733
-
1734
- <dt>disposition</dt>
1735
- <dd>
1736
- Content-Dispositionに使われる。許容値: <tt>nil</tt> (デフォルト)、
1737
- <tt>:attachment</tt> および <tt>:inline</tt>
1738
- </dd>
1739
-
1740
- <dt>length</dt>
1741
- <dd>Content-Lengthヘッダ。デフォルトはファイルサイズ。</dd>
1742
-
1743
- <dt>status</dt>
1744
- <dd>
1745
- 送られるステータスコード。静的ファイルをエラーページとして送るときに便利。
1746
-
1747
- Rackハンドラでサポートされている場合は、Rubyプロセスからのストリーミング以外の手段が使われる。このヘルパーメソッドを使うと、Sinatraは自動で範囲リクエスト(range requests)を扱う。
1748
- </dd>
1749
- </dl>
1750
-
1751
- ### リクエストオブジェクトへのアクセス
1752
-
1753
- 受信するリクエストオブジェクトは、`request`メソッドを通じてリクエストレベル(フィルタ、ルーティング、エラーハンドラ)からアクセスすることができます。
1754
-
1755
- ```ruby
1756
- # アプリケーションが http://example.com/example で動作している場合
1757
- get '/foo' do
1758
- t = %w[text/css text/html application/javascript]
1759
- request.accept # ['text/html', '*/*']
1760
- request.accept? 'text/xml' # true
1761
- request.preferred_type(t) # 'text/html'
1762
- request.body # クライアントによって送信されたリクエストボディ(下記参照)
1763
- request.scheme # "http"
1764
- request.script_name # "/example"
1765
- request.path_info # "/foo"
1766
- request.port # 80
1767
- request.request_method # "GET"
1768
- request.query_string # ""
1769
- request.content_length # request.bodyの長さ
1770
- request.media_type # request.bodyのメディアタイプ
1771
- request.host # "example.com"
1772
- request.get? # true (他の動詞にも同種メソッドあり)
1773
- request.form_data? # false
1774
- request["some_param"] # some_param変数の値。[]はパラメータハッシュのショートカット
1775
- request.referrer # クライアントのリファラまたは'/'
1776
- request.user_agent # ユーザエージェント (:agent 条件によって使用される)
1777
- request.cookies # ブラウザクッキーのハッシュ
1778
- request.xhr? # Ajaxリクエストかどうか
1779
- request.url # "http://example.com/example/foo"
1780
- request.path # "/example/foo"
1781
- request.ip # クライアントのIPアドレス
1782
- request.secure? # false (sslではtrueになる)
1783
- request.forwarded? # true (リバースプロキシの裏で動いている場合)
1784
- request.env # Rackによって渡された生のenvハッシュ
1785
- end
1786
- ```
1787
-
1788
- `script_name`や`path_info`などのオプションは次のように利用することもできます。
1789
-
1790
- ```ruby
1791
- before { request.path_info = "/" }
1792
-
1793
- get "/" do
1794
- "全てのリクエストはここに来る"
1795
- end
1796
- ```
1797
-
1798
- `request.body`はIOまたはStringIOのオブジェクトです。
1799
-
1800
- ```ruby
1801
- post "/api" do
1802
- request.body.rewind # 既に読まれているときのため
1803
- data = JSON.parse request.body.read
1804
- "Hello #{data['name']}!"
1805
- end
1806
- ```
1807
-
1808
- ### アタッチメント(Attachments)
1809
-
1810
- `attachment`ヘルパーを使って、レスポンスがブラウザに表示されるのではなく、ディスクに保存されることをブラウザに対し通知することができます。
1811
-
1812
- ```ruby
1813
- get '/' do
1814
- attachment
1815
- "保存しました!"
1816
- end
1817
- ```
1818
-
1819
- ファイル名を渡すこともできます。
1820
-
1821
- ```ruby
1822
- get '/' do
1823
- attachment "info.txt"
1824
- "保存しました!"
1825
- end
1826
- ```
1827
-
1828
- ### 日付と時刻の取り扱い
1829
-
1830
- Sinatraは`time_for`ヘルパーメソッドを提供しており、それは与えられた値からTimeオブジェクトを生成します。これはまた`DateTime`、`Date`および類似のクラスを変換できます。
1831
-
1832
- ```ruby
1833
- get '/' do
1834
- pass if Time.now > time_for('Dec 23, 2012')
1835
- "まだ時間がある"
1836
- end
1837
- ```
1838
-
1839
- このメソッドは、`expires`、`last_modified`といった種類のものの内部で使われています。そのため、アプリケーションにおいて、`time_for`をオーバーライドすることでそれらのメソッドの挙動を簡単に拡張できます。
1840
-
1841
- ```ruby
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
1848
- end
1849
- end
1850
- end
1851
-
1852
- get '/' do
1853
- last_modified :yesterday
1854
- expires :tomorrow
1855
- "hello"
1856
- end
1857
- ```
1858
-
1859
- ### テンプレートファイルの探索
1860
-
1861
- `find_template`ヘルパーは、レンダリングのためのテンプレートファイルを見つけるために使われます。
1862
-
1863
- ```ruby
1864
- find_template settings.views, 'foo', Tilt[:haml] do |file|
1865
- puts "could be #{file}"
1866
- end
1867
- ```
1868
-
1869
- この例はあまり有益ではありません。しかし、このメソッドを、独自の探索機構で働くようオーバーライドするなら有益になります。例えば、複数のビューディレクトリを使えるようにしたいときがあります。
1870
-
1871
-
1872
- ```ruby
1873
- set :views, ['views', 'templates']
1874
-
1875
- helpers do
1876
- def find_template(views, name, engine, &block)
1877
- Array(views).each { |v| super(v, name, engine, &block) }
1878
- end
1879
- end
1880
- ```
1881
-
1882
- 他の例としては、異なるエンジン用の異なるディレクトリを使う場合です。
1883
-
1884
- ```ruby
1885
- set :views, :sass => 'views/sass', :haml => 'templates', :default => 'views'
1886
-
1887
- helpers do
1888
- def find_template(views, name, engine, &block)
1889
- _, folder = views.detect { |k,v| engine == Tilt[k] }
1890
- folder ||= views[:default]
1891
- super(folder, name, engine, &block)
1892
- end
1893
- end
1894
- ```
1895
-
1896
- これをエクステンションとして書いて、他の人と簡単に共有することもできます!
1897
-
1898
- ノート: `find_template`はファイルが実際に存在するかのチェックをしませんが、与えられたブロックをすべての可能なパスに対し呼び出します。これがパフォーマンス上の問題にはならないのは、`render`はファイルを見つけると直ちに`break`を使うからです。また、テンプレートの場所(および内容)は、developmentモードでの起動でない限りはキャッシュされます。このことは、複雑なメソッド(a really crazy method)を書いた場合は記憶しておく必要があります。
1899
-
1900
- ## コンフィギュレーション(Configuration)
1901
-
1902
- どの環境でも起動時に1回だけ実行されます。
1903
-
1904
- ```ruby
1905
- configure do
1906
- # 1つのオプションをセット
1907
- set :option, 'value'
1908
-
1909
- # 複数のオプションをセット
1910
- set :a => 1, :b => 2
1911
-
1912
- # `set :option, true`と同じ
1913
- enable :option
1914
-
1915
- # `set :option, false`と同じ
1916
- disable :option
1917
-
1918
- # ブロックを使って動的な設定をすることもできます。
1919
- set(:css_dir) { File.join(views, 'css') }
1920
- end
1921
- ```
1922
-
1923
- 環境設定(`APP_ENV`環境変数)が`:production`に設定されている時だけ実行する方法:
1924
-
1925
- ```ruby
1926
- configure :production do
1927
- ...
1928
- end
1929
- ```
1930
-
1931
- 環境設定が`:production`か`:test`に設定されている時だけ実行する方法:
1932
-
1933
- ```ruby
1934
- configure :production, :test do
1935
- ...
1936
- end
1937
- ```
1938
-
1939
- 設定したオプションには`settings`からアクセスできます:
1940
-
1941
- ```ruby
1942
- configure do
1943
- set :foo, 'bar'
1944
- end
1945
-
1946
- get '/' do
1947
- settings.foo? # => true
1948
- settings.foo # => 'bar'
1949
- ...
1950
- end
1951
- ```
1952
-
1953
- ### 攻撃防御に対する設定
1954
-
1955
- Sinatraは[Rack::Protection](https://github.com/sinatra/sinatra/tree/master/rack-protection#readme)を使用することで、アプリケーションを一般的な日和見的攻撃から守っています。これは簡単に無効化できます(が、アプリケーションに大量の一般的な脆弱性を埋め込むことになってしまいます)。
1956
-
1957
- ```ruby
1958
- disable :protection
1959
- ```
1960
-
1961
- ある1つの防御を無効にするには、`protection`にハッシュでオプションを指定します。
1962
-
1963
- ```ruby
1964
- set :protection, :except => :path_traversal
1965
- ```
1966
-
1967
- 配列を渡すことで、複数の防御を無効にすることもできます。
1968
-
1969
- ```ruby
1970
- set :protection, :except => [:path_traversal, :session_hijacking]
1971
- ```
1972
-
1973
- デフォルトでSinatraは、`:sessions`が有効になっている場合、セッションベースの防御だけを設定します。しかし、自身でセッションを設定したい場合があります。その場合は、`:session`オプションを渡すことにより、セッションベースの防御を設定することができます。
1974
-
1975
- ```ruby
1976
- use Rack::Session::Pool
1977
- set :protection, :session => true
1978
- ```
1979
-
1980
- ### 利用可能な設定
1981
-
1982
- <dl>
1983
- <dt>absolute_redirects</dt>
1984
- <dd>
1985
- 無効のとき、Sinatraは相対リダイレクトを許容するが、RFC 2616 (HTTP 1.1)は絶対リダイレクトのみを許容するので、これには準拠しなくなる。
1986
- </dd>
1987
- <dd>
1988
- アプリケーションが、適切に設定されていないリバースプロキシの裏で走っている場合は有効。ノート: <tt>url</tt>ヘルパーは、第2引数に<tt>false</tt>を渡さない限り、依然として絶対URLを生成する。
1989
- </dd>
1990
- <dd>デフォルトは無効。</dd>
1991
-
1992
- <dt>add_charset</dt>
1993
- <dd>
1994
- Mimeタイプ <tt>content_type</tt>ヘルパーが自動的にキャラクタセット情報をここに追加する。このオプションは書き換えるのではなく、値を追加するようにすること。
1995
- <tt>settings.add_charset << "application/foobar"</tt>
1996
- </dd>
1997
-
1998
- <dt>app_file</dt>
1999
- <dd>
2000
- メインのアプリケーションファイルのパスであり、プロジェクトのルート、viewsおよびpublicフォルダを見つけるために使われる。
2001
- </dd>
2002
-
2003
- <dt>bind</dt>
2004
- <dd>バインドするIPアドレス(デフォルト: `environment`がdevelopmentにセットされているときは、<tt>0.0.0.0</tt> <em>または</em> <tt>localhost</tt>)。ビルトインサーバでのみ使われる。</dd>
2005
-
2006
- <dt>default_encoding</dt>
2007
- <dd>不明なときに仮定されるエンコーディング(デフォルトは<tt>"utf-8"</tt>)。</dd>
2008
-
2009
- <dt>dump_errors</dt>
2010
- <dd>ログにおけるエラーの表示。</dd>
2011
-
2012
- <dt>environment</dt>
2013
- <dd>
2014
- 現在の環境。デフォルトは<tt>ENV['APP_ENV']</tt>、それが無い場合は<tt>"development"</tt>。
2015
- </dd>
2016
-
2017
- <dt>logging</dt>
2018
- <dd>ロガーの使用。</dd>
2019
-
2020
- <dt>lock</dt>
2021
- <dd>
2022
- 各リクエスト周りのロックの配置で、Rubyプロセスごとにリクエスト処理を並行して走らせるようにする。
2023
- </dd>
2024
- <dd>アプリケーションがスレッドセーフでなければ有効。デフォルトは無効。</dd>
2025
-
2026
- <dt>method_override</dt>
2027
- <dd>
2028
- put/deleteフォームを、それらをサポートしないブラウザで使えるように<tt>_method</tt>のおまじないを使えるようにする。
2029
- </dd>
2030
-
2031
- <dt>port</dt>
2032
- <dd>待ち受けポート。ビルトインサーバのみで有効。</dd>
2033
-
2034
- <dt>prefixed_redirects</dt>
2035
- <dd>
2036
- 絶対パスが与えられていないときに、リダイレクトに<tt>request.script_name</tt>を挿入するか否かの設定。これにより<tt>redirect '/foo'</tt>は、<tt>redirect to('/foo')</tt>のように振る舞う。デフォルトは無効。
2037
- </dd>
2038
-
2039
- <dt>protection</dt>
2040
- <dd>Web攻撃防御を有効にするか否かの設定。上述の攻撃防御の項を参照。</dd>
2041
-
2042
- <dt>public_dir</dt>
2043
- <dd><tt>public_folder</tt>のエイリアス。以下を参照。</dd>
2044
-
2045
- <dt>public_folder</dt>
2046
- <dd>
2047
- publicファイルが提供されるディレクトリのパス。静的ファイルの提供が有効になっている場合にのみ使われる (以下の<tt>static</tt>設定を参照)。設定されていない場合、<tt>app_file</tt>設定から推定。
2048
- </dd>
2049
-
2050
- <dt>reload_templates</dt>
2051
- <dd>
2052
- リクエスト間でテンプレートを再ロードするか否かの設定。developmentモードでは有効。
2053
- </dd>
2054
-
2055
- <dt>root</dt>
2056
- <dd>
2057
- プロジェクトのルートディレクトリのパス。設定されていない場合、<tt>app_file</tt>設定から推定。
2058
- </dd>
2059
-
2060
- <dt>raise_errors</dt>
2061
- <dd>
2062
- 例外発生の設定(アプリケーションは止まる)。<tt>environment</tt>が<tt>"test"</tt>に設定されているときはデフォルトは有効。それ以外は無効。
2063
- </dd>
2064
-
2065
- <dt>run</dt>
2066
- <dd>
2067
- 有効のとき、SinatraがWebサーバの起動を取り扱う。rackupまたは他の手段を使うときは有効にしないこと。
2068
- </dd>
2069
-
2070
- <dt>running</dt>
2071
- <dd>ビルトインサーバが稼働中か?この設定を変更しないこと!</dd>
2072
-
2073
- <dt>server</dt>
2074
- <dd>
2075
- ビルトインサーバとして使用するサーバまたはサーバ群の指定。指定順位は優先度を表し、デフォルトはRuby実装に依存。
2076
- </dd>
2077
-
2078
- <dt>sessions</dt>
2079
- <dd>
2080
- <tt>Rack::Session::Cookie</tt>を使ったクッキーベースのセッションサポートの有効化。詳しくは、'セッションの使用'の項を参照のこと。
2081
- </dd>
2082
-
2083
- <dt>show_exceptions</dt>
2084
- <dd>
2085
- 例外発生時にブラウザにスタックトレースを表示する。<tt>environment</tt>が<tt>"development"</tt>に設定されているときは、デフォルトで有効。それ以外は無効。
2086
- </dd>
2087
- <dd>
2088
- また、<tt>:after_handler</tt>をセットすることができ、これにより、ブラウザにスタックトレースを表示する前に、アプリケーション固有のエラーハンドリングを起動させられる。
2089
- </dd>
2090
-
2091
- <dt>static</dt>
2092
- <dd>Sinatraが静的ファイルの提供を取り扱うかの設定。</dd>
2093
- <dd>その取り扱いができるサーバを使う場合は無効。</dd>
2094
- <dd>無効化でパフォーマンスは改善する</dd>
2095
- <dd>
2096
- クラッシックスタイルではデフォルトで有効。モジュラースタイルでは無効。
2097
- </dd>
2098
-
2099
- <dt>static_cache_control</dt>
2100
- <dd>
2101
- Sinatraが静的ファイルを提供するときこれをセットして、レスポンスに<tt>Cache-Control</tt>ヘッダを追加するようにする。<tt>cache_control</tt>ヘルパーを使うこと。デフォルトは無効。
2102
- </dd>
2103
- <dd>
2104
- 複数の値をセットするときは明示的に配列を使う:
2105
- <tt>set :static_cache_control, [:public, :max_age => 300]</tt>
2106
- </dd>
2107
-
2108
- <dt>threaded</dt>
2109
- <dd>
2110
- <tt>true</tt>に設定されているときは、Thinにリクエストを処理するために<tt>EventMachine.defer</tt>を使うことを通知する。
2111
- </dd>
2112
-
2113
- <dt>views</dt>
2114
- <dd>
2115
- ビューディレクトリのパス。設定されていない場合、<tt>app_file</tt>設定から推定する。
2116
- </dd>
2117
-
2118
- <dt>x_cascade</dt>
2119
- <dd>
2120
- マッチするルーティングが無い場合に、X-Cascadeヘッダをセットするか否かの設定。デフォルトは<tt>true</tt>。
2121
- </dd>
2122
- </dl>
2123
-
2124
- ## 環境設定(Environments)
2125
-
2126
- 3種類の既定環境、`"development"`、`"production"`および`"test"`があります。環境は、`APP_ENV`環境変数を通して設定できます。デフォルト値は、`"development"`です。`"development"`環境において、すべてのテンプレートは、各リクエスト間で再ロードされ、そして、特別の`not_found`および`error`ハンドラがブラウザにスタックトレースを表示します。`"production"`および`"test"`環境においては、テンプレートはデフォルトでキャッシュされます。
2127
-
2128
- 異なる環境を走らせるには、`APP_ENV`環境変数を設定します。
2129
-
2130
- ```shell
2131
- APP_ENV=production ruby my_app.rb
2132
- ```
2133
-
2134
- 既定メソッド、`development?`、`test?`および`production?`を、現在の環境設定を確認するために使えます。
2135
-
2136
- ```ruby
2137
- get '/' do
2138
- if settings.development?
2139
- "development!"
2140
- else
2141
- "not development!"
2142
- end
2143
- end
2144
- ```
2145
-
2146
- ## エラーハンドリング(Error Handling)
2147
-
2148
- エラーハンドラはルーティングおよびbeforeフィルタと同じコンテキストで実行されます。すなわちこれは、`haml`、`erb`、`halt`といった便利なものが全て使えることを意味します。
2149
-
2150
- ### 未検出(Not Found)
2151
-
2152
- `Sinatra::NotFound`例外が発生したとき、またはレスポンスのステータスコードが404のときに、`not_found`ハンドラが発動します。
2153
-
2154
- ```ruby
2155
- not_found do
2156
- 'ファイルが存在しません'
2157
- end
2158
- ```
2159
-
2160
- ### エラー(Error)
2161
-
2162
- `error`ハンドラはルーティングブロックまたはフィルタ内で例外が発生したときはいつでも発動します。
2163
- しかし、環境設定がdevelopmentの場合は`:after_handler`を設定している場合のみ発動するようになります。
2164
-
2165
- ```ruby
2166
- set :show_exceptions, :after_handler
2167
- ```
2168
-
2169
- 例外オブジェクトはRack変数`sinatra.error`から取得できます。
2170
-
2171
- ```ruby
2172
- error do
2173
- 'エラーが発生しました。 - ' + env['sinatra.error'].message
2174
- end
2175
- ```
2176
-
2177
- エラーをカスタマイズする場合は、
2178
-
2179
- ```ruby
2180
- error MyCustomError do
2181
- 'エラーメッセージ...' + env['sinatra.error'].message
2182
- end
2183
- ```
2184
-
2185
- と書いておいて、下記のように呼び出します。
2186
-
2187
- ```ruby
2188
- get '/' do
2189
- raise MyCustomError, '何かがまずかったようです'
2190
- end
2191
- ```
2192
-
2193
- そうするとこうなります。
2194
-
2195
- ```
2196
- エラーメッセージ... 何かがまずかったようです
2197
- ```
2198
-
2199
- あるいは、ステータスコードに対応するエラーハンドラを設定することもできます。
2200
-
2201
- ```ruby
2202
- error 403 do
2203
- 'Access forbidden'
2204
- end
2205
-
2206
- get '/secret' do
2207
- 403
2208
- end
2209
- ```
2210
-
2211
- 範囲指定もできます。
2212
-
2213
- ```ruby
2214
- error 400..510 do
2215
- 'Boom'
2216
- end
2217
- ```
2218
-
2219
- Sinatraを開発環境の下で実行している場合は、特別な`not_found`および`error`ハンドラが導入され、これは親切なスタックトレースと追加のデバッギング情報をブラウザに表示します。
2220
-
2221
- ## Rackミドルウェア(Rack Middleware)
2222
-
2223
- SinatraはRuby製Webフレームワークのミニマルな標準的インタフェースである[Rack](https://rack.github.io/)上に構築されています。アプリケーションデベロッパーにとってRackにおける最も興味深い機能は、「ミドルウェア(middleware)」をサポートしていることであり、これは、サーバとアプリケーションとの間に置かれ、HTTPリクエスト/レスポンスを監視および/または操作することで、各種の汎用的機能を提供するコンポーネントです。
2224
-
2225
- Sinatraはトップレベルの`use`メソッドを通して、Rackミドルウェアパイプラインの構築を楽にします。
2226
-
2227
- ```ruby
2228
- require 'sinatra'
2229
- require 'my_custom_middleware'
2230
-
2231
- use Rack::Lint
2232
- use MyCustomMiddleware
2233
-
2234
- get '/hello' do
2235
- 'Hello World'
2236
- end
2237
- ```
2238
-
2239
- `use`の文法は、[Rack::Builder](http://www.rubydoc.info/github/rack/rack/master/Rack/Builder)DSLで定義されているそれ(rackupファイルで最もよく使われる)と同じです。例えば `use`メソッドは複数の引数、そしてブロックも取ることができます。
2240
-
2241
- ```ruby
2242
- use Rack::Auth::Basic do |username, password|
2243
- username == 'admin' && password == 'secret'
2244
- end
2245
- ```
2246
-
2247
- Rackは、ロギング、デバッギング、URLルーティング、認証、セッション管理など、多様な標準的ミドルウェアを共に配布されています。Sinatraはその多くのコンポーネントを自動で使うよう基本設定されているため、通常、それらを`use`で明示的に指定する必要はありません。
2248
-
2249
- 便利なミドルウェアを以下で見つけられます。
2250
-
2251
- [rack](https://github.com/rack/rack/tree/master/lib/rack)、
2252
- [rack-contrib](https://github.com/rack/rack-contrib#readm)、
2253
- または[Rack wiki](https://github.com/rack/rack/wiki/List-of-Middleware)。
2254
-
2255
- ## テスト(Testing)
2256
-
2257
- SinatraでのテストはRackベースのテストライブラリまたはフレームワークを使って書くことができます。[Rack::Test](http://www.rubydoc.info/github/brynary/rack-test/master/frames)をお薦めします。
2258
-
2259
- ```ruby
2260
- require 'my_sinatra_app'
2261
- require 'minitest/autorun'
2262
- require 'rack/test'
2263
-
2264
- class MyAppTest < Minitest::Test
2265
- include Rack::Test::Methods
2266
-
2267
- def app
2268
- Sinatra::Application
2269
- end
2270
-
2271
- def test_my_default
2272
- get '/'
2273
- assert_equal 'Hello World!', last_response.body
2274
- end
2275
-
2276
- def test_with_params
2277
- get '/meet', :name => 'Frank'
2278
- assert_equal 'Hello Frank!', last_response.body
2279
- end
2280
-
2281
- def test_with_user_agent
2282
- get '/', {}, 'HTTP_USER_AGENT' => 'Songbird'
2283
- assert_equal "Songbirdを使ってます!", last_response.body
2284
- end
2285
- end
2286
- ```
2287
-
2288
- ノート: モジュラースタイルでSinatraを使う場合は、上記`Sinatra::Application`をアプリケーションのクラス名に置き換えてください。
2289
-
2290
- ## Sinatra::Base - ミドルウェア、ライブラリおよびモジュラーアプリ
2291
-
2292
- 軽量なアプリケーションであれば、トップレベルでアプリケーションを定義していくことはうまくいきますが、再利用性可能なコンポーネント、例えばRackミドルウェア、RailsのMetal、サーバコンポーネントを含むシンプルなライブラリ、あるいはSinatraの拡張プログラムを構築するような場合、これは無視できない欠点を持つものとなります。トップレベルは、軽量なアプリケーションのスタイルにおける設定(例えば、単一のアプリケーションファイル、`./public`および`./views`ディレクトリ、ロギング、例外詳細ページなど)を仮定しています。そこで`Sinatra::Base`の出番です。
2293
-
2294
- ```ruby
2295
- require 'sinatra/base'
2296
-
2297
- class MyApp < Sinatra::Base
2298
- set :sessions, true
2299
- set :foo, 'bar'
2300
-
2301
- get '/' do
2302
- 'Hello world!'
2303
- end
2304
- end
2305
- ```
2306
-
2307
- `Sinatra::Base`のサブクラスで利用できるメソッドは、トップレベルDSLで利用できるものと全く同じです。ほとんどのトップレベルで記述されたアプリは、以下の2点を修正することで`Sinatra::Base`コンポーネントに変えることができます。
2308
-
2309
- * `sinatra`の代わりに`sinatra/base`を読み込む
2310
- (そうしない場合、SinatraのDSLメソッドの全てがmainの名前空間にインポートされます)
2311
- * ルーティング、エラーハンドラ、フィルタ、オプションを`Sinatra::Base`のサブクラスに書く
2312
-
2313
- `Sinatra::Base`はまっさらです。ビルトインサーバを含む、ほとんどのオプションがデフォルトで無効になっています。利用可能なオプションとその挙動の詳細については[Configuring Settings](http://www.sinatrarb.com/configuration.html)(英語)をご覧ください。
2314
-
2315
- もしもクラシックスタイルと同じような挙動のアプリケーションをトップレベルで定義させる必要があれば、`Sinatra::Application`をサブクラス化させてください。
2316
-
2317
- ```ruby
2318
- require "sinatra/base"
2319
-
2320
- class MyApp < Sinatra::Application
2321
- get "/" do
2322
- 'Hello world!'
2323
- end
2324
- end
2325
- ```
2326
-
2327
- ### モジュラースタイル vs クラッシックスタイル
2328
-
2329
- 一般的認識と違って、クラッシックスタイルを使うことに問題はなにもありません。それがそのアプリケーションに合っているのであれば、モジュラーアプリケーションに移行する必要はありません。
2330
-
2331
- モジュラースタイルを使わずにクラッシックスタイルを使った場合の一番の不利な点は、Rubyプロセスごとにただ一つのSinatraアプリケーションしか持てない点です。複数が必要な場合はモジュラースタイルに移行してください。モジュラースタイルとクラッシックスタイルを混合できないということはありません。
2332
-
2333
- 一方のスタイルから他方へ移行する場合、デフォルト設定がわずかに異なる点に注意が必要です。
2334
-
2335
- <table>
2336
- <tr>
2337
- <th>設定</th>
2338
- <th>クラッシック</th>
2339
- <th>モジュラー</th>
2340
- <th>モジュラー</th>
2341
- </tr>
2342
-
2343
- <tr>
2344
- <td>app_file</td>
2345
- <td>sinatraを読み込むファイル</td>
2346
- <td>Sinatra::Baseをサブクラス化したファイル</td>
2347
- <td>Sinatra::Applicationをサブクラス化したファイル</td>
2348
- </tr>
2349
-
2350
- <tr>
2351
- <td>run</td>
2352
- <td>$0 == app_file</td>
2353
- <td>false</td>
2354
- <td>false</td>
2355
- </tr>
2356
-
2357
- <tr>
2358
- <td>logging</td>
2359
- <td>true</td>
2360
- <td>false</td>
2361
- <td>true</td>
2362
- </tr>
2363
-
2364
- <tr>
2365
- <td>method_override</td>
2366
- <td>true</td>
2367
- <td>false</td>
2368
- <td>true</td>
2369
- </tr>
2370
-
2371
- <tr>
2372
- <td>inline_templates</td>
2373
- <td>true</td>
2374
- <td>false</td>
2375
- <td>true</td>
2376
- </tr>
2377
-
2378
- <tr>
2379
- <td>static</td>
2380
- <td>true</td>
2381
- <td>File.exist?(public_folder)</td>
2382
- <td>true</td>
2383
- </tr>
2384
- </table>
2385
-
2386
- ### モジュラーアプリケーションの提供
2387
-
2388
- モジュラーアプリケーションを開始、つまり`run!`を使って開始させる二種類のやり方があります。
2389
-
2390
- ```ruby
2391
- # my_app.rb
2392
- require 'sinatra/base'
2393
-
2394
- class MyApp < Sinatra::Base
2395
- # ... アプリケーションのコードを書く ...
2396
-
2397
- # Rubyファイルが直接実行されたらサーバを立ち上げる
2398
- run! if app_file == $0
2399
- end
2400
- ```
2401
-
2402
- として、次のように起動するか、
2403
-
2404
- ```shell
2405
- ruby my_app.rb
2406
- ```
2407
-
2408
- または、Rackハンドラを使えるようにする`config.ru`ファイルを書いて、
2409
-
2410
- ```ruby
2411
- # config.ru (rackupで起動)
2412
- require './my_app'
2413
- run MyApp
2414
- ```
2415
-
2416
- 起動します。
2417
-
2418
- ```shell
2419
- rackup -p 4567
2420
- ```
2421
-
2422
- ### config.ruを用いたクラッシックスタイルアプリケーションの使用
2423
-
2424
- アプリケーションファイルと、
2425
-
2426
- ```ruby
2427
- # app.rb
2428
- require 'sinatra'
2429
-
2430
- get '/' do
2431
- 'Hello world!'
2432
- end
2433
- ```
2434
-
2435
- 対応する`config.ru`を書きます。
2436
-
2437
- ```ruby
2438
- require './app'
2439
- run Sinatra::Application
2440
- ```
2441
-
2442
- ### config.ruはいつ使うのか?
2443
-
2444
- `config.ru`ファイルは、以下の場合に適しています。
2445
-
2446
- * 異なるRackハンドラ(Passenger, Unicorn, Herokuなど)でデプロイしたいとき
2447
- * `Sinatra::Base`の複数のサブクラスを使いたいとき
2448
- * Sinatraをミドルウェアとして利用し、エンドポイントとしては利用しないとき
2449
-
2450
- **モジュラースタイルに移行したという理由だけで、`config.ru`に移行する必要はなく、`config.ru`で起動するためにモジュラースタイルを使う必要はありません。**
2451
-
2452
- ### Sinatraのミドルウェアとしての利用
2453
-
2454
- Sinatraは他のRackミドルウェアを利用することができるだけでなく、
2455
- 全てのSinatraアプリケーションは、それ自体ミドルウェアとして別のRackエンドポイントの前に追加することが可能です。
2456
-
2457
- このエンドポイントには、別のSinatraアプリケーションまたは他のRackベースのアプリケーション(Rails/Ramaze/Camping/…)が用いられるでしょう。
2458
-
2459
- ```ruby
2460
- require 'sinatra/base'
2461
-
2462
- class LoginScreen < Sinatra::Base
2463
- enable :sessions
2464
-
2465
- get('/login') { haml :login }
2466
-
2467
- post('/login') do
2468
- if params['name'] = 'admin' and params['password'] = 'admin'
2469
- session['user_name'] = params['name']
2470
- else
2471
- redirect '/login'
2472
- end
2473
- end
2474
- end
2475
-
2476
- class MyApp < Sinatra::Base
2477
- # ミドルウェアはbeforeフィルタの前に実行される
2478
- use LoginScreen
2479
-
2480
- before do
2481
- unless session['user_name']
2482
- halt "アクセスは拒否されました。<a href='/login'>ログイン</a>してください。"
2483
- end
2484
- end
2485
-
2486
- get('/') { "Hello #{session['user_name']}." }
2487
- end
2488
- ```
2489
-
2490
- ### 動的なアプリケーションの生成
2491
-
2492
- 新しいアプリケーションを実行時に、定数に割り当てることなく生成したくなる場合があるでしょう。`Sinatra.new`を使えばそれができます。
2493
-
2494
- ```ruby
2495
- require 'sinatra/base'
2496
- my_app = Sinatra.new { get('/') { "hi" } }
2497
- my_app.run!
2498
- ```
2499
-
2500
- これは省略できる引数として、それが継承するアプリケーションを取ります。
2501
-
2502
- ```ruby
2503
- # config.ru (rackupで起動)
2504
- require 'sinatra/base'
2505
-
2506
- controller = Sinatra.new do
2507
- enable :logging
2508
- helpers MyHelpers
2509
- end
2510
-
2511
- map('/a') do
2512
- run Sinatra.new(controller) { get('/') { 'a' } }
2513
- end
2514
-
2515
- map('/b') do
2516
- run Sinatra.new(controller) { get('/') { 'b' } }
2517
- end
2518
- ```
2519
-
2520
- これは特にSinatraのextensionをテストするときや、Sinatraを自身のライブラリで利用する場合に役立ちます。
2521
-
2522
- これはまた、Sinatraをミドルウェアとして利用することを極めて簡単にします。
2523
-
2524
- ```ruby
2525
- require 'sinatra/base'
2526
-
2527
- use Sinatra do
2528
- get('/') { ... }
2529
- end
2530
-
2531
- run RailsProject::Application
2532
- ```
2533
-
2534
- ## スコープとバインディング(Scopes and Binding)
2535
-
2536
- 現在のスコープはどのメソッドや変数が利用可能かを決定します。
2537
-
2538
- ### アプリケーション/クラスのスコープ
2539
-
2540
- 全てのSinatraアプリケーションはSinatra::Baseのサブクラスに相当します。
2541
- もしトップレベルDSLを利用しているならば(`require 'sinatra'`)このクラスはSinatra::Applicationであり、
2542
- そうでなければ、あなたが明示的に作成したサブクラスです。
2543
- クラスレベルでは`get`や`before`のようなメソッドを持っています。
2544
- しかし`request`や`session`オブジェクトには、全てのリクエストに対する単一のアプリケーションクラスがあるだけなので、アクセスできません。
2545
-
2546
- `set`によって作られたオプションはクラスレベルのメソッドです。
2547
-
2548
- ```ruby
2549
- class MyApp < Sinatra::Base
2550
- # アプリケーションスコープの中だよ!
2551
- set :foo, 42
2552
- foo # => 42
2553
-
2554
- get '/foo' do
2555
- # もうアプリケーションスコープの中にいないよ!
2556
- end
2557
- end
2558
- ```
2559
-
2560
- 次の場所ではアプリケーションスコープバインディングを持ちます。
2561
-
2562
- * アプリケーションクラス本体
2563
- * 拡張によって定義されたメソッド
2564
- * `helpers`に渡されたブロック
2565
- * `set`の値として使われるProcまたはブロック
2566
- * `Sinatra.new`に渡されたブロック
2567
-
2568
- このスコープオブジェクト(クラス)は次のように利用できます。
2569
-
2570
- * configureブロックに渡されたオブジェクト経由(`configure { |c| ... }`)
2571
- * リクエストスコープの中での`settings`
2572
-
2573
- ### リクエスト/インスタンスのスコープ
2574
-
2575
- やってくるリクエストごとに、あなたのアプリケーションクラスの新しいインスタンスが作成され、全てのハンドラブロックがそのスコープで実行されます。
2576
- このスコープの内側からは`request`や`session`オブジェクトにアクセスすることができ、`erb`や`haml`のようなレンダリングメソッドを呼び出すことができます。
2577
- リクエストスコープの内側からは、`settings`ヘルパーによってアプリケーションスコープにアクセスすることができます。
2578
-
2579
- ```ruby
2580
- class MyApp < Sinatra::Base
2581
- # アプリケーションスコープの中だよ!
2582
- get '/define_route/:name' do
2583
- # '/define_route/:name'のためのリクエストスコープ
2584
- @value = 42
2585
-
2586
- settings.get("/#{params['name']}") do
2587
- # "/#{params['name']}"のためのリクエストスコープ
2588
- @value # => nil (not the same request)
2589
- end
2590
-
2591
- "ルーティングが定義された!"
2592
- end
2593
- end
2594
- ```
2595
-
2596
- 次の場所ではリクエストスコープバインディングを持ちます。
2597
-
2598
- * get/head/post/put/delete/options/patch/link/unlink ブロック
2599
- * before/after フィルタ
2600
- * helper メソッド
2601
- * テンプレート/ビュー
2602
-
2603
- ### デリゲートスコープ
2604
-
2605
- デリゲートスコープは、単にクラススコープにメソッドを転送します。
2606
- しかしながら、クラスのバインディングを持っていないため、クラススコープと全く同じふるまいをするわけではありません。
2607
- 委譲すると明示的に示されたメソッドのみが利用可能であり、またクラススコープと変数/状態を共有することはできません(注:
2608
- 異なった`self`を持っています)。
2609
- `Sinatra::Delegator.delegate :method_name`を呼び出すことによってデリゲートするメソッドを明示的に追加することができます。
2610
-
2611
- 次の場所ではデリゲートスコープを持ちます。
2612
-
2613
- * もし`require "sinatra"`しているならば、トップレベルバインディング
2614
- * `Sinatra::Delegator` mixinでextendされたオブジェクト
2615
-
2616
- コードをご覧ください: ここでは [Sinatra::Delegator
2617
- mixin](https://github.com/sinatra/sinatra/blob/ca06364/lib/sinatra/base.rb#L1609-1633)は[mainオブジェクトにextendされています](https://github.com/sinatra/sinatra/blob/ca06364/lib/sinatra/main.rb#L28-30)。
2618
-
2619
- ## コマンドライン
2620
-
2621
- Sinatraアプリケーションは直接実行できます。
2622
-
2623
- ```shell
2624
- ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-o HOST] [-s HANDLER]
2625
- ```
2626
-
2627
- オプション:
2628
-
2629
- ```
2630
- -h # ヘルプ
2631
- -p # ポート指定(デフォルトは4567)
2632
- -o # ホスト指定(デフォルトは0.0.0.0)
2633
- -e # 環境を指定 (デフォルトはdevelopment)
2634
- -s # rackserver/handlerを指定 (デフォルトはthin)
2635
- -x # mutex lockを付ける (デフォルトはoff)
2636
- ```
2637
-
2638
- ### マルチスレッド
2639
-
2640
- _この[StackOverflow](https://stackoverflow.com/a/6282999/5245129)
2641
- のKonstantinによる回答を言い換えています。_
2642
-
2643
- Sinatraでは同時実行モデルを負わせることはできませんが、根本的な部分であるThinやPuma、WebrickのようなRackハンドラ(サーバー)部分に委ねることができます。
2644
- Sinatra自身はスレッドセーフであり、もしRackハンドラが同時実行モデルのスレッドを使用していても問題はありません。
2645
- つまり、これはサーバーを起動させる時、特定のRackハンドラに対して正しい起動処理を特定することが出来ます。
2646
- この例はThinサーバーをマルチスレッドで起動する方法のデモです。
2647
-
2648
- ```ruby
2649
- # app.rb
2650
-
2651
- require 'sinatra/base'
2652
-
2653
- class App < Sinatra::Base
2654
- get '/' do
2655
- "Hello, World"
2656
- end
2657
- end
2658
-
2659
- App.run!
2660
- ```
2661
-
2662
- サーバーを開始するコマンドです。
2663
-
2664
- ```
2665
- thin --threaded start
2666
- ```
2667
-
2668
- ## 必要環境
2669
-
2670
- 次のRubyバージョンが公式にサポートされています。
2671
-
2672
- <dl>
2673
- <dt>Ruby 1.8.7</dt>
2674
- <dd>
2675
- 1.8.7は完全にサポートされていますが、特にそれでなければならないという理由がないのであれば、アップグレードまたはJRubyまたはRubiniusへの移行を薦めます。1.8.7のサポートがSinatra 2.0の前に終わることはないでしょう。Ruby 1.8.6はサポート対象外です。
2676
- </dd>
2677
-
2678
- <dt>Ruby 1.9.2</dt>
2679
- <dd>
2680
- 1.9.2は完全にサポートされています。1.9.2p0は、Sinatraを起動したときにセグメントフォルトを引き起こすことが分かっているので、使わないでください。公式なサポートは、少なくともSinatra 1.5のリリースまでは続きます。
2681
- </dd>
2682
-
2683
- <dt>Ruby 1.9.3</dt>
2684
- <dd>
2685
- 1.9.3は完全にサポート、そして推奨されています。以前のバージョンからの1.9.3への移行は全セッションを無効にする点、覚えておいてください。
2686
- </dd>
2687
-
2688
- <dt>Ruby 2.0.0</dt>
2689
- <dd>
2690
- 2.0.0は完全にサポート、そして推奨されています。現在、その公式サポートを終了する計画はありません。
2691
- </dd>
2692
-
2693
- <dt>Rubinius</dt>
2694
- <dd>
2695
- Rubiniusは公式にサポートされています(Rubinius >= 2.x)。
2696
- <tt>gem install puma</tt>することが推奨されています。
2697
- </dd>
2698
-
2699
- <dt>JRuby</dt>
2700
- <dd>
2701
- JRubyの最新安定版が公式にサポートされています。JRubyでC拡張を使うことは推奨されていません。
2702
- <tt>gem install trinidad</tt>することが推奨されています。
2703
- </dd>
2704
- </dl>
2705
-
2706
- 開発チームは常に最新となるRubyバージョンに注視しています。
2707
-
2708
- 次のRuby実装は公式にはサポートされていませんが、Sinatraが起動すると報告されています。
2709
-
2710
- * JRubyとRubiniusの古いバージョン
2711
- * Ruby Enterprise Edition
2712
- * MacRuby, Maglev, IronRuby
2713
- * Ruby 1.9.0と1.9.1 (これらの使用はお薦めしません)
2714
-
2715
- 公式サポートをしないという意味は、問題がそこだけで起こり、サポートされているプラットフォーム上では起きない場合に、開発チームはそれはこちら側の問題ではないとみなすということです。
2716
-
2717
- 開発チームはまた、ruby-head(最新となる2.1.0)に対しCIを実行していますが、それが一貫して動くようになるまで何も保証しません。2.1.0が完全にサポートされればその限りではありません。
2718
-
2719
- Sinatraは、利用するRuby実装がサポートしているオペレーティングシステム上なら動作するはずです。
2720
-
2721
- MacRubyを使う場合は、`gem install control_tower`してください。
2722
-
2723
- Sinatraは現在、Cardinal、SmallRuby、BlueRubyまたは1.8.7以前のバージョンのRuby上では動作しません。
2724
-
2725
- ## 最新開発版
2726
-
2727
- Sinatraの最新開発版のコードを使いたい場合は、マスターブランチに対してアプリケーションを走らせて構いません。ある程度安定しています。また、適宜プレリリース版gemをpushしているので、
2728
-
2729
- ```shell
2730
- gem install sinatra --pre
2731
- ```
2732
-
2733
- すれば、最新の機能のいくつかを利用できます。
2734
-
2735
- ### Bundlerを使う場合
2736
-
2737
- 最新のSinatraでアプリケーションを動作させたい場合には、[Bundler](https://bundler.io)を使うのがお薦めのやり方です。
2738
-
2739
- まず、Bundlerがなければそれをインストールします。
2740
-
2741
- ```shell
2742
- gem install bundler
2743
- ```
2744
-
2745
- そして、プロジェクトのディレクトリで、`Gemfile`を作ります。
2746
-
2747
- ```ruby
2748
- source 'https://rubygems.org'
2749
- gem 'sinatra', :github => "sinatra/sinatra"
2750
-
2751
- # 他の依存ライブラリ
2752
- gem 'haml' # Hamlを使う場合
2753
- gem 'activerecord', '~> 3.0' # ActiveRecord 3.xが必要かもしれません
2754
- ```
2755
-
2756
- ノート: `Gemfile`にアプリケーションの依存ライブラリのすべてを並べる必要があります。しかし、Sinatraが直接依存するもの(RackおよびTile)はBundlerによって自動的に取り込まれ、追加されます。
2757
-
2758
- これで、以下のようにしてアプリケーションを起動することができます。
2759
-
2760
- ```shell
2761
- bundle exec ruby myapp.rb
2762
- ```
2763
-
2764
- ### 直接組み込む場合
2765
-
2766
- ローカルにクローンを作って、`sinatra/lib`ディレクトリを`$LOAD_PATH`に追加してアプリケーションを起動します。
2767
-
2768
- ```shell
2769
- cd myapp
2770
- git clone git://github.com/sinatra/sinatra.git
2771
- ruby -I sinatra/lib myapp.rb
2772
- ```
2773
-
2774
- 追ってSinatraのソースを更新する方法。
2775
-
2776
- ```shell
2777
- cd myapp/sinatra
2778
- git pull
2779
- ```
2780
-
2781
- ### グローバル環境にインストールする場合
2782
-
2783
- Sinatraのgemを自身でビルドすることもできます。
2784
-
2785
- ```shell
2786
- git clone git://github.com/sinatra/sinatra.git
2787
- cd sinatra
2788
- rake sinatra.gemspec
2789
- rake install
2790
- ```
2791
-
2792
- gemをルートとしてインストールする場合は、最後のステップはこうなります。
2793
-
2794
- ```shell
2795
- sudo rake install
2796
- ```
2797
-
2798
- ## バージョニング(Versioning)
2799
-
2800
- Sinatraは、[Semantic Versioning](https://semver.org/)におけるSemVerおよびSemVerTagの両方に準拠しています。
2801
-
2802
- ## 参考文献
2803
-
2804
- * [プロジェクトサイト](http://www.sinatrarb.com/) - ドキュメント、ニュース、他のリソースへのリンクがあります。
2805
- * [プロジェクトに参加(貢献)する](http://www.sinatrarb.com/contributing.html) - バグレポート パッチの送信、サポートなど
2806
- * [Issue tracker](https://github.com/sinatra/sinatra/issues)
2807
- * [Twitter](https://twitter.com/sinatra)
2808
- * [メーリングリスト](https://groups.google.com/group/sinatrarb/topics)
2809
- * http://freenode.net上のIRC: [#sinatra](irc://chat.freenode.net/#sinatra)
2810
- * [Sinatra Book](https://github.com/sinatra/sinatra-book/) クックブック、チュートリアル
2811
- * [Sinatra Recipes](http://recipes.sinatrarb.com/) コミュニティによるレシピ集
2812
- * http://www.rubydoc.info/上のAPIドキュメント: [最新版(latest release)用](http://www.rubydoc.info/gems/sinatra)または[現在のHEAD用](http://www.rubydoc.info/github/sinatra/sinatra)
2813
- * [CIサーバ](https://travis-ci.org/sinatra/sinatra)
2814
- * [Greenbear Laboratory Rack日本語マニュアル](http://route477.net/w/RackReferenceJa.html)