sinatra 1.4.6 โ 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sinatra might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/AUTHORS.md +5 -2
- data/{CHANGES โ CHANGELOG.md} +126 -46
- data/CONTRIBUTING.md +100 -0
- data/Gemfile +12 -17
- data/LICENSE +5 -2
- data/MAINTENANCE.md +42 -0
- data/README.de.md +711 -466
- data/README.es.md +206 -171
- data/README.fr.md +370 -344
- data/README.hu.md +44 -10
- data/README.ja.md +300 -210
- data/README.ko.md +230 -191
- data/README.md +675 -528
- data/README.pt-br.md +149 -115
- data/README.pt-pt.md +65 -65
- data/README.ru.md +198 -97
- data/README.zh.md +1943 -1237
- data/Rakefile +72 -49
- data/SECURITY.md +35 -0
- data/lib/sinatra/base.rb +141 -207
- data/lib/sinatra/indifferent_hash.rb +150 -0
- data/lib/sinatra/main.rb +1 -0
- data/lib/sinatra/show_exceptions.rb +70 -56
- data/lib/sinatra/version.rb +1 -1
- data/sinatra.gemspec +19 -7
- metadata +32 -163
- data/test/asciidoctor_test.rb +0 -72
- data/test/base_test.rb +0 -167
- data/test/builder_test.rb +0 -91
- data/test/coffee_test.rb +0 -96
- data/test/compile_test.rb +0 -183
- data/test/contest.rb +0 -91
- data/test/creole_test.rb +0 -65
- data/test/delegator_test.rb +0 -160
- data/test/encoding_test.rb +0 -20
- data/test/erb_test.rb +0 -116
- data/test/extensions_test.rb +0 -98
- data/test/filter_test.rb +0 -487
- data/test/haml_test.rb +0 -109
- data/test/helper.rb +0 -132
- data/test/helpers_test.rb +0 -1917
- data/test/integration/app.rb +0 -79
- data/test/integration_helper.rb +0 -236
- data/test/integration_test.rb +0 -104
- data/test/less_test.rb +0 -69
- data/test/liquid_test.rb +0 -77
- data/test/mapped_error_test.rb +0 -285
- data/test/markaby_test.rb +0 -80
- data/test/markdown_test.rb +0 -85
- data/test/mediawiki_test.rb +0 -68
- data/test/middleware_test.rb +0 -68
- data/test/nokogiri_test.rb +0 -67
- data/test/public/favicon.ico +0 -0
- data/test/rabl_test.rb +0 -89
- data/test/rack_test.rb +0 -45
- data/test/radius_test.rb +0 -59
- data/test/rdoc_test.rb +0 -66
- data/test/readme_test.rb +0 -130
- data/test/request_test.rb +0 -100
- data/test/response_test.rb +0 -63
- data/test/result_test.rb +0 -76
- data/test/route_added_hook_test.rb +0 -59
- data/test/routing_test.rb +0 -1412
- data/test/sass_test.rb +0 -115
- data/test/scss_test.rb +0 -88
- data/test/server_test.rb +0 -56
- data/test/settings_test.rb +0 -582
- data/test/sinatra_test.rb +0 -12
- data/test/slim_test.rb +0 -102
- data/test/static_test.rb +0 -236
- data/test/streaming_test.rb +0 -149
- data/test/stylus_test.rb +0 -90
- data/test/templates_test.rb +0 -382
- data/test/textile_test.rb +0 -65
- data/test/views/a/in_a.str +0 -1
- data/test/views/ascii.erb +0 -2
- data/test/views/b/in_b.str +0 -1
- data/test/views/calc.html.erb +0 -1
- data/test/views/error.builder +0 -3
- data/test/views/error.erb +0 -3
- data/test/views/error.haml +0 -3
- data/test/views/error.sass +0 -2
- data/test/views/explicitly_nested.str +0 -1
- data/test/views/foo/hello.test +0 -1
- data/test/views/hello.asciidoc +0 -1
- data/test/views/hello.builder +0 -1
- data/test/views/hello.coffee +0 -1
- data/test/views/hello.creole +0 -1
- data/test/views/hello.erb +0 -1
- data/test/views/hello.haml +0 -1
- data/test/views/hello.less +0 -5
- data/test/views/hello.liquid +0 -1
- data/test/views/hello.mab +0 -1
- data/test/views/hello.md +0 -1
- data/test/views/hello.mediawiki +0 -1
- data/test/views/hello.nokogiri +0 -1
- data/test/views/hello.rabl +0 -2
- data/test/views/hello.radius +0 -1
- data/test/views/hello.rdoc +0 -1
- data/test/views/hello.sass +0 -2
- data/test/views/hello.scss +0 -3
- data/test/views/hello.slim +0 -1
- data/test/views/hello.str +0 -1
- data/test/views/hello.styl +0 -2
- data/test/views/hello.test +0 -1
- data/test/views/hello.textile +0 -1
- data/test/views/hello.wlang +0 -1
- data/test/views/hello.yajl +0 -1
- data/test/views/layout2.builder +0 -3
- data/test/views/layout2.erb +0 -2
- data/test/views/layout2.haml +0 -2
- data/test/views/layout2.liquid +0 -2
- data/test/views/layout2.mab +0 -2
- data/test/views/layout2.nokogiri +0 -3
- data/test/views/layout2.rabl +0 -3
- data/test/views/layout2.radius +0 -2
- data/test/views/layout2.slim +0 -3
- data/test/views/layout2.str +0 -2
- data/test/views/layout2.test +0 -1
- data/test/views/layout2.wlang +0 -2
- data/test/views/nested.str +0 -1
- data/test/views/utf8.erb +0 -2
- data/test/wlang_test.rb +0 -87
- data/test/yajl_test.rb +0 -86
data/README.ko.md
CHANGED
@@ -3,9 +3,9 @@
|
|
3
3
|
*์ฃผ์: ์ด ๋ฌธ์๋ ์๋ฌธํ์ ๋ฒ์ญ๋ณธ์ด๋ฉฐ ์ต์ ํ ๋ฌธ์์ ๋ค๋ฅผ ์ ์์ต๋๋ค.*
|
4
4
|
|
5
5
|
Sinatra๋ ์ต์ํ์ ๋
ธ๋ ฅ์ผ๋ก ๋ฃจ๋น ๊ธฐ๋ฐ ์น ์ ํ๋ฆฌ์ผ์ด์
์ ์ ์ํ๊ฒ ๋ง๋ค ์ ์๊ฒ
|
6
|
-
ํด ์ฃผ๋ [DSL](
|
6
|
+
ํด ์ฃผ๋ [DSL](https://en.wikipedia.org/wiki/Domain-specific_language)์
๋๋ค.
|
7
7
|
|
8
|
-
```
|
8
|
+
```ruby
|
9
9
|
# myapp.rb
|
10
10
|
require 'sinatra'
|
11
11
|
|
@@ -14,19 +14,19 @@ get '/' do
|
|
14
14
|
end
|
15
15
|
```
|
16
16
|
|
17
|
-
์ ฌ์ ์ค์นํฉ๋๋ค.
|
17
|
+
์๋์ ๋ช
๋ น์ด๋ก ์ ฌ์ ์ค์นํฉ๋๋ค.
|
18
18
|
|
19
|
-
```
|
19
|
+
```shell
|
20
20
|
gem install sinatra
|
21
21
|
```
|
22
22
|
|
23
|
-
์คํํฉ๋๋ค.
|
23
|
+
์๋์ ๋ช
๋ น์ด๋ก ์คํํฉ๋๋ค.
|
24
24
|
|
25
|
-
```
|
25
|
+
```shell
|
26
26
|
ruby myapp.rb
|
27
27
|
```
|
28
28
|
|
29
|
-
|
29
|
+
[http://localhost:4567](http://localhost:4567) ๋ฅผ ํ์ธํด ๋ณด์ธ์.
|
30
30
|
|
31
31
|
`gem install thin`๋ ํจ๊ป ์คํํ๊ธฐ๋ฅผ ๊ถ์ฅํฉ๋๋ค.
|
32
32
|
thin์ด ์ค์น๋์ด ์์ ๊ฒฝ์ฐ Sinatra๋ thin์ ํตํด ์คํํฉ๋๋ค.
|
@@ -111,6 +111,7 @@ thin์ด ์ค์น๋์ด ์์ ๊ฒฝ์ฐ Sinatra๋ thin์ ํตํด ์คํํฉ๋๋ค.
|
|
111
111
|
* [์์ฒญ/์ธ์คํด์ค ๋ฒ์](#์์ฒญ์ธ์คํด์ค-๋ฒ์)
|
112
112
|
* [์์ ๋ฒ์(Delegation Scope)](#์์-๋ฒ์delegation-scope)
|
113
113
|
* [๋ช
๋ นํ(Command Line)](#๋ช
๋ นํcommand-line)
|
114
|
+
* [๋ค์ค ์ค๋ ๋(Multi-threading)](#๋ค์ค-์ค๋ ๋multi-threading)
|
114
115
|
* [์๊ตฌ์ฌํญ(Requirement)](#์๊ตฌ์ฌํญrequirement)
|
115
116
|
* [์ต์ (The Bleeding Edge)](#์ต์ the-bleeding-edge)
|
116
117
|
* [Bundler๋ฅผ ์ฌ์ฉํ์ฌ](#bundler๋ฅผ-์ฌ์ฉํ์ฌ)
|
@@ -124,7 +125,7 @@ thin์ด ์ค์น๋์ด ์์ ๊ฒฝ์ฐ Sinatra๋ thin์ ํตํด ์คํํฉ๋๋ค.
|
|
124
125
|
Sinatra์์, ๋ผ์ฐํฐ(route)๋ URL-๋งค์นญ ํจํด๊ณผ ์์ ์ด๋ฃจ๋ HTTP ๋ฉ์๋์
๋๋ค.
|
125
126
|
๊ฐ๊ฐ์ ๋ผ์ฐํฐ๋ ๋ธ๋ก๊ณผ ์ฐ๊ฒฐ๋ฉ๋๋ค.
|
126
127
|
|
127
|
-
```
|
128
|
+
```ruby
|
128
129
|
get '/' do
|
129
130
|
.. ๋ฌด์ธ๊ฐ ๋ณด์ฌ์ฃผ๊ธฐ(show) ..
|
130
131
|
end
|
@@ -162,7 +163,7 @@ end
|
|
162
163
|
|
163
164
|
๋ผ์ฐํฐ ํจํด์๋ ์ด๋ฆ์ ๊ฐ์ง ๋งค๊ฐ๋ณ์๊ฐ ํฌํจ๋ ์ ์์ผ๋ฉฐ, `params` ํด์๋ก ์ ๊ทผํ ์ ์์ต๋๋ค.
|
164
165
|
|
165
|
-
```
|
166
|
+
```ruby
|
166
167
|
get '/hello/:name' do
|
167
168
|
# "GET /hello/foo" ๋ฐ "GET /hello/bar"์ ๋งค์น
|
168
169
|
# params['name']์ 'foo' ๋๋ 'bar'
|
@@ -172,7 +173,7 @@ end
|
|
172
173
|
|
173
174
|
๋ํ ๋ธ๋ก ๋งค๊ฐ๋ณ์๋ฅผ ํตํ์ฌ๋ ์ด๋ฆ์ ๊ฐ์ง ๋งค๊ฐ๋ณ์์ ์ ๊ทผํ ์ ์์ต๋๋ค.
|
174
175
|
|
175
|
-
```
|
176
|
+
```ruby
|
176
177
|
get '/hello/:name' do |n|
|
177
178
|
# "GET /hello/foo" ๋ฐ "GET /hello/bar"์ ๋งค์น
|
178
179
|
# params['name']์ 'foo' ๋๋ 'bar'
|
@@ -183,7 +184,7 @@ end
|
|
183
184
|
|
184
185
|
๋ผ์ฐํฐ ํจํด์๋ ์คํ๋ซ(splat, ๋๋ ์์ผ๋์นด๋)๋ ๋งค๊ฐ๋ณ์๋ ํฌํจ๋ ์ ์์ผ๋ฉฐ, ์ด๋ด ๊ฒฝ์ฐ `params['splat']` ๋ฐฐ์ด์ ํตํด ์ ๊ทผํ ์ ์์ต๋๋ค.
|
185
186
|
|
186
|
-
```
|
187
|
+
```ruby
|
187
188
|
get '/say/*/to/*' do
|
188
189
|
# /say/hello/to/world์ ๋งค์น
|
189
190
|
params['splat'] # => ["hello", "world"]
|
@@ -197,7 +198,7 @@ end
|
|
197
198
|
|
198
199
|
๋ธ๋ก ๋งค๊ฐ๋ณ์๋ก๋ ์ ๊ทผํ ์ ์์ต๋๋ค.
|
199
200
|
|
200
|
-
```
|
201
|
+
```ruby
|
201
202
|
get '/download/*.*' do |path, ext|
|
202
203
|
[path, ext] # => ["path/to/file", "xml"]
|
203
204
|
end
|
@@ -205,15 +206,15 @@ end
|
|
205
206
|
|
206
207
|
๋ผ์ฐํฐ๋ ์ ๊ทํํ์์ผ๋ก ๋งค์นํ ์ ์์ต๋๋ค.
|
207
208
|
|
208
|
-
```
|
209
|
-
get
|
209
|
+
```ruby
|
210
|
+
get /\/hello\/([\w]+)/ do
|
210
211
|
"Hello, #{params['captures'].first}!"
|
211
212
|
end
|
212
213
|
```
|
213
214
|
|
214
215
|
๋ธ๋ก ๋งค๊ฐ๋ณ์๋ก๋ ์ฌ์ฉ๊ฐ๋ฅํฉ๋๋ค.
|
215
216
|
|
216
|
-
```
|
217
|
+
```ruby
|
217
218
|
get %r{/hello/([\w]+)} do |c|
|
218
219
|
# "GET /meta/hello/world", "GET /hello/world/1234" ๋ฑ๊ณผ ๋งค์น
|
219
220
|
"Hello, #{c}!"
|
@@ -222,15 +223,15 @@ end
|
|
222
223
|
|
223
224
|
๋ผ์ฐํฐ ํจํด์๋ ์ ํ์ ์ธ(optional) ๋งค๊ฐ๋ณ์๋ ์ฌ ์ ์์ต๋๋ค.
|
224
225
|
|
225
|
-
```
|
226
|
-
get '/posts
|
227
|
-
# "GET /posts" ๋ ๋ฌผ๋ก "GET /posts
|
226
|
+
```ruby
|
227
|
+
get '/posts/:format?' do
|
228
|
+
# "GET /posts/" ๋ ๋ฌผ๋ก "GET /posts/json", "GET /posts/xml" ์ ๊ฐ์ ์ด๋ค ํ์ฅ์์๋ ๋งค์นญ
|
228
229
|
end
|
229
230
|
```
|
230
231
|
|
231
232
|
์ฟผ๋ฆฌ ํ๋ผ๋ฉํฐ๋ก๋ ์ด์ฉ๊ฐ๋ฅ ํฉ๋๋ค.
|
232
233
|
|
233
|
-
```
|
234
|
+
```ruby
|
234
235
|
get '/posts' do
|
235
236
|
# matches "GET /posts?title=foo&author=bar"
|
236
237
|
title = params['title']
|
@@ -246,7 +247,7 @@ end
|
|
246
247
|
|
247
248
|
๋ผ์ฐํฐ๋ ์ฌ์ฉ์ ์์ด์ ํธ(user agent)๊ฐ์ ๋ค์ํ ๋งค์นญ ์กฐ๊ฑด์ ํฌํจํ ์ ์์ต๋๋ค.
|
248
249
|
|
249
|
-
```
|
250
|
+
```ruby
|
250
251
|
get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
|
251
252
|
"Songbird ๋ฒ์ #{params['agent'][0]}์ ์ฌ์ฉํ๋๊ตฐ์!"
|
252
253
|
end
|
@@ -258,7 +259,7 @@ end
|
|
258
259
|
|
259
260
|
๋ค๋ฅธ ๊ฐ๋ฅํ ์กฐ๊ฑด์๋ `host_name`๊ณผ `provides`๊ฐ ์์ต๋๋ค.
|
260
261
|
|
261
|
-
```
|
262
|
+
```ruby
|
262
263
|
get '/', :host_name => /^admin\./ do
|
263
264
|
"Admin Area, Access denied!"
|
264
265
|
end
|
@@ -275,7 +276,7 @@ end
|
|
275
276
|
|
276
277
|
์ฌ์ฉ์ ์ ์ ์กฐ๊ฑด๋ ์ฝ๊ฒ ๋ง๋ค ์ ์์ต๋๋ค.
|
277
278
|
|
278
|
-
```
|
279
|
+
```ruby
|
279
280
|
set(:probability) { |value| condition { rand <= value } }
|
280
281
|
|
281
282
|
get '/win_a_car', :probability => 0.1 do
|
@@ -289,7 +290,7 @@ end
|
|
289
290
|
|
290
291
|
์ฌ๋ฌ ๊ฐ์ ๋ฐ๋ ์กฐ๊ฑด์๋ ์คํ๋ซ(splat)์ ์ฌ์ฉํฉ๋๋ค.
|
291
292
|
|
292
|
-
```
|
293
|
+
```ruby
|
293
294
|
set(:auth) do |*roles| # <- ์ด๊ฒ ์คํ๋ซ
|
294
295
|
condition do
|
295
296
|
unless logged_in? && roles.any? {|role| current_user.in_role? role }
|
@@ -321,7 +322,7 @@ end
|
|
321
322
|
|
322
323
|
์ด๊ฒ์ ์ด์ฉํ ์๋ฅผ ๋ค์๋ฉด, ์คํธ๋ฆฌ๋ฐ(streaming) ์์ ๋ฅผ ์ฝ๊ฒ ๊ตฌํํ ์ ์์ต๋๋ค.
|
323
324
|
|
324
|
-
```
|
325
|
+
```ruby
|
325
326
|
class Stream
|
326
327
|
def each
|
327
328
|
100.times { |i| yield "#{i}\n" }
|
@@ -338,7 +339,7 @@ get('/') { Stream.new }
|
|
338
339
|
์์์ ๋ณด๋ฏ, Sinatra์๋ ๋ฌธ์์ด ํจํด ๋ฐ ์ ๊ทํํ์์ ์ด์ฉํ ๋ผ์ฐํฐ ๋งค์นญ ์ง์์ด ๋ด์ฅ๋์ด ์์ต๋๋ค.
|
339
340
|
ํ์ง๋ง, ๊ทธ๊ฒ ๋์ ์๋๋๋ค. ์ฌ๋ฌ๋ถ ๋ง์ ๋งค์ฒ(matcher)๋ ์ฝ๊ฒ ์ ์ํ ์ ์์ต๋๋ค.
|
340
341
|
|
341
|
-
```
|
342
|
+
```ruby
|
342
343
|
class AllButPattern
|
343
344
|
Match = Struct.new(:captures)
|
344
345
|
|
@@ -363,7 +364,7 @@ end
|
|
363
364
|
|
364
365
|
์ฌ์ค ์์ ์์ ๋ ์กฐ๊ธ ๊ณผํ๊ฒ ์์ฑ๋ ๋ฉด์ด ์์ต๋๋ค. ๊ฐ๋จํ๊ฒ ํํํ ์๋ ์์ด์.
|
365
366
|
|
366
|
-
```
|
367
|
+
```ruby
|
367
368
|
get // do
|
368
369
|
pass if request.path_info == "/index"
|
369
370
|
# ...
|
@@ -372,8 +373,8 @@ end
|
|
372
373
|
|
373
374
|
๋๋ ๊ฑฐ๊พธ๋ก ํ์(negative look ahead)ํ ์๋ ์์ต๋๋ค.
|
374
375
|
|
375
|
-
```
|
376
|
-
get %r{
|
376
|
+
```ruby
|
377
|
+
get %r{(?!/index)} do
|
377
378
|
# ...
|
378
379
|
end
|
379
380
|
```
|
@@ -383,12 +384,12 @@ end
|
|
383
384
|
์ ์ ํ์ผ๋ค์ `./public` ๋๋ ํฐ๋ฆฌ์์ ์ ๊ณต๋ฉ๋๋ค. ์์น๋ฅผ ๋ค๋ฅธ ๊ณณ์ผ๋ก
|
384
385
|
๋ณ๊ฒฝํ๋ ค๋ฉด `:public_folder` ์ต์
์ ์ง์ ํ๋ฉด ๋ฉ๋๋ค.
|
385
386
|
|
386
|
-
```
|
387
|
+
```ruby
|
387
388
|
set :public_folder, File.dirname(__FILE__) + '/static'
|
388
389
|
```
|
389
390
|
|
390
391
|
public ๋๋ ํฐ๋ฆฌ๋ช
์ URL์ ํฌํจ๋์ง ์๋๋ค๋ ์ ์ ์ฃผ์ํ์ธ์.
|
391
|
-
`./public/css/style.css` ํ์ผ์ ์๋ง `http://example.com/css/style.css` ๋ก ์ ๊ทผํ ์ ์์
|
392
|
+
`./public/css/style.css` ํ์ผ์ ์๋ง `http://example.com/css/style.css` ๋ก ์ ๊ทผํ ์ ์์ ๊ฒ์
๋๋ค.
|
392
393
|
|
393
394
|
`Cache-Control` ํค๋ ์ ๋ณด๋ฅผ ์ถ๊ฐํ๋ ค๋ฉด `:static_cache_control` ์ค์ (์๋ ์ฐธ์กฐ)์ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
|
394
395
|
|
@@ -397,7 +398,7 @@ public ๋๋ ํฐ๋ฆฌ๋ช
์ URL์ ํฌํจ๋์ง ์๋๋ค๋ ์ ์ ์ฃผ์ํ์ธ
|
|
397
398
|
ํ
ํ๋ฆฟ ์ธ์ด๋ค์ ๊ฐ๊ฐ์ ๋ ๋๋ง ๋ฉ์๋๋ฅผ ํตํด ํ์ถ๋ฉ๋๋ค.
|
398
399
|
์ด๋ค ๋ฉ์๋๋ ๋ฌธ์์ด์ ๋ฐํํ ๋ฟ์
๋๋ค.
|
399
400
|
|
400
|
-
```
|
401
|
+
```ruby
|
401
402
|
get '/' do
|
402
403
|
erb :index
|
403
404
|
end
|
@@ -407,7 +408,7 @@ end
|
|
407
408
|
|
408
409
|
ํ
ํ๋ฆฟ ์ด๋ฆ ๋์ ํ
ํ๋ฆฟ์ ๋ด์ฉ์ ์ง์ ๋๊ธธ ์๋ ์์ต๋๋ค.
|
409
410
|
|
410
|
-
```
|
411
|
+
```ruby
|
411
412
|
get '/' do
|
412
413
|
code = "<%= Time.now %>"
|
413
414
|
erb code
|
@@ -416,7 +417,7 @@ end
|
|
416
417
|
|
417
418
|
ํ
ํ๋ฆฟ์ ๋ ๋ฒ์งธ ์ธ์๋ก ์ต์
๊ฐ์ ํด์๋ฅผ ๋ฐ์ต๋๋ค.
|
418
419
|
|
419
|
-
```
|
420
|
+
```ruby
|
420
421
|
get '/' do
|
421
422
|
erb :index, :layout => :post
|
422
423
|
end
|
@@ -427,7 +428,7 @@ end
|
|
427
428
|
|
428
429
|
Sinatra๊ฐ ์ดํดํ์ง ๋ชปํ๋ ๋ชจ๋ ์ต์
๊ฐ๋ค์ ํ
ํ๋ฆฟ ์์ง์ผ๋ก ์ ๋ฌ๋ฉ๋๋ค.
|
429
430
|
|
430
|
-
```
|
431
|
+
```ruby
|
431
432
|
get '/' do
|
432
433
|
haml :index, :format => :html5
|
433
434
|
end
|
@@ -435,7 +436,7 @@ end
|
|
435
436
|
|
436
437
|
์ต์
๊ฐ์ ํ
ํ๋ฆฟ ์ธ์ด๋ณ๋ก ์ ์ญ์ ์ผ๋ก ์ค์ ํ ์๋ ์์ต๋๋ค.
|
437
438
|
|
438
|
-
```
|
439
|
+
```ruby
|
439
440
|
set :haml, :format => :html5
|
440
441
|
|
441
442
|
get '/' do
|
@@ -495,7 +496,7 @@ render ๋ฉ์๋์์ ์ ๋ฌ๋ ์ต์
๊ฐ๋ค์ `set`์ ํตํด ์ค์ ํ ์ต
|
|
495
496
|
ํ
ํ๋ฆฟ์ `./views` ๋๋ ํฐ๋ฆฌ์ ์๋ ๊ฒ์ผ๋ก ๊ฐ์ ๋ฉ๋๋ค. ๋ทฐ ๋๋ ํฐ๋ฆฌ๋ฅผ
|
496
497
|
๋ค๋ฅธ ๊ณณ์ผ๋ก ํ๊ณ ์ถ์ผ์๋ฉด ์ด๋ ๊ฒ ํ์ธ์.
|
497
498
|
|
498
|
-
```
|
499
|
+
```ruby
|
499
500
|
set :views, settings.root + '/templates'
|
500
501
|
```
|
501
502
|
|
@@ -506,7 +507,7 @@ set :views, settings.root + '/templates'
|
|
506
507
|
|
507
508
|
### ๋ฆฌํฐ๋ด ํ
ํ๋ฆฟ(Literal Templates)
|
508
509
|
|
509
|
-
```
|
510
|
+
```ruby
|
510
511
|
get '/' do
|
511
512
|
haml '%div.title Hello World'
|
512
513
|
end
|
@@ -519,7 +520,7 @@ end
|
|
519
520
|
์ผ๋ถ ์ธ์ด๋ ์ฌ๋ฌ ๊ฐ์ ๊ตฌํ์ด ์์ต๋๋ค. (์ค๋ ๋์ ์์ ํ๊ฒ thread-safe) ์ด๋ ๊ตฌํ์
|
520
521
|
์ฌ์ฉํ ์ง ์ ์ ํ๋ ค๋ฉด, ๋จผ์ require ํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค.
|
521
522
|
|
522
|
-
```
|
523
|
+
```ruby
|
523
524
|
require 'rdiscount' # or require 'bluecloth'
|
524
525
|
get('/') { markdown :index }
|
525
526
|
```
|
@@ -582,7 +583,7 @@ get('/') { markdown :index }
|
|
582
583
|
<table>
|
583
584
|
<tr>
|
584
585
|
<td>์์กด์ฑ</td>
|
585
|
-
<td><a href="http://nokogiri.org/">nokogiri</a></td>
|
586
|
+
<td><a href="http://www.nokogiri.org/">nokogiri</a></td>
|
586
587
|
</tr>
|
587
588
|
<tr>
|
588
589
|
<td>ํ์ผ ํ์ฅ์</td>
|
@@ -635,7 +636,7 @@ get('/') { markdown :index }
|
|
635
636
|
<table>
|
636
637
|
<tr>
|
637
638
|
<td>์์กด์ฑ</td>
|
638
|
-
<td><a href="http://
|
639
|
+
<td><a href="http://lesscss.org/">less</a></td>
|
639
640
|
</tr>
|
640
641
|
<tr>
|
641
642
|
<td>ํ์ผ ํ์ฅ์</td>
|
@@ -652,7 +653,7 @@ get('/') { markdown :index }
|
|
652
653
|
<table>
|
653
654
|
<tr>
|
654
655
|
<td>์์กด์ฑ</td>
|
655
|
-
<td><a href="http://
|
656
|
+
<td><a href="http://liquidmarkup.org/">liquid</a></td>
|
656
657
|
</tr>
|
657
658
|
<tr>
|
658
659
|
<td>ํ์ผ ํ์ฅ์</td>
|
@@ -673,7 +674,7 @@ Liquid ํ
ํ๋ฆฟ์์๋ ๋ฃจ๋น ๋ฉ์๋(`yield` ์ ์ธ)๋ฅผ ํธ์ถํ ์ ์
|
|
673
674
|
<tr>
|
674
675
|
<td>์์กด์ฑ</td>
|
675
676
|
<td>
|
676
|
-
<a href="https://github.com/
|
677
|
+
<a href="https://github.com/davidfstr/rdiscount" title="RDiscount">RDiscount</a>,
|
677
678
|
<a href="https://github.com/vmg/redcarpet" title="RedCarpet">RedCarpet</a>,
|
678
679
|
<a href="http://deveiate.org/projects/BlueCloth" title="BlueCloth">BlueCloth</a>,
|
679
680
|
<a href="http://kramdown.gettalong.org/" title="kramdown">kramdown</a>,
|
@@ -694,13 +695,13 @@ Liquid ํ
ํ๋ฆฟ์์๋ ๋ฃจ๋น ๋ฉ์๋(`yield` ์ ์ธ)๋ฅผ ํธ์ถํ ์ ์
|
|
694
695
|
Markdown์์๋ ๋ฉ์๋ ํธ์ถ ๋ฟ ์๋๋ผ locals ์ ๋ฌ๋ ์๋ฉ๋๋ค.
|
695
696
|
๋ฐ๋ผ์ ์ผ๋ฐ์ ์ผ๋ก๋ ๋ค๋ฅธ ๋ ๋๋ง ์์ง๊ณผ ํจ๊ป ์ฌ์ฉํ๊ฒ ๋ฉ๋๋ค.
|
696
697
|
|
697
|
-
```
|
698
|
+
```ruby
|
698
699
|
erb :overview, :locals => { :text => markdown(:introduction) }
|
699
700
|
```
|
700
701
|
|
701
702
|
๋ค๋ฅธ ํ
ํ๋ฆฟ ์์์ `markdown` ๋ฉ์๋๋ฅผ ํธ์ถํ ์๋ ์์ต๋๋ค.
|
702
703
|
|
703
|
-
```
|
704
|
+
```ruby
|
704
705
|
%h1 ์๋
Haml!
|
705
706
|
%p= markdown(:greetings)
|
706
707
|
```
|
@@ -729,13 +730,13 @@ Markdown์์ ๋ฃจ๋น๋ฅผ ํธ์ถํ ์ ์๊ธฐ ๋๋ฌธ์, Markdown์ผ๋ก ์์ฑ
|
|
729
730
|
Textile์์๋ ๋ฉ์๋ ํธ์ถ ๋ฟ ์๋๋ผ locals ์ ๋ฌ๋ ์๋ฉ๋๋ค.
|
730
731
|
๋ฐ๋ผ์ ์ผ๋ฐ์ ์ผ๋ก๋ ๋ค๋ฅธ ๋ ๋๋ง ์์ง๊ณผ ํจ๊ป ์ฌ์ฉํ๊ฒ ๋ฉ๋๋ค.
|
731
732
|
|
732
|
-
```
|
733
|
+
```ruby
|
733
734
|
erb :overview, :locals => { :text => textile(:introduction) }
|
734
735
|
```
|
735
736
|
|
736
737
|
๋ค๋ฅธ ํ
ํ๋ฆฟ ์์์ `textile` ๋ฉ์๋๋ฅผ ํธ์ถํ ์๋ ์์ต๋๋ค.
|
737
738
|
|
738
|
-
```
|
739
|
+
```ruby
|
739
740
|
%h1 ์๋
Haml!
|
740
741
|
%p= textile(:greetings)
|
741
742
|
```
|
@@ -764,13 +765,13 @@ Textile์์ ๋ฃจ๋น๋ฅผ ํธ์ถํ ์ ์๊ธฐ ๋๋ฌธ์, Textile์ผ๋ก ์์ฑ๋
|
|
764
765
|
RDoc์์๋ ๋ฉ์๋ ํธ์ถ ๋ฟ ์๋๋ผ locals ์ ๋ฌ๋ ์๋ฉ๋๋ค.
|
765
766
|
๋ฐ๋ผ์ ์ผ๋ฐ์ ์ผ๋ก๋ ๋ค๋ฅธ ๋ ๋๋ง ์์ง๊ณผ ํจ๊ป ์ฌ์ฉํ๊ฒ ๋ฉ๋๋ค.
|
766
767
|
|
767
|
-
```
|
768
|
+
```ruby
|
768
769
|
erb :overview, :locals => { :text => rdoc(:introduction) }
|
769
770
|
```
|
770
771
|
|
771
772
|
๋ค๋ฅธ ํ
ํ๋ฆฟ ์์์ `rdoc` ๋ฉ์๋๋ฅผ ํธ์ถํ ์๋ ์์ต๋๋ค.
|
772
773
|
|
773
|
-
```
|
774
|
+
```ruby
|
774
775
|
%h1 Hello From Haml!
|
775
776
|
%p= rdoc(:greetings)
|
776
777
|
```
|
@@ -824,7 +825,7 @@ Radius ํ
ํ๋ฆฟ์์๋ ๋ฃจ๋น ๋ฉ์๋๋ฅผ ํธ์ถํ ์ ์๊ธฐ
|
|
824
825
|
<table>
|
825
826
|
<tr>
|
826
827
|
<td>์์กด์ฑ</td>
|
827
|
-
<td><a href="http://markaby.github.
|
828
|
+
<td><a href="http://markaby.github.io/">markaby</a></td>
|
828
829
|
</tr>
|
829
830
|
<tr>
|
830
831
|
<td>ํ์ผํ์ฅ</td>
|
@@ -892,13 +893,13 @@ Radius ํ
ํ๋ฆฟ์์๋ ๋ฃจ๋น ๋ฉ์๋๋ฅผ ํธ์ถํ ์ ์๊ธฐ
|
|
892
893
|
Creole์์๋ ๋ฉ์๋ ํธ์ถ ๋ฟ ์๋๋ผ locals ์ ๋ฌ๋ ์๋ฉ๋๋ค.
|
893
894
|
๋ฐ๋ผ์ ์ผ๋ฐ์ ์ผ๋ก๋ ๋ค๋ฅธ ๋ ๋๋ง ์์ง๊ณผ ํจ๊ป ์ฌ์ฉํ๊ฒ ๋ฉ๋๋ค.
|
894
895
|
|
895
|
-
```
|
896
|
+
```ruby
|
896
897
|
erb :overview, :locals => { :text => creole(:introduction) }
|
897
898
|
```
|
898
899
|
|
899
900
|
๋ค๋ฅธ ํ
ํ๋ฆฟ ์์์ `creole` ๋ฉ์๋๋ฅผ ํธ์ถํ ์๋ ์์ต๋๋ค.
|
900
901
|
|
901
|
-
```
|
902
|
+
```ruby
|
902
903
|
%h1 Hello From Haml!
|
903
904
|
%p= creole(:greetings)
|
904
905
|
```
|
@@ -927,13 +928,13 @@ Creole์์ ๋ฃจ๋น๋ฅผ ํธ์ถํ ์ ์๊ธฐ ๋๋ฌธ์, Creole์ผ๋ก ์์ฑ๋
|
|
927
928
|
MediaWiki ๋งํฌ์
์์๋ ๋ฉ์๋ ํธ์ถ ๋ฟ ์๋๋ผ locals ์ ๋ฌ๋ ๋ถ๊ฐ๋ฅํฉ๋๋ค.
|
928
929
|
๋ฐ๋ผ์ ์ผ๋ฐ์ ์ผ๋ก๋ ๋ค๋ฅธ ๋ ๋๋ง ์์ง๊ณผ ํจ๊ป ์ฌ์ฉํ๊ฒ ๋ฉ๋๋ค.
|
929
930
|
|
930
|
-
```
|
931
|
+
```ruby
|
931
932
|
erb :overview, :locals => { :text => mediawiki(:introduction) }
|
932
933
|
```
|
933
934
|
|
934
935
|
๋ค๋ฅธ ํ
ํ๋ฆฟ ์์์ `mediawiki` ๋ฉ์๋๋ฅผ ํธ์ถํ ์๋ ์์ต๋๋ค.
|
935
936
|
|
936
|
-
```
|
937
|
+
```ruby
|
937
938
|
%h1 Hello From Haml!
|
938
939
|
%p= mediawiki(:greetings)
|
939
940
|
```
|
@@ -972,7 +973,7 @@ MediaWiki์์ ๋ฃจ๋น๋ฅผ ํธ์ถํ ์ ์๊ธฐ ๋๋ฌธ์, MediaWiki์ผ๋ก ์์ฑ
|
|
972
973
|
<tr>
|
973
974
|
<td>์์กด์ฑ</td>
|
974
975
|
<td>
|
975
|
-
<a href="https://github.com/
|
976
|
+
<a href="https://github.com/forgecrafted/ruby-stylus" title="Ruby Stylus">
|
976
977
|
Stylus
|
977
978
|
</a> ์
|
978
979
|
<a href="https://github.com/sstephenson/execjs/blob/master/README.md#readme" title="ExecJS">
|
@@ -993,7 +994,7 @@ MediaWiki์์ ๋ฃจ๋น๋ฅผ ํธ์ถํ ์ ์๊ธฐ ๋๋ฌธ์, MediaWiki์ผ๋ก ์์ฑ
|
|
993
994
|
Stylus ํ
ํ๋ฆฟ์ ์ฌ์ฉ๊ฐ๋ฅํ๊ฒ ํ๋ ค๋ฉด, ๋จผ์ `stylus`์ `stylus/tilt`๋ฅผ ๋ก๋
|
994
995
|
ํด์ผํฉ๋๋ค.
|
995
996
|
|
996
|
-
```
|
997
|
+
```ruby
|
997
998
|
require 'sinatra'
|
998
999
|
require 'stylus'
|
999
1000
|
require 'stylus/tilt'
|
@@ -1029,7 +1030,7 @@ end
|
|
1029
1030
|
|
1030
1031
|
ํ
ํ๋ฆฟ ์์ค๋ ๋ฃจ๋น ๋ฌธ์์ด๋ก ํ๊ฐ(evaluate)๋๊ณ , ๊ฒฐ๊ณผ์ธ json ๋ณ์๋ `#to_json`์ผ๋ก ๋ณํ๋ฉ๋๋ค.
|
1031
1032
|
|
1032
|
-
```
|
1033
|
+
```ruby
|
1033
1034
|
json = { :foo => 'bar' }
|
1034
1035
|
json[:baz] = key
|
1035
1036
|
```
|
@@ -1067,7 +1068,7 @@ WLang์ผ๋ก ์ฐ์ฌ์ง ๋ ์ด์์๊ณผ `yield`๋ ์ง์ํฉ๋๋ค.
|
|
1067
1068
|
ํ
ํ๋ฆฟ์ ๋ผ์ฐํฐ ํธ๋ค๋ฌ์ ๊ฐ์ ๋งฅ๋ฝ(context)์์ ํ๊ฐ๋ฉ๋๋ค. ๋ผ์ฐํฐ
|
1068
1069
|
ํธ๋ค๋ฌ์์ ์ค์ ํ ์ธ์คํด์ค ๋ณ์๋ค์ ํ
ํ๋ฆฟ์์ ์ง์ ์ ๊ทผ ๊ฐ๋ฅํฉ๋๋ค.
|
1069
1070
|
|
1070
|
-
```
|
1071
|
+
```ruby
|
1071
1072
|
get '/:id' do
|
1072
1073
|
@foo = Foo.find(params['id'])
|
1073
1074
|
haml '%h1= @foo.name'
|
@@ -1076,7 +1077,7 @@ end
|
|
1076
1077
|
|
1077
1078
|
๋ช
์์ ์ผ๋ก ๋ก์ปฌ ๋ณ์์ ํด์๋ฅผ ์ง์ ํ ์๋ ์์ต๋๋ค.
|
1078
1079
|
|
1079
|
-
```
|
1080
|
+
```ruby
|
1080
1081
|
get '/:id' do
|
1081
1082
|
foo = Foo.find(params['id'])
|
1082
1083
|
haml '%h1= bar.name', :locals => { :bar => foo }
|
@@ -1092,7 +1093,7 @@ end
|
|
1092
1093
|
์์ ์ค๋ช
๋ `:template` ์ต์
์ ํตํด ํ
ํ๋ฆฟ์ ์ฌ์ฉํ๊ฑฐ๋,
|
1093
1094
|
๋ค์ ์์ ์ฒ๋ผ ๋ธ๋ก์ผ๋ก ๋ ๋๋ง ํ ์ ์์ต๋๋ค.
|
1094
1095
|
|
1095
|
-
```
|
1096
|
+
```ruby
|
1096
1097
|
erb :post, :layout => false do
|
1097
1098
|
erb :index
|
1098
1099
|
end
|
@@ -1102,7 +1103,7 @@ end
|
|
1102
1103
|
|
1103
1104
|
๋ ๋๋ง ๋ฉ์๋์ ๋ธ๋ก ๋๊ธฐ๊ธฐ๋ ์ค์ฒฉ ๋ ์ด์์์ ๋ง๋ค๋ ์ ์ฉํฉ๋๋ค.
|
1104
1105
|
|
1105
|
-
```
|
1106
|
+
```ruby
|
1106
1107
|
erb :main_layout, :layout => false do
|
1107
1108
|
erb :admin_layout do
|
1108
1109
|
erb :user
|
@@ -1112,7 +1113,7 @@ end
|
|
1112
1113
|
|
1113
1114
|
์์ ์ฝ๋๋ ์ค์ผ ์ ์์ต๋๋ค.
|
1114
1115
|
|
1115
|
-
```
|
1116
|
+
```ruby
|
1116
1117
|
erb :admin_layout, :layout => :main_layout do
|
1117
1118
|
erb :user
|
1118
1119
|
end
|
@@ -1125,7 +1126,7 @@ end
|
|
1125
1126
|
|
1126
1127
|
ํ
ํ๋ฆฟ์ ์์ค ํ์ผ์ ๋ง์ง๋ง์์ ์ ์ํ ์๋ ์์ต๋๋ค.
|
1127
1128
|
|
1128
|
-
```
|
1129
|
+
```ruby
|
1129
1130
|
require 'sinatra'
|
1130
1131
|
|
1131
1132
|
get '/' do
|
@@ -1150,7 +1151,7 @@ __END__
|
|
1150
1151
|
|
1151
1152
|
ํ
ํ๋ฆฟ์ ํฑ ๋ ๋ฒจ(top-level)์์ `template`๋ฉ์๋๋ก๋ ์ ์ํ ์ ์์ต๋๋ค.
|
1152
1153
|
|
1153
|
-
```
|
1154
|
+
```ruby
|
1154
1155
|
template :layout do
|
1155
1156
|
"%html\n =yield\n"
|
1156
1157
|
end
|
@@ -1169,7 +1170,7 @@ end
|
|
1169
1170
|
๋นํ์ฑ์ํค๊ฑฐ๋ `set :haml, :layout => false`์ผ๋ก ๊ธฐ๋ณธ๊ฐ์ ๋นํ์ฑ์ผ๋ก ๋ ์
|
1170
1171
|
์์ต๋๋ค.
|
1171
1172
|
|
1172
|
-
```
|
1173
|
+
```ruby
|
1173
1174
|
get '/' do
|
1174
1175
|
haml :index, :layout => !request.xhr?
|
1175
1176
|
end
|
@@ -1181,7 +1182,7 @@ end
|
|
1181
1182
|
๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด, `tt`๋ผ๋ ํ์ผ ํ์ฅ์๋ฅผ Textile ํ
ํ๋ฆฟ๊ณผ ์ฐ๊ฒฐํ๊ณ ์ถ๋ค๋ฉด,
|
1182
1183
|
๋ค์๊ณผ ๊ฐ์ด ํ๋ฉด ๋ฉ๋๋ค.
|
1183
1184
|
|
1184
|
-
```
|
1185
|
+
```ruby
|
1185
1186
|
Tilt.register :tt, Tilt[:textile]
|
1186
1187
|
```
|
1187
1188
|
|
@@ -1189,7 +1190,7 @@ Tilt.register :tt, Tilt[:textile]
|
|
1189
1190
|
|
1190
1191
|
์ฐ์ , Tilt๋ก ์ฌ๋ฌ๋ถ ์์ง์ ๋ฑ๋กํ๊ณ , ๋ ๋๋ง ๋ฉ์๋๋ฅผ ์์ฑํฉ๋๋ค.
|
1191
1192
|
|
1192
|
-
```
|
1193
|
+
```ruby
|
1193
1194
|
Tilt.register :myat, MyAwesomeTemplateEngine
|
1194
1195
|
|
1195
1196
|
helpers do
|
@@ -1208,7 +1209,7 @@ Tilt์ ๋ํ ๋ ์์ธํ ๋ด์ฉ์ https://github.com/rtomayko/tilt ์ฐธ์กฐ
|
|
1208
1209
|
|
1209
1210
|
๊ณ ์ ํ ํ
ํ๋ฆฟ ๋ฃฉ์
์ ๊ตฌํํ๊ธฐ ์ํด์๋ `#find_template` ๋ฉ์๋๋ฅผ ๋ง๋์
์ผ ํฉ๋๋ค.
|
1210
1211
|
|
1211
|
-
```
|
1212
|
+
```ruby
|
1212
1213
|
configure do
|
1213
1214
|
set :views [ './views/a', './views/b' ]
|
1214
1215
|
end
|
@@ -1226,7 +1227,7 @@ end
|
|
1226
1227
|
์์ฒญ๊ณผ ์๋ต์ ๋ณํํ ์ ์์ต๋๋ค. ํํฐ์์ ์ค์ ๋ ์ธ์คํด์ค ๋ณ์๋ค์ ๋ผ์ฐํฐ์
|
1227
1228
|
ํ
ํ๋ฆฟ์์ ์ ๊ทผ ๊ฐ๋ฅํฉ๋๋ค.
|
1228
1229
|
|
1229
|
-
```
|
1230
|
+
```ruby
|
1230
1231
|
before do
|
1231
1232
|
@note = 'Hi!'
|
1232
1233
|
request.path_info = '/foo/bar/baz'
|
@@ -1242,7 +1243,7 @@ end
|
|
1242
1243
|
๋ง์ฐฌ๊ฐ์ง๋ก ์์ฒญ๊ณผ ์๋ต์ ๋ณํํ ์ ์์ต๋๋ค. ์ฌ์ ํํฐ์ ๋ผ์ฐํฐ์์ ์ค์ ๋
|
1243
1244
|
์ธ์คํด์ค ๋ณ์๋ค์ ์ฌํ ํํฐ์์ ์ ๊ทผ ๊ฐ๋ฅํฉ๋๋ค.
|
1244
1245
|
|
1245
|
-
```
|
1246
|
+
```ruby
|
1246
1247
|
after do
|
1247
1248
|
puts response.status
|
1248
1249
|
end
|
@@ -1255,7 +1256,7 @@ end
|
|
1255
1256
|
ํํฐ๋ ํจํด์ ์ทจํ ์๋ ์์ผ๋ฉฐ, ์ด ๊ฒฝ์ฐ ์์ฒญ ๊ฒฝ๋ก๊ฐ ๊ทธ ํจํด๊ณผ ๋งค์นํ
|
1256
1257
|
๊ฒฝ์ฐ์๋ง ํํฐ๊ฐ ํ๊ฐ๋ ๊ฒ์
๋๋ค.
|
1257
1258
|
|
1258
|
-
```
|
1259
|
+
```ruby
|
1259
1260
|
before '/protected/*' do
|
1260
1261
|
authenticate!
|
1261
1262
|
end
|
@@ -1267,7 +1268,7 @@ end
|
|
1267
1268
|
|
1268
1269
|
๋ผ์ฐํฐ์ ๋ง์ฐฌ๊ฐ์ง๋ก, ํํฐ ์ญ์ ์กฐ๊ฑด์ ์ทจํ ์ ์์ต๋๋ค.
|
1269
1270
|
|
1270
|
-
```
|
1271
|
+
```ruby
|
1271
1272
|
before :agent => /Songbird/ do
|
1272
1273
|
# ...
|
1273
1274
|
end
|
@@ -1282,7 +1283,7 @@ end
|
|
1282
1283
|
ํฑ-๋ ๋ฒจ์ `helpers` ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ๋ผ์ฐํฐ ํธ๋ค๋ฌ์ ํ
ํ๋ฆฟ์์ ์ฌ์ฉํ ํฌํผ
|
1283
1284
|
๋ฉ์๋๋ค์ ์ ์ํ ์ ์์ต๋๋ค.
|
1284
1285
|
|
1285
|
-
```
|
1286
|
+
```ruby
|
1286
1287
|
helpers do
|
1287
1288
|
def bar(name)
|
1288
1289
|
"#{name}bar"
|
@@ -1296,7 +1297,7 @@ end
|
|
1296
1297
|
|
1297
1298
|
๋๋, ํฌํผ ๋ฉ์๋๋ ๋ณ๋์ ๋ชจ๋ ์์ ์ ์ํ ์๋ ์์ต๋๋ค.
|
1298
1299
|
|
1299
|
-
```
|
1300
|
+
```ruby
|
1300
1301
|
module FooUtils
|
1301
1302
|
def foo(name) "#{name}foo" end
|
1302
1303
|
end
|
@@ -1315,7 +1316,7 @@ helpers FooUtils, BarUtils
|
|
1315
1316
|
์ธ์
์ ์์ฒญ ๋์์ ์ํ๋ฅผ ์ ์งํ๊ธฐ ์ํด ์ฌ์ฉํฉ๋๋ค.
|
1316
1317
|
์ธ์
์ด ํ์ฑํ๋๋ฉด, ์ฌ์ฉ์ ์ธ์
๋น ์ธ์
ํด์ ํ๋์ฉ์ ๊ฐ๊ฒ ๋ฉ๋๋ค.
|
1317
1318
|
|
1318
|
-
```
|
1319
|
+
```ruby
|
1319
1320
|
enable :sessions
|
1320
1321
|
|
1321
1322
|
get '/' do
|
@@ -1334,7 +1335,7 @@ end
|
|
1334
1335
|
`enable :sessions`์ ํธ์ถํ์ง **์๋** ๋์ ์, ์ ํํ ๋ฏธ๋ค์จ์ด๋ฅผ ๋ค๋ฅธ
|
1335
1336
|
๋ฏธ๋ค์จ์ด๋ค์ฒ๋ผ ํฌํจ์ํค๋ฉด ๋ฉ๋๋ค.
|
1336
1337
|
|
1337
|
-
```
|
1338
|
+
```ruby
|
1338
1339
|
use Rack::Session::Pool, :expire_after => 2592000
|
1339
1340
|
|
1340
1341
|
get '/' do
|
@@ -1351,21 +1352,21 @@ end
|
|
1351
1352
|
์ํฌ๋ฆฟ์ ์ ํ๋ฆฌ์ผ์ด์
์์ ์๋ง๋ค ๋ณ๊ฒฝ๋๊ธฐ ๋๋ฌธ์, ์ ํ๋ฆฌ์ผ์ด์
์
|
1352
1353
|
๋ชจ๋ ์ธ์คํด์ค๋ค์ด ๊ณต์ ํ ์ํฌ๋ฆฟ์ ์ง์ ๋ง๋ค ์๋ ์์ต๋๋ค.
|
1353
1354
|
|
1354
|
-
```
|
1355
|
+
```ruby
|
1355
1356
|
set :session_secret, 'super secret'
|
1356
1357
|
```
|
1357
1358
|
|
1358
1359
|
์กฐ๊ธ ๋ ์ธ๋ถ์ ์ธ ์ค์ ์ด ํ์ํ๋ค๋ฉด, `sessions` ์ค์ ์์ ์ต์
์ด ์๋
|
1359
1360
|
ํด์๋ฅผ ์ ์ฅํ ์๋ ์์ต๋๋ค.
|
1360
1361
|
|
1361
|
-
```
|
1362
|
+
```ruby
|
1362
1363
|
set :sessions, :domain => 'foo.com'
|
1363
1364
|
```
|
1364
1365
|
|
1365
1366
|
์ธ์
์ ๋ค๋ฅธ foo.com์ ์๋ธ๋๋ฉ์ธ ๋ค๊ณผ ๊ณต์ ํ๊ธฐ ์ํ๋ค๋ฉด, ๋ค์์ ๋์ค๋
|
1366
1367
|
๊ฒ ์ฒ๋ผ ๋๋ฉ์ธ ์์ *.*์ ๋ถ์ด์
์ผ ํฉ๋๋ค.
|
1367
1368
|
|
1368
|
-
```
|
1369
|
+
```ruby
|
1369
1370
|
set :sessions, :domain => '.foo.com'
|
1370
1371
|
```
|
1371
1372
|
|
@@ -1373,37 +1374,37 @@ set :sessions, :domain => '.foo.com'
|
|
1373
1374
|
|
1374
1375
|
ํํฐ๋ ๋ผ์ฐํฐ์์ ์์ฒญ์ ์ฆ๊ฐ ์ค๋จํ๊ณ ์ถ์ ๋ ์ฌ์ฉํํฉ๋๋ค.
|
1375
1376
|
|
1376
|
-
```
|
1377
|
+
```ruby
|
1377
1378
|
halt
|
1378
1379
|
```
|
1379
1380
|
|
1380
1381
|
์ค๋จํ ๋ ์ํ๋ฅผ ์ง์ ํ ์๋ ์์ต๋๋ค.
|
1381
1382
|
|
1382
|
-
```
|
1383
|
+
```ruby
|
1383
1384
|
halt 410
|
1384
1385
|
```
|
1385
1386
|
|
1386
1387
|
๋ณธ๋ฌธ์ ๋ฃ์ ์๋ ์์ต๋๋ค.
|
1387
1388
|
|
1388
|
-
```
|
1389
|
+
```ruby
|
1389
1390
|
halt 'this will be the body'
|
1390
1391
|
```
|
1391
1392
|
|
1392
1393
|
๋ ๋ค ํ ์๋ ์์ต๋๋ค.
|
1393
1394
|
|
1394
|
-
```
|
1395
|
+
```ruby
|
1395
1396
|
halt 401, 'go away!'
|
1396
1397
|
```
|
1397
1398
|
|
1398
1399
|
ํค๋๋ฅผ ์ถ๊ฐํ ๊ฒฝ์ฐ์๋ ๋ค์๊ณผ ๊ฐ์ด ํ๋ฉด ๋ฉ๋๋ค.
|
1399
1400
|
|
1400
|
-
```
|
1401
|
+
```ruby
|
1401
1402
|
halt 402, {'Content-Type' => 'text/plain'}, 'revenge'
|
1402
1403
|
```
|
1403
1404
|
|
1404
1405
|
๋น์ฐํ `halt`์ ํ
ํ๋ฆฟ์ ๊ฐ์ด ์ฌ์ฉํ ์ ์์ต๋๋ค.
|
1405
1406
|
|
1406
|
-
```
|
1407
|
+
```ruby
|
1407
1408
|
halt erb(:error)
|
1408
1409
|
```
|
1409
1410
|
|
@@ -1411,7 +1412,7 @@ halt erb(:error)
|
|
1411
1412
|
|
1412
1413
|
๋ผ์ฐํฐ๋ `pass`๋ฅผ ์ฌ์ฉํ์ฌ ๋ค์ ๋ฒ ๋งค์นญ๋๋ ๋ผ์ฐํฐ๋ก ์ฒ๋ฆฌ๋ฅผ ๋๊ธธ ์ ์์ต๋๋ค.
|
1413
1414
|
|
1414
|
-
```
|
1415
|
+
```ruby
|
1415
1416
|
get '/guess/:who' do
|
1416
1417
|
pass unless params['who'] == 'Frank'
|
1417
1418
|
'You got me!'
|
@@ -1430,7 +1431,7 @@ end
|
|
1430
1431
|
๋๋ก๋ `pass`๊ฐ ์๋๋ผ, ๋ค๋ฅธ ๋ผ์ฐํฐ๋ฅผ ํธ์ถํ ๊ฒฐ๊ณผ๋ฅผ ์ป๊ณ ์ถ์ ๋๋
|
1431
1432
|
์์ต๋๋ค. ์ด๋ด๋๋ ๊ฐ๋จํ๊ฒ `call`์ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
|
1432
1433
|
|
1433
|
-
```
|
1434
|
+
```ruby
|
1434
1435
|
get '/foo' do
|
1435
1436
|
status, headers, body = call env.merge("PATH_INFO" => '/bar')
|
1436
1437
|
[status, headers, body.map(&:upcase)]
|
@@ -1456,7 +1457,7 @@ end
|
|
1456
1457
|
์ง์ ์์ ์ค์ ํด์ผ ํ ๋๋ ์์ต๋๋ค. ์ด๋ฐ ๊ฒฝ์ฐ `body` ํฌํผ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด
|
1457
1458
|
๋ฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด, ๊ทธ ์๊ฐ๋ถํฐ ๋ณธ๋ฌธ์ ์ ๊ทผํ ๋ ๊ทธ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์๊ฐ ์์ต๋๋ค.
|
1458
1459
|
|
1459
|
-
```
|
1460
|
+
```ruby
|
1460
1461
|
get '/foo' do
|
1461
1462
|
body "bar"
|
1462
1463
|
end
|
@@ -1472,7 +1473,7 @@ end
|
|
1472
1473
|
|
1473
1474
|
๋ณธ๋ฌธ์ ๋ง์ฐฌ๊ฐ์ง๋ก, ์ํ์ฝ๋์ ํค๋๋ ์ค์ ํ ์ ์์ต๋๋ค.
|
1474
1475
|
|
1475
|
-
```
|
1476
|
+
```ruby
|
1476
1477
|
get '/foo' do
|
1477
1478
|
status 418
|
1478
1479
|
headers \
|
@@ -1492,7 +1493,7 @@ end
|
|
1492
1493
|
๊ณ์ ๋ฐ์ดํฐ๋ฅผ ๋ด๋ณด๋ด๊ณ ์ถ์ ๊ฒฝ์ฐ๋ ์์ฃ . ์ฌ๋ฌ๋ถ๋ง์ ๋ํผ(wrapper)๋ฅผ
|
1493
1494
|
๋ง๋ค์ง ์์ผ๋ ค๋ฉด `stream` ํฌํผ๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
|
1494
1495
|
|
1495
|
-
```
|
1496
|
+
```ruby
|
1496
1497
|
get '/' do
|
1497
1498
|
stream do |out|
|
1498
1499
|
out << "It's gonna be legen -\n"
|
@@ -1505,23 +1506,23 @@ end
|
|
1505
1506
|
```
|
1506
1507
|
|
1507
1508
|
์ด๋ ๊ฒ ์คํธ๋ฆฌ๋ฐ API๋ [์๋ฒ ๋ฐ์ก ์ด๋ฒคํธServer Sent
|
1508
|
-
Events](
|
1509
|
-
[WebSockets](
|
1509
|
+
Events](https://w3c.github.io/eventsource/)๋ฅผ ๊ตฌํํ ์ ์๊ณ , ์ด ๋ฐฉ๋ฒ์
|
1510
|
+
[WebSockets](https://en.wikipedia.org/wiki/WebSocket)์ ์ํ ๊ธฐ๋ฐ์ผ๋ก ์ฌ์ฉ๋ฉ๋๋ค.
|
1510
1511
|
์ด ๋ฐฉ๋ฒ์ ์ผ๋ถ ์ฝํ
์ธ ๊ฐ ๋๋ฆฐ ์์์ ์์กดํ๋ ๊ฒฝ์ฐ์ ์ค๋กํ(throughtput)์
|
1511
1512
|
๋์ด๊ธฐ ์ํด ์ฌ์ฉ๋๊ธฐ๋ ํฉ๋๋ค.
|
1512
1513
|
|
1513
1514
|
์คํธ๋ฆฌ๋ฐ ๋์, ํนํ ๋์ ์์ฒญ์ ์๋ ์ ํ๋ฆฌ์ผ์ด์
์ ์๋นํ๋ ์น์๋ฒ์ ํฌ๊ฒ
|
1514
|
-
์์กดํฉ๋๋ค.
|
1515
|
-
|
1516
|
-
|
1517
|
-
|
1515
|
+
์์กดํฉ๋๋ค. ์ผ๋ถ์ ๊ฒฝ์ฐ ์์ ์คํธ๋ฆฌ๋ฐ์ ์ง์ํ์ง ์กฐ์ฐจ ์์ต๋๋ค. ๋ง์ฝ ์๋ฒ๊ฐ
|
1516
|
+
์คํธ๋ฆฌ๋ฐ์ ์ง์ํ์ง ์๋๋ค๋ฉด, ๋ณธ๋ฌธ์ `stream` ์ผ๋ก ์ ๋ฌ๋ ๋ธ๋ก์ด ์ํ์ ๋ง์น
|
1517
|
+
ํ์ ํ๊บผ๋ฒ์ ๋ฐํ๋ฉ๋๋ค. ์ด๋ฐ ํ๋ฒ์ ์๋ ์ท๊ฑด๊ฐ์ ๋ฐฉ์์ผ๋ก๋ ์คํธ๋ฆฌ๋ฐ์
|
1518
|
+
์์ง์ด์ง ์์ต๋๋ค.
|
1518
1519
|
|
1519
1520
|
์ ํ์ ๋งค๊ฐ๋ณ์ `keep_open`์ด ์ค์ ๋์ด ์๋ค๋ฉด, ์คํธ๋ฆผ ๊ฐ์ฒด์์ `close`๋ฅผ
|
1520
1521
|
ํธ์ถํ์ง ์์ ๊ฒ์ด๊ณ , ๋์ค์ ์คํ ํ๋ฆ ์์ ์ด๋ ์์ ์์ ์คํธ๋ฆผ์ ๋ซ์ ์
|
1521
1522
|
์์ต๋๋ค. ์ด ์ต์
์ Thin๊ณผ Rainbow ๊ฐ์ ์ด๋ฒคํธ ๊ธฐ๋ฐ ์๋ฒ์์๋ง ์๋ํ๊ณ
|
1522
1523
|
๋ค๋ฅธ ์๋ฒ๋ค์ ์ฌ์ ํ ์คํธ๋ฆผ์ ๋ซ์ต๋๋ค.
|
1523
1524
|
|
1524
|
-
```
|
1525
|
+
```ruby
|
1525
1526
|
# long polling
|
1526
1527
|
|
1527
1528
|
set :server, :thin
|
@@ -1555,7 +1556,7 @@ end
|
|
1555
1556
|
์์ฒญ ์ค์ฝํ(request scope) ๋ด์์, `Logger`์ ์ธ์คํด์ค์ธ `logger`
|
1556
1557
|
ํฌํผ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
|
1557
1558
|
|
1558
|
-
```
|
1559
|
+
```ruby
|
1559
1560
|
get '/' do
|
1560
1561
|
logger.info "loading data"
|
1561
1562
|
# ...
|
@@ -1569,7 +1570,7 @@ end
|
|
1569
1570
|
๋ก๊น
์ `Sinatra::Application`์์๋ง ๊ธฐ๋ณธ์ผ๋ก ํ์ฑํ๋์ด ์์์ ์ ์ํฉ์๋ค.
|
1570
1571
|
๋ง์ฝ `Sinatra::Base`๋ก๋ถํฐ ์์๋ฐ์ ๊ฒฝ์ฐ๋ผ๋ฉด ์ง์ ํ์ฑํ์์ผ ์ค์ผ ํฉ๋๋ค.
|
1571
1572
|
|
1572
|
-
```
|
1573
|
+
```ruby
|
1573
1574
|
class MyApp < Sinatra::Base
|
1574
1575
|
configure :production, :development do
|
1575
1576
|
enable :logging
|
@@ -1588,7 +1589,7 @@ Sinatra๋ `env['rack.logger']`์์ ์ฐพ์ ๋ก๊ฑฐ๋ฅผ ์ฌ์ฉํ ๊ฒ์
๋๋ค.
|
|
1588
1589
|
๋ง์ ํ์
์ด ์์ ์ ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ `mime_type`์ ์ฌ์ฉํ์ฌ ํ์ผ
|
1589
1590
|
ํ์ฅ์๋ฅผ ๋ฑ๋กํฉ๋๋ค.
|
1590
1591
|
|
1591
|
-
```
|
1592
|
+
```ruby
|
1592
1593
|
configure do
|
1593
1594
|
mime_type :foo, 'text/foo'
|
1594
1595
|
end
|
@@ -1596,7 +1597,7 @@ end
|
|
1596
1597
|
|
1597
1598
|
`content_type` ํฌํผ๋ก ์ธ ์๋ ์์ต๋๋ค.
|
1598
1599
|
|
1599
|
-
```
|
1600
|
+
```ruby
|
1600
1601
|
get '/' do
|
1601
1602
|
content_type :foo
|
1602
1603
|
"foo foo foo"
|
@@ -1608,7 +1609,7 @@ end
|
|
1608
1609
|
URL์ ์์ฑํ ๋ `url` ํฌํผ ๋ฉ์๋๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์๋ฅผ ๋ค์ด Haml์์๋ ์ด๋ ๊ฒ
|
1609
1610
|
ํฉ๋๋ค.
|
1610
1611
|
|
1611
|
-
```
|
1612
|
+
```ruby
|
1612
1613
|
%a{:href => url('/foo')} foo
|
1613
1614
|
```
|
1614
1615
|
|
@@ -1620,7 +1621,7 @@ URL์ ์์ฑํ ๋ `url` ํฌํผ ๋ฉ์๋๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์๋ฅผ ๋ค์ด Ham
|
|
1620
1621
|
|
1621
1622
|
`redirect` ํฌํผ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ๋ธ๋ผ์ฐ์ ๋ฅผ ๋ฆฌ๋ค์ด๋ ํธ ์ํฌ ์ ์์ต๋๋ค.
|
1622
1623
|
|
1623
|
-
```
|
1624
|
+
```ruby
|
1624
1625
|
get '/foo' do
|
1625
1626
|
redirect to('/bar')
|
1626
1627
|
end
|
@@ -1628,15 +1629,15 @@ end
|
|
1628
1629
|
|
1629
1630
|
๋ค๋ฅธ ๋ถ๊ฐ์ ์ธ ๋งค๊ฐ๋ณ์๋ค์ `halt`์ ์ ๋ฌํ๋ ์ธ์๋ค๊ณผ ๋น์ทํฉ๋๋ค.
|
1630
1631
|
|
1631
|
-
```
|
1632
|
+
```ruby
|
1632
1633
|
redirect to('/bar'), 303
|
1633
|
-
redirect 'http://google.com', 'wrong place, buddy'
|
1634
|
+
redirect 'http://www.google.com/', 'wrong place, buddy'
|
1634
1635
|
```
|
1635
1636
|
|
1636
1637
|
`redirect back`์ ์ฌ์ฉํ๋ฉด ์ฝ๊ฒ ์ฌ์ฉ์๊ฐ ์๋ ํ์ด์ง๋ก ๋ค์ ๋์๊ฐ๊ฒ
|
1637
1638
|
ํ ์ ์์ต๋๋ค.
|
1638
1639
|
|
1639
|
-
```
|
1640
|
+
```ruby
|
1640
1641
|
get '/foo' do
|
1641
1642
|
"<a href='/bar'>do something</a>"
|
1642
1643
|
end
|
@@ -1649,13 +1650,13 @@ end
|
|
1649
1650
|
|
1650
1651
|
๋ฆฌ๋ค์ด๋ ํธ์ ํจ๊ป ์ธ์๋ฅผ ์ ๋ฌํ๋ ค๋ฉด, ์ฟผ๋ฆฌ๋ก ๋ถ์ด๊ฑฐ๋,
|
1651
1652
|
|
1652
|
-
```
|
1653
|
+
```ruby
|
1653
1654
|
redirect to('/bar?sum=42')
|
1654
1655
|
```
|
1655
1656
|
|
1656
1657
|
์ธ์
์ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
|
1657
1658
|
|
1658
|
-
```
|
1659
|
+
```ruby
|
1659
1660
|
enable :sessions
|
1660
1661
|
|
1661
1662
|
get '/foo' do
|
@@ -1674,7 +1675,7 @@ end
|
|
1674
1675
|
|
1675
1676
|
Cache-Control ํค๋๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ๊ฐ๋จํ๊ฒ ์ค์ ํ ์ ์์ต๋๋ค.
|
1676
1677
|
|
1677
|
-
```
|
1678
|
+
```ruby
|
1678
1679
|
get '/' do
|
1679
1680
|
cache_control :public
|
1680
1681
|
"cache it!"
|
@@ -1683,7 +1684,7 @@ end
|
|
1683
1684
|
|
1684
1685
|
ํ๋ก ํ: ์บ์ฑ์ ์ฌ์ ํํฐ์์ ์ค์ ํ์ธ์.
|
1685
1686
|
|
1686
|
-
```
|
1687
|
+
```ruby
|
1687
1688
|
before do
|
1688
1689
|
cache_control :public, :must_revalidate, :max_age => 60
|
1689
1690
|
end
|
@@ -1692,7 +1693,7 @@ end
|
|
1692
1693
|
`expires` ํฌํผ๋ฅผ ์ฌ์ฉํ์ฌ ๊ทธ์ ์์ํ๋ ํค๋๋ฅผ ์ค์ ํ๋ค๋ฉด,
|
1693
1694
|
`Cache-Control`์ด ์๋์ผ๋ก ์ค์ ๋ฉ๋๋ค.
|
1694
1695
|
|
1695
|
-
```
|
1696
|
+
```ruby
|
1696
1697
|
before do
|
1697
1698
|
expires 500, :public, :must_revalidate
|
1698
1699
|
end
|
@@ -1703,7 +1704,7 @@ end
|
|
1703
1704
|
ํด๋ผ์ด์ธํธ ์บ์์ ํ์ฌ ๋ฒ์ ์ด ์ด๋ฏธ ๋ค์ด ์์ ๊ฒฝ์ฐ์ ์ฆ๊ฐ ์๋ต์
|
1704
1705
|
๋ฟ๋ฆด(flush) ๊ฒ์
๋๋ค.
|
1705
1706
|
|
1706
|
-
```
|
1707
|
+
```ruby
|
1707
1708
|
get "/article/:id" do
|
1708
1709
|
@article = Article.find params['id']
|
1709
1710
|
last_modified @article.updated_at
|
@@ -1712,10 +1713,10 @@ get "/article/:id" do
|
|
1712
1713
|
end
|
1713
1714
|
```
|
1714
1715
|
|
1715
|
-
[์ฝํ ETag](
|
1716
|
+
[์ฝํ ETag](https://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation)๋ฅผ
|
1716
1717
|
์ฌ์ฉํ ์ ๋ ์์ต๋๋ค.
|
1717
1718
|
|
1718
|
-
```
|
1719
|
+
```ruby
|
1719
1720
|
etag @article.sha1, :weak
|
1720
1721
|
```
|
1721
1722
|
|
@@ -1723,7 +1724,7 @@ etag @article.sha1, :weak
|
|
1723
1724
|
์์ฌ์ด ๋ฆฌ๋ฒ์ค ํ๋ก์(reverse-proxy) ์บ์ฑ ์๋ฃจ์
์ ์ฐพ๊ณ ์๋ค๋ฉด,
|
1724
1725
|
[rack-cache](https://github.com/rtomayko/rack-cache)๋ฅผ ์จ๋ณด์ธ์.
|
1725
1726
|
|
1726
|
-
```
|
1727
|
+
```ruby
|
1727
1728
|
require "rack/cache"
|
1728
1729
|
require "sinatra"
|
1729
1730
|
|
@@ -1745,7 +1746,7 @@ RFC 2616์ ๋ฐ๋ฅด๋ฉด If-Match ๋๋ If-None-Match ํค๋๊ฐ `*`๋ก ์ค์ ๋
|
|
1745
1746
|
์ด๋ฏธ ์กด์ฌํ๋ค๊ณ ๊ฐ์ ํ์ง๋ง, ๋ค๋ฅธ ๋ฆฌ์์ค(์๋ฅผ ๋ค๋ฉด post ์์ฒญ ๊ฐ์)์ ๊ฒฝ์ฐ๋
|
1746
1747
|
์ ๋ฆฌ์์ค๋ก ์ทจ๊ธํฉ๋๋ค. ์ด ํ๋์ `:new_resource` ์ต์
์ ์ ๋ฌํ์ฌ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
|
1747
1748
|
|
1748
|
-
```
|
1749
|
+
```ruby
|
1749
1750
|
get '/create' do
|
1750
1751
|
etag '', :new_resource => true
|
1751
1752
|
Article.create
|
@@ -1755,7 +1756,7 @@ end
|
|
1755
1756
|
|
1756
1757
|
์ฝํ ETag๋ฅผ ์ฌ์ฉํ๊ณ ์ ํ๋ค๋ฉด, `:kind`์ผ๋ก ์ ๋ฌํฉ์๋ค.
|
1757
1758
|
|
1758
|
-
```
|
1759
|
+
```ruby
|
1759
1760
|
etag '', :new_resource => true, :kind => :weak
|
1760
1761
|
```
|
1761
1762
|
|
@@ -1763,7 +1764,7 @@ etag '', :new_resource => true, :kind => :weak
|
|
1763
1764
|
|
1764
1765
|
์๋ต(response)์ผ๋ก ํ์ผ์ ์ปจํ ์ธ ๋ฅผ ๋ฆฌํดํ๋ ค๋ฉด, `send_file` ํฌํผ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
|
1765
1766
|
|
1766
|
-
```
|
1767
|
+
```ruby
|
1767
1768
|
get '/' do
|
1768
1769
|
send_file 'foo.png'
|
1769
1770
|
end
|
@@ -1771,7 +1772,7 @@ end
|
|
1771
1772
|
|
1772
1773
|
์ด ๋ฉ์๋๋ ๋ช ๊ฐ์ง ์ต์
์ ๋ฐ์ต๋๋ค.
|
1773
1774
|
|
1774
|
-
```
|
1775
|
+
```ruby
|
1775
1776
|
send_file 'foo.png', :type => :jpg
|
1776
1777
|
```
|
1777
1778
|
|
@@ -1812,7 +1813,7 @@ send_file 'foo.png', :type => :jpg
|
|
1812
1813
|
๋ค์ด์ค๋ ์์ฒญ ๊ฐ์๋ ์์ฒญ ๋ ๋ฒจ(ํํฐ, ๋ผ์ฐํฐ, ์ค๋ฅ ํธ๋ค๋ฌ)์์ `request`
|
1813
1814
|
๋ฉ์๋๋ฅผ ํตํด ์ ๊ทผ ๊ฐ๋ฅํฉ๋๋ค.
|
1814
1815
|
|
1815
|
-
```
|
1816
|
+
```ruby
|
1816
1817
|
# http://example.com/example ์์์ ์คํ ์ค์ธ ์ฑ
|
1817
1818
|
get '/foo' do
|
1818
1819
|
t = %w[text/css text/html application/javascript]
|
@@ -1847,7 +1848,7 @@ end
|
|
1847
1848
|
|
1848
1849
|
`script_name`, `path_info`๊ฐ์ ์ผ๋ถ ์ต์
๋ค์ ์ด๋ ๊ฒ ์ธ ์๋ ์์ต๋๋ค.
|
1849
1850
|
|
1850
|
-
```
|
1851
|
+
```ruby
|
1851
1852
|
before { request.path_info = "/" }
|
1852
1853
|
|
1853
1854
|
get "/" do
|
@@ -1857,7 +1858,7 @@ end
|
|
1857
1858
|
|
1858
1859
|
`request.body`๋ IO ๊ฐ์ฒด์ด๊ฑฐ๋ StringIO ๊ฐ์ฒด์
๋๋ค.
|
1859
1860
|
|
1860
|
-
```
|
1861
|
+
```ruby
|
1861
1862
|
post "/api" do
|
1862
1863
|
request.body.rewind # ๋๊ตฐ๊ฐ ์ด๋ฏธ ์ฝ์ ๊ฒฝ์ฐ
|
1863
1864
|
data = JSON.parse request.body.read
|
@@ -1870,7 +1871,7 @@ end
|
|
1870
1871
|
`attachment` ํฌํผ๋ฅผ ์ฌ์ฉํ์ฌ ์๋ต์ด ๋ธ๋ผ์ฐ์ ์ ํ์ํ๋ ๋์
|
1871
1872
|
๋์คํฌ์ ์ ์ฅ๋์ด์ผ ํจ์ ๋ธ๋ผ์ฐ์ ์๊ฒ ์๋ฆด ์ ์์ต๋๋ค.
|
1872
1873
|
|
1873
|
-
```
|
1874
|
+
```ruby
|
1874
1875
|
get '/' do
|
1875
1876
|
attachment
|
1876
1877
|
"store it!"
|
@@ -1879,7 +1880,7 @@ end
|
|
1879
1880
|
|
1880
1881
|
ํ์ผ๋ช
์ ์ ๋ฌํ ์๋ ์์ต๋๋ค.
|
1881
1882
|
|
1882
|
-
```
|
1883
|
+
```ruby
|
1883
1884
|
get '/' do
|
1884
1885
|
attachment "info.txt"
|
1885
1886
|
"store it!"
|
@@ -1892,7 +1893,7 @@ Sinatra๋ `time_for_` ํฌํผ ๋ฉ์๋๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ด ๋ฉ์๋๋
|
|
1892
1893
|
์ฃผ์ด์ง ๊ฐ์ผ๋ก๋ถํฐ Time ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค. `DateTime`, `Date` ๊ฐ์
|
1893
1894
|
๋น์ทํ ํด๋์ค๋ค๋ ๋ณํ๋ฉ๋๋ค.
|
1894
1895
|
|
1895
|
-
```
|
1896
|
+
```ruby
|
1896
1897
|
get '/' do
|
1897
1898
|
pass if Time.now > time_for('Dec 23, 2012')
|
1898
1899
|
"still time"
|
@@ -1903,7 +1904,7 @@ end
|
|
1903
1904
|
๋ฐ๋ผ์ ์ฌ๋ฌ๋ถ์ ์ ํ๋ฆฌ์ผ์ด์
์์ `time_for`๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉํ์ฌ ์ด๋ค ๋ฉ์๋์
|
1904
1905
|
๋์์ ์ฝ๊ฒ ํ์ฅํ ์ ์์ต๋๋ค.
|
1905
1906
|
|
1906
|
-
```
|
1907
|
+
```ruby
|
1907
1908
|
helpers do
|
1908
1909
|
def time_for(value)
|
1909
1910
|
case value
|
@@ -1925,7 +1926,7 @@ end
|
|
1925
1926
|
|
1926
1927
|
`find_template`๋ ๋ ๋๋งํ ํ
ํ๋ฆฟ ํ์ผ์ ์ฐพ๋๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
|
1927
1928
|
|
1928
|
-
```
|
1929
|
+
```ruby
|
1929
1930
|
find_template settings.views, 'foo', Tilt[:haml] do |file|
|
1930
1931
|
puts "could be #{file}"
|
1931
1932
|
end
|
@@ -1935,7 +1936,7 @@ end
|
|
1935
1936
|
์ฐธ์กฐ ๋ฉ์ปค๋์ฆ์์ ๊ฐ๋ก์ฑ๊ฒ ํ๋ฉด ์ ์ฉํด์ง๋๋ค. ์๋ฅผ ๋ค์ด, ํ๋ ์ด์์ ๋ทฐ ๋๋ ํฐ๋ฆฌ๋ฅผ
|
1936
1937
|
์ฌ์ฉํ๊ณ ์ ํ๋ค๋ฉด ์ด๋ ๊ฒ ํ์ธ์.
|
1937
1938
|
|
1938
|
-
```
|
1939
|
+
```ruby
|
1939
1940
|
set :views, ['views', 'templates']
|
1940
1941
|
|
1941
1942
|
helpers do
|
@@ -1947,7 +1948,7 @@ end
|
|
1947
1948
|
|
1948
1949
|
๋ค๋ฅธ ์์ ๋ ๊ฐ ์์ง๋ง๋ค ๋ค๋ฅธ ๋๋ ํฐ๋ฆฌ๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ์
๋๋ค.
|
1949
1950
|
|
1950
|
-
```
|
1951
|
+
```ruby
|
1951
1952
|
set :views, :sass => 'views/sass', :haml => 'templates', :default => 'views'
|
1952
1953
|
|
1953
1954
|
helpers do
|
@@ -1971,7 +1972,7 @@ end
|
|
1971
1972
|
|
1972
1973
|
๋ชจ๋ ํ๊ฒฝ์์, ์์๋ ๋, ํ๋ฒ๋ง ์คํ๋๊ฒ ํ๋ ค๋ฉด ์ด๋ ๊ฒ ํ๋ฉด ๋ฉ๋๋ค.
|
1973
1974
|
|
1974
|
-
```
|
1975
|
+
```ruby
|
1975
1976
|
configure do
|
1976
1977
|
# ์ต์
ํ๋ ์ค์
|
1977
1978
|
set :option, 'value'
|
@@ -1990,9 +1991,9 @@ configure do
|
|
1990
1991
|
end
|
1991
1992
|
```
|
1992
1993
|
|
1993
|
-
ํ๊ฒฝ(
|
1994
|
+
ํ๊ฒฝ(APP_ENV ํ๊ฒฝ ๋ณ์)์ด `:production`์ผ ๋๋ง ์คํ๋๊ฒ ํ๋ ค๋ฉด ์ด๋ ๊ฒ ํ๋ฉด ๋ฉ๋๋ค.
|
1994
1995
|
|
1995
|
-
```
|
1996
|
+
```ruby
|
1996
1997
|
configure :production do
|
1997
1998
|
...
|
1998
1999
|
end
|
@@ -2000,7 +2001,7 @@ end
|
|
2000
2001
|
|
2001
2002
|
ํ๊ฒฝ์ด `:production` ๋๋ `:test`์ผ ๋ ์คํ๋๊ฒ ํ๋ ค๋ฉด ์ด๋ ๊ฒ ํ๋ฉด ๋ฉ๋๋ค.
|
2002
2003
|
|
2003
|
-
```
|
2004
|
+
```ruby
|
2004
2005
|
configure :production, :test do
|
2005
2006
|
...
|
2006
2007
|
end
|
@@ -2008,7 +2009,7 @@ end
|
|
2008
2009
|
|
2009
2010
|
์ด ์ต์
๋ค์ `settings`๋ฅผ ํตํด ์ ๊ทผ ๊ฐ๋ฅํฉ๋๋ค.
|
2010
2011
|
|
2011
|
-
```
|
2012
|
+
```ruby
|
2012
2013
|
configure do
|
2013
2014
|
set :foo, 'bar'
|
2014
2015
|
end
|
@@ -2022,23 +2023,23 @@ end
|
|
2022
2023
|
|
2023
2024
|
### ๊ณต๊ฒฉ ๋ฐฉ์ด ์ค์ ํ๊ธฐ(Configuring attack protection)
|
2024
2025
|
|
2025
|
-
Sinatra๋ [Rack::Protection](https://github.com/
|
2026
|
+
Sinatra๋ [Rack::Protection](https://github.com/sinatra/rack-protection#readme)์ ์ฌ์ฉํ์ฌ
|
2026
2027
|
์ผ๋ฐ์ ์ด๊ณ ์ผ์ด๋ ์ ์๋ ๊ณต๊ฒฉ์ ๋๋นํฉ๋๋ค. ์ด ๋ชจ๋์ ๊ฐ๋จํ๊ฒ ๋นํ์ฑ์ํฌ ์ ์์ต๋๋ค.
|
2027
2028
|
(ํ์ง๋ง ์ ํ๋ฆฌ์ผ์ด์
์ ์์ฒญ๋๊ฒ ๋ง์ ์ทจ์ฝ์ฑ์ ์ผ๊ธฐํฉ๋๋ค.)
|
2028
2029
|
|
2029
|
-
```
|
2030
|
+
```ruby
|
2030
2031
|
disable :protection
|
2031
2032
|
```
|
2032
2033
|
|
2033
2034
|
ํ๋์ ๋ฐฉ์ด์ธต๋ง ์คํตํ๋ ค๋ฉด, ์ต์
ํด์์ `protection`์ ์ค์ ํ๋ฉด ๋ฉ๋๋ค.
|
2034
2035
|
|
2035
|
-
```
|
2036
|
+
```ruby
|
2036
2037
|
set :protection, :except => :path_traversal
|
2037
2038
|
```
|
2038
2039
|
|
2039
2040
|
๋ฐฐ์ด๋ก ๋๊น์ผ๋ก์จ ๋ฐฉ์ด์ธต ์ฌ๋ฌ ๊ฐ๋ฅผ ๋นํ์ฑํํ ์ ์์ต๋๋ค.
|
2040
2041
|
|
2041
|
-
```
|
2042
|
+
```ruby
|
2042
2043
|
set :protection, :except => [:path_traversal, :session_hijacking]
|
2043
2044
|
```
|
2044
2045
|
|
@@ -2046,7 +2047,7 @@ set :protection, :except => [:path_traversal, :session_hijacking]
|
|
2046
2047
|
๋๋ก๋ ์์ ๋ง์ ์ธ์
์ ์ค์ ํ ๋๋ ์์ต๋๋ค. ์ด๋ฐ ๊ฒฝ์ฐ `:session` ์ต์
์
|
2047
2048
|
๋๊ฒจ์ค์ผ๋ก์จ ์ธ์
์ ๊ธฐ๋ฐ์ผ๋กํ ๋ฐฉ์ด์ธต์ ์ค์ ํ ์ ์์ต๋๋ค.
|
2048
2049
|
|
2049
|
-
```
|
2050
|
+
```ruby
|
2050
2051
|
use Rack::Session::Pool
|
2051
2052
|
set :protection, :session => true
|
2052
2053
|
```
|
@@ -2093,7 +2094,7 @@ set :protection, :session => true
|
|
2093
2094
|
|
2094
2095
|
<dt>environment</dt>
|
2095
2096
|
<dd>
|
2096
|
-
ํ์ฌ ํ๊ฒฝ, ๊ธฐ๋ณธ๊ฐ์ <tt>ENV['
|
2097
|
+
ํ์ฌ ํ๊ฒฝ, ๊ธฐ๋ณธ๊ฐ์ <tt>ENV['APP_ENV']</tt> ENV์ ์์ ๊ฒฝ์ฐ์ "development".
|
2097
2098
|
</dd>
|
2098
2099
|
|
2099
2100
|
<dt>logging</dt>
|
@@ -2224,22 +2225,22 @@ set :protection, :session => true
|
|
2224
2225
|
## ํ๊ฒฝ(Environments)
|
2225
2226
|
|
2226
2227
|
3๊ฐ์ง์ ๋ฏธ๋ฆฌ ์ ์๋ `environments` `"development"`, `"production"`, `"test"`
|
2227
|
-
๊ฐ ์์ต๋๋ค. ํ๊ฒฝ์ `
|
2228
|
+
๊ฐ ์์ต๋๋ค. ํ๊ฒฝ์ `APP_ENV` ํ๊ฒฝ ๋ณ์๋ฅผ ํตํด์๋ ์ค์ ๋ฉ๋๋ค. ๊ธฐ๋ณธ๊ฐ์
|
2228
2229
|
`"development"`์
๋๋ค. `"development"` ๋ชจ๋์์๋ ๋ชจ๋ ํ
ํ๋ฆฟ๋ค์ ์์ฒญ ๊ฐ์
|
2229
2230
|
๋ฆฌ๋ก๋๋ฉ๋๋ค. ๋, `"development"` ๋ชจ๋์์๋ ํน๋ณํ `not_found` ์ `error`
|
2230
2231
|
ํธ๋ค๋ฌ๊ฐ ๋ธ๋ผ์ฐ์ ์์ ์คํ ํธ๋ ์ด์ค๋ฅผ ๋ณผ ์ ์๊ฒํฉ๋๋ค.
|
2231
2232
|
`"production"`๊ณผ `"test"`์์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ํ
ํ๋ฆฟ์ ์บ์๋ฉ๋๋ค.
|
2232
2233
|
|
2233
|
-
๋ค๋ฅธ ํ๊ฒฝ์ผ๋ก ์คํ์ํค๋ ค๋ฉด `
|
2234
|
+
๋ค๋ฅธ ํ๊ฒฝ์ผ๋ก ์คํ์ํค๋ ค๋ฉด `APP_ENV` ํ๊ฒฝ ๋ณ์๋ฅผ ์ฌ์ฉํ์ธ์.
|
2234
2235
|
|
2235
|
-
```
|
2236
|
-
|
2236
|
+
```shell
|
2237
|
+
APP_ENV=production ruby my_app.rb
|
2237
2238
|
```
|
2238
2239
|
|
2239
2240
|
ํ์ฌ ์ค์ ๋ ํ๊ฒฝ์ด ๋ฌด์์ธ์ง ๊ฒ์ฌํ๊ธฐ ์ํด์๋ ์ค๋น๋ `development?`, `test?`,
|
2240
2241
|
`production?` ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
|
2241
2242
|
|
2242
|
-
```
|
2243
|
+
```ruby
|
2243
2244
|
get '/' do
|
2244
2245
|
if settings.development?
|
2245
2246
|
"development!"
|
@@ -2260,7 +2261,7 @@ end
|
|
2260
2261
|
`Sinatra::NotFound` ์์ธ๊ฐ ๋ฐ์ํ๊ฑฐ๋ ๋๋ ์๋ต์ ์ํ ์ฝ๋๊ฐ 404๋ผ๋ฉด,
|
2261
2262
|
`not_found` ํธ๋ค๋ฌ๊ฐ ํธ์ถ๋ฉ๋๋ค.
|
2262
2263
|
|
2263
|
-
```
|
2264
|
+
```ruby
|
2264
2265
|
not_found do
|
2265
2266
|
'์๋ฌด ๊ณณ์๋ ์ฐพ์ ์ ์์ต๋๋ค.'
|
2266
2267
|
end
|
@@ -2272,13 +2273,13 @@ end
|
|
2272
2273
|
ํ์ง๋ง ๊ฐ๋ฐ ํ๊ฒฝ์์๋ ์์ธ ํ์ธ ์ต์
์ `:after_handler`๋ก ์ค์ ๋์ด ์์ ๊ฒฝ์ฐ์๋ง
|
2273
2274
|
์คํ๋จ์ ์ฃผ์ํ์ธ์.
|
2274
2275
|
|
2275
|
-
```
|
2276
|
+
```ruby
|
2276
2277
|
set :show_exceptions, :after_handler
|
2277
2278
|
```
|
2278
2279
|
|
2279
2280
|
์์ธ ๊ฐ์ฒด๋ Rack ๋ณ์ `sinatra.error`๋ก๋ถํฐ ์ป์ ์ ์์ต๋๋ค.
|
2280
2281
|
|
2281
|
-
```
|
2282
|
+
```ruby
|
2282
2283
|
error do
|
2283
2284
|
'๊ณ ์ฝํ ์ค๋ฅ๊ฐ ๋ฐ์ํ๊ตฐ์ - ' + env['sinatra.error'].message
|
2284
2285
|
end
|
@@ -2286,7 +2287,7 @@ end
|
|
2286
2287
|
|
2287
2288
|
์ฌ์ฉ์ ์ ์ ์ค๋ฅ๋ ์ด๋ ๊ฒ ์ ์ํฉ๋๋ค.
|
2288
2289
|
|
2289
|
-
```
|
2290
|
+
```ruby
|
2290
2291
|
error MyCustomError do
|
2291
2292
|
'๋ฌด์จ ์ผ์ด ์๊ฒผ๋๋ฉด์...' + env['sinatra.error'].message
|
2292
2293
|
end
|
@@ -2294,7 +2295,7 @@ end
|
|
2294
2295
|
|
2295
2296
|
๊ทธ๋ฐ ๋ค์, ์ด ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด ์ด๋ ๊ฒ ์ฒ๋ฆฌํฉ๋๋ค.
|
2296
2297
|
|
2297
|
-
```
|
2298
|
+
```ruby
|
2298
2299
|
get '/' do
|
2299
2300
|
raise MyCustomError, '์์ข์ ์ผ'
|
2300
2301
|
end
|
@@ -2308,7 +2309,7 @@ end
|
|
2308
2309
|
|
2309
2310
|
์ํ ์ฝ๋์ ๋ํด ์ค๋ฅ ํธ๋ค๋ฌ๋ฅผ ์ค์นํ ์๋ ์์ต๋๋ค.
|
2310
2311
|
|
2311
|
-
```
|
2312
|
+
```ruby
|
2312
2313
|
error 403 do
|
2313
2314
|
'์ก์ธ์ค๊ฐ ๊ธ์ง๋จ'
|
2314
2315
|
end
|
@@ -2320,7 +2321,7 @@ end
|
|
2320
2321
|
|
2321
2322
|
๋ฒ์๋ก ์ง์ ํ ์๋ ์์ต๋๋ค.
|
2322
2323
|
|
2323
|
-
```
|
2324
|
+
```ruby
|
2324
2325
|
error 400..510 do
|
2325
2326
|
'์ด์ด์ฟ '
|
2326
2327
|
end
|
@@ -2340,7 +2341,7 @@ Sinatra๋ [Rack](http://rack.github.io/) ์์์ ๋์ํ๋ฉฐ, Rack์ ๋ฃจ๋น
|
|
2340
2341
|
Sinatra๋ ํฑ๋ ๋ฒจ์ `use` ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ Rack ๋ฏธ๋ค์จ์ด์ ํ์ดํ๋ผ์ธ์ ๋ง๋๋ ์ผ์
|
2341
2342
|
์์ ์ฃฝ ๋จน๊ธฐ๋ก ๋ง๋ญ๋๋ค.
|
2342
2343
|
|
2343
|
-
```
|
2344
|
+
```ruby
|
2344
2345
|
require 'sinatra'
|
2345
2346
|
require 'my_custom_middleware'
|
2346
2347
|
|
@@ -2352,11 +2353,11 @@ get '/hello' do
|
|
2352
2353
|
end
|
2353
2354
|
```
|
2354
2355
|
|
2355
|
-
`use`๋ฌธ๋ฒ์ [Rack::Builder](http://rubydoc.info/github/rack/rack/master/Rack/Builder) DSL
|
2356
|
+
`use`๋ฌธ๋ฒ์ [Rack::Builder](http://www.rubydoc.info/github/rack/rack/master/Rack/Builder) DSL
|
2356
2357
|
(rackup ํ์ผ์์ ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉ)์์ ์ ์ํ ๊ฒ๊ณผ ๋์ผํฉ๋๋ค. ์๋ฅผ ๋ค์ด, `use` ๋ฉ์๋๋
|
2357
2358
|
๋ธ๋ก์ด๋ ์ฌ๋ฌ ๊ฐ์/๊ฐ๋ณ์ ์ธ ์ธ์๋ ๋ฐ์ ์ ์์ต๋๋ค.
|
2358
2359
|
|
2359
|
-
```
|
2360
|
+
```ruby
|
2360
2361
|
use Rack::Auth::Basic do |username, password|
|
2361
2362
|
username == 'admin' && password == 'secret'
|
2362
2363
|
end
|
@@ -2375,9 +2376,9 @@ Rack์ ๋ก๊น
, ๋๋ฒ๊น
, URL ๋ผ์ฐํ
, ์ธ์ฆ, ๊ทธ๋ฆฌ๊ณ ์ธ์ผ ํธ๋ค๋ง์
|
|
2375
2376
|
## ํ
์คํ
(Testing)
|
2376
2377
|
|
2377
2378
|
Sinatra ํ
์คํธ๋ ๋ง์ Rack ๊ธฐ๋ฐ ํ
์คํ
๋ผ์ด๋ธ๋ฌ๋ฆฌ, ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํ์ฌ ์์ฑ๊ฐ๋ฅํฉ๋๋ค.
|
2378
|
-
๊ทธ ์ค [Rack::Test](http://
|
2379
|
+
๊ทธ ์ค [Rack::Test](http://www.rubydoc.info/github/brynary/rack-test/master/frames)๋ฅผ ๊ถ์ฅํฉ๋๋ค.
|
2379
2380
|
|
2380
|
-
```
|
2381
|
+
```ruby
|
2381
2382
|
require 'my_sinatra_app'
|
2382
2383
|
require 'minitest/autorun'
|
2383
2384
|
require 'rack/test'
|
@@ -2399,7 +2400,7 @@ class MyAppTest < Minitest::Test
|
|
2399
2400
|
assert_equal 'Hello Frank!', last_response.body
|
2400
2401
|
end
|
2401
2402
|
|
2402
|
-
def
|
2403
|
+
def test_with_user_agent
|
2403
2404
|
get '/', {}, 'HTTP_USER_AGENT' => 'Songbird'
|
2404
2405
|
assert_equal "You're using Songbird!", last_response.body
|
2405
2406
|
end
|
@@ -2418,7 +2419,7 @@ Rack ๋ฏธ๋ค์จ์ด๋, Rails ๋ฉํ(metal) ๋๋ ์๋ฒ ์ปดํฌ๋ํธ๋ฅผ ๊ฐ๋
|
|
2418
2419
|
์
๋๋ค. (์ฆ, ํ๋์ ๋จ์ผ ์ ํ๋ฆฌ์ผ์ด์
ํ์ผ๊ณผ `./public` ๋ฐ `./views` ๋๋ ํฐ๋ฆฌ,
|
2419
2420
|
๋ก๊น
, ์์ธ ์์ธ ํ์ด์ง ๋ฑ๋ฑ). ์ด ๊ณณ์์ `Sinatra::Base`๊ฐ ํ์ํฉ๋๋ค.
|
2420
2421
|
|
2421
|
-
```
|
2422
|
+
```ruby
|
2422
2423
|
require 'sinatra/base'
|
2423
2424
|
|
2424
2425
|
class MyApp < Sinatra::Base
|
@@ -2443,7 +2444,7 @@ end
|
|
2443
2444
|
|
2444
2445
|
`Sinatra::Base`๋ ๋ฐฑ์ง์ํ(blank slate)์
๋๋ค. ๋นํธ์ธ ์๋ฒ๋ฅผ ๋น๋กฏํ ๋๋ถ๋ถ์ ์ต์
๋ค์ด
|
2445
2446
|
๊ธฐ๋ณธ๊ฐ์ผ๋ก ๊บผ์ ธ ์์ต๋๋ค. ๊ฐ๋ฅํ ์ต์
๋ค๊ณผ ๊ทธ ์๋์ ๋ํ ์์ธ๋ [์ต์
๊ณผ
|
2446
|
-
์ค์ ](http://
|
2447
|
+
์ค์ ](http://www.sinatrarb.com/configuration.html)์ ์ฐธ์กฐํ์ธ์.
|
2447
2448
|
|
2448
2449
|
### ๋ชจ๋(Modular) vs. ์ ํต์ ๋ฐฉ์(Classic Style)
|
2449
2450
|
|
@@ -2491,7 +2492,7 @@ end
|
|
2491
2492
|
<tr>
|
2492
2493
|
<td>static</td>
|
2493
2494
|
<td>true</td>
|
2494
|
-
<td>
|
2495
|
+
<td>File.exist?(public_folder)</td>
|
2495
2496
|
</tr>
|
2496
2497
|
</table>
|
2497
2498
|
|
@@ -2500,7 +2501,7 @@ end
|
|
2500
2501
|
๋ชจ๋ ์ฑ์ ์์ํ๋ ๋ ๊ฐ์ง ์ผ๋ฐ์ ์ธ ์ต์
์ด ์์ต๋๋ค.
|
2501
2502
|
`run!`์ผ๋ก ๋ฅ๋์ ์ผ๋ก ์์ํ๋ ๋ฐฉ๋ฒ์ ์ด๋ ์ต๋๋ค.
|
2502
2503
|
|
2503
|
-
```
|
2504
|
+
```ruby
|
2504
2505
|
# my_app.rb
|
2505
2506
|
require 'sinatra/base'
|
2506
2507
|
|
@@ -2514,14 +2515,14 @@ end
|
|
2514
2515
|
|
2515
2516
|
์ด๋ ๊ฒ ์์ํ ์๋ ์์ต๋๋ค.
|
2516
2517
|
|
2517
|
-
```
|
2518
|
+
```shell
|
2518
2519
|
ruby my_app.rb
|
2519
2520
|
```
|
2520
2521
|
|
2521
2522
|
`config.ru`์ ํจ๊ป ์ฌ์ฉํ ์๋ ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ๋ ์ด๋ ํ Rack ํธ๋ค๋ฌ๋ ์ฌ์ฉํ ์ ์๋๋ก
|
2522
2523
|
ํ์ฉ ํฉ๋ค.
|
2523
2524
|
|
2524
|
-
```
|
2525
|
+
```ruby
|
2525
2526
|
# config.ru
|
2526
2527
|
require './my_app'
|
2527
2528
|
run MyApp
|
@@ -2529,7 +2530,7 @@ run MyApp
|
|
2529
2530
|
|
2530
2531
|
์คํ์ ์ด๋ ๊ฒ ํฉ๋๋ค.
|
2531
2532
|
|
2532
|
-
```
|
2533
|
+
```shell
|
2533
2534
|
rackup -p 4567
|
2534
2535
|
```
|
2535
2536
|
|
@@ -2537,7 +2538,7 @@ rackup -p 4567
|
|
2537
2538
|
|
2538
2539
|
์ฑ ํ์ผ์ ๋ค์๊ณผ ๊ฐ์ด ์์ฑํฉ๋๋ค.
|
2539
2540
|
|
2540
|
-
```
|
2541
|
+
```ruby
|
2541
2542
|
# app.rb
|
2542
2543
|
require 'sinatra'
|
2543
2544
|
|
@@ -2548,7 +2549,7 @@ end
|
|
2548
2549
|
|
2549
2550
|
๋์ํ๋ `config.ru`๋ ๋ค์๊ณผ ๊ฐ์ด ์์ฑํฉ๋๋ค.
|
2550
2551
|
|
2551
|
-
```
|
2552
|
+
```ruby
|
2552
2553
|
require './app'
|
2553
2554
|
run Sinatra::Application
|
2554
2555
|
```
|
@@ -2572,7 +2573,7 @@ Sinatra์์ ๋ค๋ฅธ Rack ๋ฏธ๋ค์จ์ด๋ฅผ ์ฌ์ฉํ ์ ์์ ๋ฟ ์๋๋ผ,
|
|
2572
2573
|
๋๋ Rack ๊ธฐ๋ฐ์ ์ด๋ ํ ์ ํ๋ฆฌ์ผ์ด์
(Rails/Ramaze/Camping/...)์ด ๋ ์๋
|
2573
2574
|
์์ต๋๋ค.
|
2574
2575
|
|
2575
|
-
```
|
2576
|
+
```ruby
|
2576
2577
|
require 'sinatra/base'
|
2577
2578
|
|
2578
2579
|
class LoginScreen < Sinatra::Base
|
@@ -2608,7 +2609,7 @@ end
|
|
2608
2609
|
์ด๋ค ์์์ ํ ๋นํ์ง ์๊ณ ๋ฐํ์์์ ์ ์ ํ๋ฆฌ์ผ์ด์
๋ค์ ์์ฑํ๋ ค๋ฉด,
|
2609
2610
|
`Sinatra.new`๋ฅผ ์ฐ๋ฉด ๋ฉ๋๋ค.
|
2610
2611
|
|
2611
|
-
```
|
2612
|
+
```ruby
|
2612
2613
|
require 'sinatra/base'
|
2613
2614
|
my_app = Sinatra.new { get('/') { "hi" } }
|
2614
2615
|
my_app.run!
|
@@ -2616,7 +2617,7 @@ my_app.run!
|
|
2616
2617
|
|
2617
2618
|
์ ํ์ ์ธ์๋ก ์์ํ ์ ํ๋ฆฌ์ผ์ด์
์ ๋ฐ์ ์ ์์ต๋๋ค.
|
2618
2619
|
|
2619
|
-
```
|
2620
|
+
```ruby
|
2620
2621
|
# config.ru
|
2621
2622
|
require 'sinatra/base'
|
2622
2623
|
|
@@ -2639,7 +2640,7 @@ end
|
|
2639
2640
|
|
2640
2641
|
์ด ๋ฐฉ๋ฒ์ Sinatra๋ฅผ ๋ฏธ๋ค์จ์ด๋ก ์ฌ์ฉํ๋ ๊ฒ์ ์์ฃผ ์ฝ๊ฒ ๋ง๋ค์ด ์ฃผ๊ธฐ๋ ํฉ๋๋ค.
|
2641
2642
|
|
2642
|
-
```
|
2643
|
+
```ruby
|
2643
2644
|
require 'sinatra/base'
|
2644
2645
|
|
2645
2646
|
use Sinatra do
|
@@ -2664,7 +2665,7 @@ run RailsProject::Application
|
|
2664
2665
|
|
2665
2666
|
`set`์ผ๋ก ์์ฑํ ์ต์
๋ค์ ํด๋์ค ๋ ๋ฒจ์ ๋ฉ์๋๋ค์
๋๋ค.
|
2666
2667
|
|
2667
|
-
```
|
2668
|
+
```ruby
|
2668
2669
|
class MyApp < Sinatra::Base
|
2669
2670
|
# ์ ๊ธฐ์, ์ ๋ ์ ํ๋ฆฌ์ผ์ด์
๋ฒ์์ ์๋ค๊ตฌ์!
|
2670
2671
|
set :foo, 42
|
@@ -2696,7 +2697,7 @@ end
|
|
2696
2697
|
์ ๊ทผํ๊ฑฐ๋ `erb` ๋ `haml` ๊ฐ์ ๋ ๋๋ง ๋ฉ์๋๋ฅผ ํธ์ถํ ์ ์์ต๋๋ค. ์์ฒญ ๋ฒ์
|
2697
2698
|
๋ด์์ `settings` ํฌํผ๋ฅผ ํตํด ์ ํ๋ฆฌ์ผ์ด์
๋ฒ์์ ์ ๊ทผ ๊ฐ๋ฅํฉ๋๋ค.
|
2698
2699
|
|
2699
|
-
```
|
2700
|
+
```ruby
|
2700
2701
|
class MyApp < Sinatra::Base
|
2701
2702
|
# ์ด๋ด์, ์ ์ ํ๋ฆฌ์ผ์ด์
๋ฒ์์ ์๋ค๊ตฌ์!
|
2702
2703
|
get '/define_route/:name' do
|
@@ -2736,13 +2737,13 @@ end
|
|
2736
2737
|
|
2737
2738
|
์ง์ ์ฝ๋๋ฅผ ์ดํด๋ณด๊ธธ ๋ฐ๋๋๋ค.
|
2738
2739
|
[Sinatra::Delegator ๋ฏน์ค์ธ](https://github.com/sinatra/sinatra/blob/ca06364/lib/sinatra/base.rb#L1609-1633)
|
2739
|
-
์ [๋ฉ์ธ ๊ฐ์ฒด๋ฅผ ํ์ฅํ ๊ฒ](https://github.com/sinatra/sinatra/blob/ca06364/lib/sinatra/main.rb#L28-30)
|
2740
|
+
์ [๋ฉ์ธ ๊ฐ์ฒด๋ฅผ ํ์ฅํ ๊ฒ](https://github.com/sinatra/sinatra/blob/ca06364/lib/sinatra/main.rb#L28-30)์
๋๋ค.
|
2740
2741
|
|
2741
2742
|
## ๋ช
๋ นํ(Command Line)
|
2742
2743
|
|
2743
2744
|
Sinatra ์ ํ๋ฆฌ์ผ์ด์
์ ์ง์ ์คํํ ์ ์์ต๋๋ค.
|
2744
2745
|
|
2745
|
-
```
|
2746
|
+
```shell
|
2746
2747
|
ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-o HOST] [-s HANDLER]
|
2747
2748
|
```
|
2748
2749
|
|
@@ -2757,6 +2758,40 @@ ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-o HOST] [-s HANDLER]
|
|
2757
2758
|
-x # mutex ์ ๊ธ ์ผ๊ธฐ (๊ธฐ๋ณธ๊ฐ์ off)
|
2758
2759
|
```
|
2759
2760
|
|
2761
|
+
### ๋ค์ค ์ค๋ ๋(Multi-threading)
|
2762
|
+
|
2763
|
+
_Konstantin์ [StackOverflow์ ๋ต๋ณ][so-answer]์์ ๊ฐ์ ธ์์ต๋๋ค_
|
2764
|
+
|
2765
|
+
์๋ํธ๋ผ๋ ๋์์ฑ ๋ชจ๋ธ์ ์ ํ ์ฌ์ฉํ์ง ์์ง๋ง, Thin, Puma, WEBrick ๊ฐ์
|
2766
|
+
๊ธฐ์ ์ Rack ํธ๋ค๋ฌ(์๋ฒ)๋ ์ฌ์ฉํฉ๋๋ค. ์๋ํธ๋ผ ์์ ์ ์ค๋ ๋์ ์์ ํ๋ฏ๋ก
|
2767
|
+
๋ ํธ๋ค๋ฌ๊ฐ ๋์์ฑ ์ค๋ ๋ ๋ชจ๋ธ์ ์ฌ์ฉํ๋ค๊ณ ํด๋ ๋ฌธ์ ๊ฐ ๋์ง๋ ์์ต๋๋ค.
|
2768
|
+
์ด๋ ์๋ฒ๋ฅผ ์์ํ ๋, ์๋ฒ์ ๋ฐ๋ฅธ ์ ํํ ํธ์ถ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ์ ๋์
|
2769
|
+
์ด์ผ๊ธฐ์
๋๋ค. ๋ฐ์ ์์ ๋ ๋ค์ค ์ค๋ ๋ Thin ์๋ฒ๋ฅผ ์์ํ๋ ๋ฐฉ๋ฒ์
๋๋ค.
|
2770
|
+
|
2771
|
+
```ruby
|
2772
|
+
# app.rb
|
2773
|
+
|
2774
|
+
require 'sinatra/base'
|
2775
|
+
|
2776
|
+
class App < Sinatra::Base
|
2777
|
+
get '/' do
|
2778
|
+
"Hello, World"
|
2779
|
+
end
|
2780
|
+
end
|
2781
|
+
|
2782
|
+
App.run!
|
2783
|
+
|
2784
|
+
```
|
2785
|
+
|
2786
|
+
์๋ฒ๋ฅผ ์์ํ๋ ๋ช
๋ น์ด๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
|
2787
|
+
|
2788
|
+
```shell
|
2789
|
+
thin --threaded start
|
2790
|
+
```
|
2791
|
+
|
2792
|
+
|
2793
|
+
[so-answer]: http://stackoverflow.com/questions/6278817/is-sinatra-multi-threaded/6282999#6282999)
|
2794
|
+
|
2760
2795
|
## ์๊ตฌ์ฌํญ(Requirement)
|
2761
2796
|
|
2762
2797
|
๋ค์์ ๋ฃจ๋น ๋ฒ์ ์ ๊ณต์์ ์ผ๋ก ์ง์๋ฉ๋๋ค.
|
@@ -2812,8 +2847,8 @@ ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-o HOST] [-s HANDLER]
|
|
2812
2847
|
* MacRuby, Maglev, IronRuby
|
2813
2848
|
* Ruby 1.9.0 ๋ฐ 1.9.1 (์ด ๋ฒ์ ๋ค์ ์ฌ์ฉํ์ง ๋ง ๊ฒ์ ๊ถํฉ๋๋ค)
|
2814
2849
|
|
2815
|
-
๊ณต์์ ์ผ๋ก ์ง์ํ์ง ์๋๋ค๋ ๊ฒ์ ์๋ฏธ๋ ๋ฌด์ธ๊ฐ๊ฐ ๊ทธ ํ๋ซํผ์์๋ง
|
2816
|
-
์ง์๋๋ ํ๋ซํผ์์๋
|
2850
|
+
๊ณต์์ ์ผ๋ก ์ง์ํ์ง ์๋๋ค๋ ๊ฒ์ ์๋ฏธ๋ ๋ฌด์ธ๊ฐ๊ฐ ๊ทธ ํ๋ซํผ์์๋ง ์๋ชป ๋์ํ๊ณ ,
|
2851
|
+
์ง์๋๋ ํ๋ซํผ์์๋ ์ ์์ ์ผ๋ก ๋์ํ ๊ฒฝ์ฐ, ์ฐ๋ฆฌ์ ๋ฌธ์ ๊ฐ ์๋๋ผ ๊ทธ ํ๋ซํผ์ ๋ฌธ์ ๋ก
|
2817
2852
|
๊ฐ์ฃผํ๋ค๋ ๋ป์
๋๋ค.
|
2818
2853
|
|
2819
2854
|
๋ํ ์ฐ๋ฆฌ๋ CI๋ฅผ ruby-head (MRI์ ์ดํ ๋ฆด๋ฆฌ์ฆ) ๋ธ๋์น์ ๋ง์ถฐ ์คํํ์ง๋ง,
|
@@ -2823,35 +2858,37 @@ ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-o HOST] [-s HANDLER]
|
|
2823
2858
|
Sinatra๋ ์ ํํ ๋ฃจ๋น ๊ตฌํ์ฒด๊ฐ ์ง์ํ๋ ์ด๋ ํ ์ด์์ฒด์ ์์๋ ์๋ํด์ผ
|
2824
2859
|
ํฉ๋๋ค.
|
2825
2860
|
|
2861
|
+
MacRuby๋ฅผ ์ฌ์ฉํ๋ค๋ฉด, gem install control_tower ๋ฅผ ์คํํด ์ฃผ์ธ์.
|
2862
|
+
|
2826
2863
|
ํ์ฌ Cardinal, SmallRuby, BlueRuby ๋๋ 1.8.7 ์ด์ ์ ๋ฃจ๋น ๋ฒ์ ์์๋
|
2827
2864
|
Sinatra๋ฅผ ์คํํ ์ ์์ ๊ฒ์
๋๋ค.
|
2828
2865
|
|
2829
2866
|
## ์ต์ (The Bleeding Edge)
|
2830
2867
|
|
2831
2868
|
Sinatra์ ๊ฐ์ฅ ์ต๊ทผ ์ฝ๋๋ฅผ ์ฌ์ฉํ๊ณ ์ ํ๋ค๋ฉด, ์ ํ๋ฆฌ์ผ์ด์
์ ๋ง์คํฐ ๋ธ๋์น์ ๋ง์ถฐ
|
2832
|
-
์คํํ๋ฉด ๋๋ฏ๋ก ๋ถ๋ด๊ฐ์ง์ง ๋ง์ธ์. ํ์ง๋ง ๋ ์์ ์ ์ผ
|
2869
|
+
์คํํ๋ฉด ๋๋ฏ๋ก ๋ถ๋ด๊ฐ์ง์ง ๋ง์ธ์. ํ์ง๋ง ๋ ์์ ์ ์ผ ๊ฒ์
๋๋ค.
|
2833
2870
|
|
2834
2871
|
์ฃผ๊ธฐ์ ์ผ๋ก ์ฌ์ ๋ฐฐํฌ(prerelease) ์ ฌ์ ํธ์ํ๊ธฐ ๋๋ฌธ์, ์ต์ ๊ธฐ๋ฅ๋ค์ ์ป๊ธฐ ์ํด
|
2835
2872
|
๋ค์๊ณผ ๊ฐ์ด ํ ์๋ ์์ต๋๋ค.
|
2836
2873
|
|
2837
|
-
```
|
2874
|
+
```shell
|
2838
2875
|
gem install sinatra --pre
|
2839
2876
|
```
|
2840
2877
|
|
2841
2878
|
### Bundler๋ฅผ ์ฌ์ฉํ์ฌ
|
2842
2879
|
|
2843
2880
|
์ฌ๋ฌ๋ถ ์ ํ๋ฆฌ์ผ์ด์
์ ์ต์ Sinatra๋ก ์คํํ๊ณ ์ ํ๋ค๋ฉด,
|
2844
|
-
[Bundler](http://
|
2881
|
+
[Bundler](http://bundler.io)๋ฅผ ์ฌ์ฉํ ๊ฒ์ ๊ถ์ฅํฉ๋๋ค.
|
2845
2882
|
|
2846
2883
|
์ฐ์ , ์์ง ์ค์นํ์ง ์์๋ค๋ฉด bundler๋ฅผ ์ค์นํฉ๋๋ค.
|
2847
2884
|
|
2848
|
-
```
|
2885
|
+
```shell
|
2849
2886
|
gem install bundler
|
2850
2887
|
```
|
2851
2888
|
|
2852
2889
|
๊ทธ๋ฐ ๋ค์, ํ๋ก์ ํธ ๋๋ ํฐ๋ฆฌ์์, `Gemfile`์ ๋ง๋ญ๋๋ค.
|
2853
2890
|
|
2854
|
-
```
|
2891
|
+
```ruby
|
2855
2892
|
source 'https://rubygems.org'
|
2856
2893
|
gem 'sinatra', :github => "sinatra/sinatra"
|
2857
2894
|
|
@@ -2866,7 +2903,7 @@ Bundler๊ฐ ์๋์ผ๋ก ์ฐพ์์ ์ถ๊ฐํ ๊ฒ์
๋๋ค.
|
|
2866
2903
|
|
2867
2904
|
์ด์ ์ฑ์ ์คํํ ์ ์์ต๋๋ค.
|
2868
2905
|
|
2869
|
-
```
|
2906
|
+
```shell
|
2870
2907
|
bundle exec ruby myapp.rb
|
2871
2908
|
```
|
2872
2909
|
|
@@ -2875,7 +2912,7 @@ bundle exec ruby myapp.rb
|
|
2875
2912
|
๋ก์ปฌ ํด๋ก (clone)์ ์์ฑํ ๋ค์ `$LOAD_PATH`์ `sinatra/lib` ๋๋ ํฐ๋ฆฌ๋ฅผ ์ฃผ๊ณ
|
2876
2913
|
์ฌ๋ฌ๋ถ ์ฑ์ ์คํํฉ๋๋ค.
|
2877
2914
|
|
2878
|
-
```
|
2915
|
+
```shell
|
2879
2916
|
cd myapp
|
2880
2917
|
git clone git://github.com/sinatra/sinatra.git
|
2881
2918
|
ruby -I sinatra/lib myapp.rb
|
@@ -2883,7 +2920,7 @@ ruby -I sinatra/lib myapp.rb
|
|
2883
2920
|
|
2884
2921
|
์ดํ์ Sinatra ์์ค๋ฅผ ์
๋ฐ์ดํธํ๋ ค๋ฉด ์ด๋ ๊ฒ ํ์ธ์.
|
2885
2922
|
|
2886
|
-
```
|
2923
|
+
```shell
|
2887
2924
|
cd myapp/sinatra
|
2888
2925
|
git pull
|
2889
2926
|
```
|
@@ -2892,7 +2929,7 @@ git pull
|
|
2892
2929
|
|
2893
2930
|
์ ฌ์ ์ง์ ๋น๋ํ ์ ์์ต๋๋ค.
|
2894
2931
|
|
2895
|
-
```
|
2932
|
+
```shell
|
2896
2933
|
git clone git://github.com/sinatra/sinatra.git
|
2897
2934
|
cd sinatra
|
2898
2935
|
rake sinatra.gemspec
|
@@ -2901,7 +2938,7 @@ rake install
|
|
2901
2938
|
|
2902
2939
|
๋ง์ฝ ์ ฌ์ ๋ฃจํธ๋ก ์ค์นํ๋ค๋ฉด, ๋ง์ง๋ง ๋จ๊ณ๋ ๋ค์๊ณผ ๊ฐ์ด ํด์ผ ํฉ๋๋ค.
|
2903
2940
|
|
2904
|
-
```
|
2941
|
+
```shell
|
2905
2942
|
sudo rake install
|
2906
2943
|
```
|
2907
2944
|
|
@@ -2917,12 +2954,14 @@ SemVerTag๋ฅผ ์ค์ํฉ๋๋ค.
|
|
2917
2954
|
๊ทธ๋ฆฌ๊ณ ๋ค๋ฅธ ๋ฆฌ์์ค๋ค์ ๋ํ ๋งํฌ.
|
2918
2955
|
* [๊ธฐ์ฌํ๊ธฐ](http://www.sinatrarb.com/contributing) - ๋ฒ๊ทธ๋ฅผ ์ฐพ์๋์?
|
2919
2956
|
๋์์ด ํ์ํ๊ฐ์? ํจ์น๋ฅผ ํ์
จ๋์?
|
2920
|
-
* [์ด์ ํธ๋์ปค](
|
2921
|
-
* [ํธ์ํฐ](
|
2957
|
+
* [์ด์ ํธ๋์ปค](https://github.com/sinatra/sinatra/issues)
|
2958
|
+
* [ํธ์ํฐ](https://twitter.com/sinatra)
|
2922
2959
|
* [๋ฉ์ผ๋ง ๋ฆฌ์คํธ](http://groups.google.com/group/sinatrarb/topics)
|
2923
2960
|
* IRC: [#sinatra](irc://chat.freenode.net/#sinatra) http://freenode.net
|
2961
|
+
* ์ฌ๋์ [Sinatra & Friends](https://sinatrarb.slack.com)์
๋๋ค.
|
2962
|
+
[์ฌ๊ธฐ](https://sinatra-slack.herokuapp.com/)์์ ๊ฐ์
๊ฐ๋ฅํฉ๋๋ค.
|
2924
2963
|
* [Sinatra Book](https://github.com/sinatra/sinatra-book/) Cookbook ํํ ๋ฆฌ์ผ
|
2925
2964
|
* [Sinatra Recipes](http://recipes.sinatrarb.com/) ์ปค๋ฎค๋ํฐ๊ฐ ๋ง๋๋ ๋ ์ํผ
|
2926
|
-
* http://rubydoc.info
|
2927
|
-
๋๋ [current HEAD](http://rubydoc.info/github/sinatra/sinatra)์ ๋ํ API ๋ฌธ์
|
2928
|
-
* [CI server](
|
2965
|
+
* http://www.rubydoc.info/์ ์๋ [์ต์ข
๋ฆด๋ฆฌ์ค](http://www.rubydoc.info/gems/sinatra)
|
2966
|
+
๋๋ [current HEAD](http://www.rubydoc.info/github/sinatra/sinatra)์ ๋ํ API ๋ฌธ์
|
2967
|
+
* [CI server](https://travis-ci.org/sinatra/sinatra)
|