sinatra-acd 1.4.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +5 -0
  3. data/AUTHORS +61 -0
  4. data/CHANGES +1293 -0
  5. data/Gemfile +76 -0
  6. data/LICENSE +23 -0
  7. data/README.de.md +2864 -0
  8. data/README.es.md +2786 -0
  9. data/README.fr.md +2924 -0
  10. data/README.hu.md +694 -0
  11. data/README.ja.md +2726 -0
  12. data/README.ko.md +2832 -0
  13. data/README.md +2980 -0
  14. data/README.pt-br.md +965 -0
  15. data/README.pt-pt.md +791 -0
  16. data/README.ru.md +2799 -0
  17. data/README.zh.md +2158 -0
  18. data/Rakefile +199 -0
  19. data/examples/chat.rb +61 -0
  20. data/examples/simple.rb +3 -0
  21. data/examples/stream.ru +26 -0
  22. data/lib/sinatra.rb +4 -0
  23. data/lib/sinatra/base.rb +2044 -0
  24. data/lib/sinatra/images/404.png +0 -0
  25. data/lib/sinatra/images/500.png +0 -0
  26. data/lib/sinatra/main.rb +34 -0
  27. data/lib/sinatra/show_exceptions.rb +345 -0
  28. data/lib/sinatra/version.rb +3 -0
  29. data/sinatra.gemspec +19 -0
  30. data/test/asciidoctor_test.rb +72 -0
  31. data/test/base_test.rb +171 -0
  32. data/test/builder_test.rb +91 -0
  33. data/test/coffee_test.rb +90 -0
  34. data/test/compile_test.rb +183 -0
  35. data/test/contest.rb +100 -0
  36. data/test/creole_test.rb +65 -0
  37. data/test/delegator_test.rb +160 -0
  38. data/test/encoding_test.rb +20 -0
  39. data/test/erb_test.rb +116 -0
  40. data/test/extensions_test.rb +98 -0
  41. data/test/filter_test.rb +487 -0
  42. data/test/haml_test.rb +109 -0
  43. data/test/helper.rb +131 -0
  44. data/test/helpers_test.rb +1917 -0
  45. data/test/integration/app.rb +79 -0
  46. data/test/integration_helper.rb +236 -0
  47. data/test/integration_test.rb +104 -0
  48. data/test/less_test.rb +69 -0
  49. data/test/liquid_test.rb +77 -0
  50. data/test/mapped_error_test.rb +285 -0
  51. data/test/markaby_test.rb +80 -0
  52. data/test/markdown_test.rb +82 -0
  53. data/test/mediawiki_test.rb +68 -0
  54. data/test/middleware_test.rb +68 -0
  55. data/test/nokogiri_test.rb +67 -0
  56. data/test/public/favicon.ico +0 -0
  57. data/test/rabl_test.rb +89 -0
  58. data/test/rack_test.rb +45 -0
  59. data/test/radius_test.rb +59 -0
  60. data/test/rdoc_test.rb +66 -0
  61. data/test/readme_test.rb +130 -0
  62. data/test/request_test.rb +97 -0
  63. data/test/response_test.rb +63 -0
  64. data/test/result_test.rb +76 -0
  65. data/test/route_added_hook_test.rb +59 -0
  66. data/test/routing_test.rb +1412 -0
  67. data/test/sass_test.rb +115 -0
  68. data/test/scss_test.rb +88 -0
  69. data/test/server_test.rb +48 -0
  70. data/test/settings_test.rb +582 -0
  71. data/test/sinatra_test.rb +12 -0
  72. data/test/slim_test.rb +102 -0
  73. data/test/static_test.rb +236 -0
  74. data/test/streaming_test.rb +149 -0
  75. data/test/stylus_test.rb +90 -0
  76. data/test/templates_test.rb +382 -0
  77. data/test/textile_test.rb +65 -0
  78. data/test/views/a/in_a.str +1 -0
  79. data/test/views/ascii.erb +2 -0
  80. data/test/views/b/in_b.str +1 -0
  81. data/test/views/calc.html.erb +1 -0
  82. data/test/views/error.builder +3 -0
  83. data/test/views/error.erb +3 -0
  84. data/test/views/error.haml +3 -0
  85. data/test/views/error.sass +2 -0
  86. data/test/views/explicitly_nested.str +1 -0
  87. data/test/views/foo/hello.test +1 -0
  88. data/test/views/hello.asciidoc +1 -0
  89. data/test/views/hello.builder +1 -0
  90. data/test/views/hello.coffee +1 -0
  91. data/test/views/hello.creole +1 -0
  92. data/test/views/hello.erb +1 -0
  93. data/test/views/hello.haml +1 -0
  94. data/test/views/hello.less +5 -0
  95. data/test/views/hello.liquid +1 -0
  96. data/test/views/hello.mab +1 -0
  97. data/test/views/hello.md +1 -0
  98. data/test/views/hello.mediawiki +1 -0
  99. data/test/views/hello.nokogiri +1 -0
  100. data/test/views/hello.rabl +2 -0
  101. data/test/views/hello.radius +1 -0
  102. data/test/views/hello.rdoc +1 -0
  103. data/test/views/hello.sass +2 -0
  104. data/test/views/hello.scss +3 -0
  105. data/test/views/hello.slim +1 -0
  106. data/test/views/hello.str +1 -0
  107. data/test/views/hello.styl +2 -0
  108. data/test/views/hello.test +1 -0
  109. data/test/views/hello.textile +1 -0
  110. data/test/views/hello.wlang +1 -0
  111. data/test/views/hello.yajl +1 -0
  112. data/test/views/layout2.builder +3 -0
  113. data/test/views/layout2.erb +2 -0
  114. data/test/views/layout2.haml +2 -0
  115. data/test/views/layout2.liquid +2 -0
  116. data/test/views/layout2.mab +2 -0
  117. data/test/views/layout2.nokogiri +3 -0
  118. data/test/views/layout2.rabl +3 -0
  119. data/test/views/layout2.radius +2 -0
  120. data/test/views/layout2.slim +3 -0
  121. data/test/views/layout2.str +2 -0
  122. data/test/views/layout2.test +1 -0
  123. data/test/views/layout2.wlang +2 -0
  124. data/test/views/nested.str +1 -0
  125. data/test/views/utf8.erb +2 -0
  126. data/test/wlang_test.rb +87 -0
  127. data/test/yajl_test.rb +86 -0
  128. metadata +280 -0
@@ -0,0 +1,2799 @@
1
+ # Sinatra
2
+
3
+ *Π’Π½ΠΈΠΌΠ°Π½ΠΈΠ΅: Π­Ρ‚ΠΎΡ‚ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ являСтся ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ΠΎΠΌ английской вСрсии ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ
4
+ ΡƒΡΡ‚Π°Ρ€Π΅Π²ΡˆΠΈΠΌ*
5
+
6
+ Sinatra β€” это ΠΏΡ€Π΅Π΄ΠΌΠ΅Ρ‚Π½ΠΎ-ΠΎΡ€ΠΈΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ каркас
7
+ ([DSL](http://ru.wikipedia.org/wiki/ΠŸΡ€Π΅Π΄ΠΌΠ΅Ρ‚Π½ΠΎ-ΠΎΡ€ΠΈΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ_язык_программирования))
8
+ для быстрого создания Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹Ρ… Π²Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Π½Π° Ruby с ΠΌΠΈΠ½ΠΈΠΌΡƒΠΌΠΎΠΌ усилий:
9
+
10
+ ```ruby
11
+ # myapp.rb
12
+ require 'sinatra'
13
+
14
+ get '/' do
15
+ 'Hello world!'
16
+ end
17
+ ```
18
+
19
+ УстановитС gem:
20
+
21
+ ```
22
+ gem install sinatra
23
+ ```
24
+
25
+ ΠΈ запуститС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ:
26
+
27
+ ```
28
+ ruby myapp.rb
29
+ ```
30
+
31
+ ΠžΡ†Π΅Π½ΠΈΡ‚Π΅ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚: http://localhost:4567
32
+
33
+ РСкомСндуСтся Ρ‚Π°ΠΊΠΆΠ΅ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ Thin, ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ это ΠΌΠΎΠΆΠ½ΠΎ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ: `gem install
34
+ thin`. Thin β€” это Π±ΠΎΠ»Π΅Π΅ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ сСрвСр для
35
+ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Π½Π° Sinatra.
36
+
37
+ ## ΠœΠ°Ρ€ΡˆΡ€ΡƒΡ‚Ρ‹
38
+
39
+ Π’ Sinatra ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ β€” это ΠΏΠ°Ρ€Π°: <HTTP ΠΌΠ΅Ρ‚ΠΎΠ΄> ΠΈ <шаблон URL>. ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚
40
+ связан с блоком кода:
41
+
42
+ ```ruby
43
+ get '/' do
44
+ # .. Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ ..
45
+ end
46
+
47
+ post '/' do
48
+ # .. Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ..
49
+ end
50
+
51
+ put '/' do
52
+ # .. Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ..
53
+ end
54
+
55
+ patch '/' do
56
+ # .. Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ..
57
+ end
58
+
59
+ delete '/' do
60
+ # .. Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ ..
61
+ end
62
+
63
+ options '/' do
64
+ # .. Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ ΠΎΡ‚Π²Π΅Ρ‚ΠΈΡ‚ΡŒ ..
65
+ end
66
+
67
+ link '/' do
68
+ .. Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ ..
69
+ end
70
+
71
+ unlink '/' do
72
+ .. Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ ..
73
+ end
74
+ ```
75
+
76
+ ΠœΠ°Ρ€ΡˆΡ€ΡƒΡ‚Ρ‹ ΡΠ²Π΅Ρ€ΡΡŽΡ‚ΡΡ с запросом Π² порядкС очСрСдности ΠΈΡ… записи Π² Ρ„Π°ΠΉΠ»Π΅
77
+ прилоТСния. ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ ΠΆΠ΅ совпавший с запросом ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ ΠΈ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π·Π²Π°Π½.
78
+
79
+ Π¨Π°Π±Π»ΠΎΠ½Ρ‹ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΎΠ² ΠΌΠΎΠ³ΡƒΡ‚ Π²ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ Π² сСбя ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹, доступныС Π² xэшС
80
+ `params`:
81
+
82
+ ```ruby
83
+ get '/hello/:name' do
84
+ # соотвСтствуСт "GET /hello/foo" ΠΈ "GET /hello/bar",
85
+ # Π³Π΄Π΅ params[:name] 'foo' ΠΈΠ»ΠΈ 'bar'
86
+ "Hello #{params[:name]}!"
87
+ end
88
+ ```
89
+
90
+ Π’Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Π² качСствС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… Π±Π»ΠΎΠΊΠ°:
91
+
92
+ ```ruby
93
+ get '/hello/:name' do |n|
94
+ "Hello #{n}!"
95
+ end
96
+ ```
97
+
98
+ Π¨Π°Π±Π»ΠΎΠ½Ρ‹ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΎΠ² Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠ³ΡƒΡ‚ Π²ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ Π² сСбя splat (ΠΈΠ»ΠΈ '*' маску,
99
+ ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡Π°ΡŽΡ‰ΡƒΡŽ любой символ) ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹, доступныС Π² массивС `params[:splat]`:
100
+
101
+ ```ruby
102
+ get '/say/*/to/*' do
103
+ # соотвСтствуСт /say/hello/to/world
104
+ params[:splat] # => ["hello", "world"]
105
+ end
106
+
107
+ get '/download/*.*' do
108
+ # соотвСтствуСт /download/path/to/file.xml
109
+ params[:splat] # => ["path/to/file", "xml"]
110
+ end
111
+ ```
112
+
113
+ Или с ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ Π±Π»ΠΎΠΊΠ°:
114
+
115
+ ```ruby
116
+ get '/download/*.*' do |path, ext|
117
+ [path, ext] # => ["path/to/file", "xml"]
118
+ end
119
+ ```
120
+
121
+ РСгулярныС выраТСния Π² качСствС шаблонов ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΎΠ²:
122
+
123
+ ```ruby
124
+ get %r{/hello/([\w]+)} do
125
+ "Hello, #{params[:captures].first}!"
126
+ end
127
+ ```
128
+
129
+ Или с ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠΌ Π±Π»ΠΎΠΊΠ°:
130
+
131
+ ```ruby
132
+ get %r{/hello/([\w]+)} do |c|
133
+ "Hello, #{c}!"
134
+ end
135
+ ```
136
+
137
+ Π¨Π°Π±Π»ΠΎΠ½Ρ‹ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΎΠ² ΠΌΠΎΠ³ΡƒΡ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹:
138
+
139
+ ```ruby
140
+ get '/posts.?:format?' do
141
+ # соотвСтствуСт "GET /posts", "GET /posts.json", "GET /posts.xml" ΠΈ Ρ‚.Π΄.
142
+ end
143
+ ```
144
+
145
+ ΠšΡΡ‚Π°Ρ‚ΠΈ, Ссли Π²Ρ‹ Π½Π΅ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅ Π·Π°Ρ‰ΠΈΡ‚Ρƒ ΠΎΡ‚ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ ΠΏΡƒΡ‚ΠΈ Π² дирСкториях (path
146
+ traversal, см. Π½ΠΈΠΆΠ΅), ΠΏΡƒΡ‚ΡŒ запроса ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ Π΄ΠΎ Π½Π°Ρ‡Π°Π»Π° поиска
147
+ подходящСго ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π°.
148
+
149
+ ### Условия
150
+
151
+ ΠœΠ°Ρ€ΡˆΡ€ΡƒΡ‚Ρ‹ ΠΌΠΎΠ³ΡƒΡ‚ Π²ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ условия совпадСний, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, клиСнтскоС
152
+ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ (user agent):
153
+
154
+ ```ruby
155
+ get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
156
+ "You're using Songbird version #{params[:agent][0]}"
157
+ end
158
+
159
+ get '/foo' do
160
+ # соотвСтствуСт Π½Π΅-songbird Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π°ΠΌ
161
+ end
162
+ ```
163
+
164
+ Π”Ρ€ΡƒΠ³ΠΈΠΌΠΈ доступными условиями ΡΠ²Π»ΡΡŽΡ‚ΡΡ `host_name` ΠΈ `provides`:
165
+
166
+ ```ruby
167
+ get '/', :host_name => /^admin\./ do
168
+ "Admin Area, Access denied!"
169
+ end
170
+
171
+ get '/', :provides => 'html' do
172
+ haml :index
173
+ end
174
+
175
+ get '/', :provides => ['rss', 'atom', 'xml'] do
176
+ builder :feed
177
+ end
178
+ ```
179
+
180
+ Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π·Π°Π΄Π°Ρ‚ΡŒ собствСнныС условия:
181
+
182
+ ```ruby
183
+ set(:probability) { |value| condition { rand <= value } }
184
+
185
+ get '/win_a_car', :probability => 0.1 do
186
+ "You won!"
187
+ end
188
+
189
+ get '/win_a_car' do
190
+ "Sorry, you lost."
191
+ end
192
+ ```
193
+
194
+ Для условия, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ нСсколько ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ², ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ Π·Π²Π΅Π·Π΄ΠΎΡ‡ΠΊΡƒ:
195
+
196
+ ```ruby
197
+ set(:auth) do |*roles| # <- ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° Π·Π²Π΅Π·Π΄ΠΎΡ‡ΠΊΡƒ
198
+ condition do
199
+ unless logged_in? && roles.any? {|role| current_user.in_role? role }
200
+ redirect "/login/", 303
201
+ end
202
+ end
203
+ end
204
+
205
+ get "/my/account/", :auth => [:user, :admin] do
206
+ "Your Account Details"
207
+ end
208
+
209
+ get "/only/admin/", :auth => :admin do
210
+ "Only admins are allowed here!"
211
+ end
212
+ ```
213
+
214
+ ### Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Π΅ значСния
215
+
216
+ Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π±Π»ΠΎΠΊΠ° ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π° ограничиваСтся Ρ‚Π΅Π»ΠΎΠΌ ΠΎΡ‚Π²Π΅Ρ‚Π°, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅
217
+ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½ΠΎ HTTP ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ, ΠΈΠ»ΠΈ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ "прослойкой" (middleware) Π² Rack
218
+ стСкС. Π§Π°Ρ‰Π΅ всСго это строка, ΠΊΠ°ΠΊ Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°Ρ… Π²Ρ‹ΡˆΠ΅. Но Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΡ€ΠΈΠ΅ΠΌΠ»Π΅ΠΌΡ‹ ΠΈ
219
+ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ значСния.
220
+
221
+ Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ любой ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ Π»ΠΈΠ±ΠΎ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹ΠΌ Rack ΠΎΡ‚Π²Π΅Ρ‚ΠΎΠΌ,
222
+ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ Rack body, Π»ΠΈΠ±ΠΎ ΠΊΠΎΠ΄ΠΎΠΌ состояния HTTP:
223
+
224
+ * массив с трСмя ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ: `[ΠΊΠΎΠ΄ (Fixnum), Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ (Hash), Ρ‚Π΅Π»ΠΎ ΠΎΡ‚Π²Π΅Ρ‚Π°
225
+ (Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΠΎΡ‚Π²Π΅Ρ‡Π°Ρ‚ΡŒ Π½Π° #each)]`;
226
+ * массив с двумя ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ: `[ΠΊΠΎΠ΄ (Fixnum), Ρ‚Π΅Π»ΠΎ ΠΎΡ‚Π²Π΅Ρ‚Π° (Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΠΎΡ‚Π²Π΅Ρ‡Π°Ρ‚ΡŒ
227
+ Π½Π° #each)]`;
228
+ * ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, ΠΎΡ‚Π²Π΅Ρ‡Π°ΡŽΡ‰ΠΈΠΉ Π½Π° `#each`, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ строковыС Ρ‚ΠΈΠΏΡ‹
229
+ Π΄Π°Π½Π½Ρ‹Ρ… Π² этот Π±Π»ΠΎΠΊ;
230
+ * Fixnum, ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄ состояния HTTP.
231
+
232
+
233
+ Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Π»Π΅Π³ΠΊΠΎ ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΏΠΎΡ‚ΠΎΡ‡Π½Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€:
234
+
235
+ ```ruby
236
+ class Stream
237
+ def each
238
+ 100.times { |i| yield "#{i}\n" }
239
+ end
240
+ end
241
+
242
+ get('/') { Stream.new }
243
+ ```
244
+
245
+ Π’Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄ `stream` (описываСмый Π½ΠΈΠΆΠ΅), Ρ‡Ρ‚ΠΎΠ±Ρ‹
246
+ ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΡ‚ΡŒ количСство Π΄ΡƒΠ±Π»ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° ΠΈ Π΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ Π»ΠΎΠ³ΠΈΠΊΡƒ стриминга прямо Π²
247
+ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π΅.
248
+
249
+ ### БобствСнныС Π΄Π΅Ρ‚Π΅ΠΊΡ‚ΠΎΡ€Ρ‹ совпадСний для ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΎΠ²
250
+
251
+ Как ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π²Ρ‹ΡˆΠ΅, Sinatra поставляСтся со встроСнной ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΎΠΉ строк ΠΈ
252
+ рСгулярных Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ Π² качСствС шаблонов URL. Но ΠΈ это Π΅Ρ‰Π΅ Π½Π΅ всС. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅
253
+ Π»Π΅Π³ΠΊΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ свои собствСнныС Π΄Π΅Ρ‚Π΅ΠΊΡ‚ΠΎΡ€Ρ‹ совпадСний (matchers) для
254
+ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΎΠ²:
255
+
256
+ ```ruby
257
+ class AllButPattern
258
+ Match = Struct.new(:captures)
259
+
260
+ def initialize(except)
261
+ @except = except
262
+ @captures = Match.new([])
263
+ end
264
+
265
+ def match(str)
266
+ @captures unless @except === str
267
+ end
268
+ end
269
+
270
+ def all_but(pattern)
271
+ AllButPattern.new(pattern)
272
+ end
273
+
274
+ get all_but("/index") do
275
+ # ...
276
+ end
277
+ ```
278
+
279
+ Π—Π°ΠΌΠ΅Ρ‚ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, чСрСсчур услоТнСн, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΎΠ½
280
+ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ Ρ‚Π°ΠΊ:
281
+
282
+ ```ruby
283
+ get // do
284
+ pass if request.path_info == "/index"
285
+ # ...
286
+ end
287
+ ```
288
+
289
+ Или с использованиСм Π½Π΅Π³Π°Ρ‚ΠΈΠ²Π½ΠΎΠ³ΠΎ просмотра Π²ΠΏΠ΅Ρ€Π΅Π΄:
290
+
291
+ ```ruby
292
+ get %r{^(?!/index$)} do
293
+ # ...
294
+ end
295
+ ```
296
+
297
+ ## БтатичСскиС Ρ„Π°ΠΉΠ»Ρ‹
298
+
299
+ БтатичСскиС Ρ„Π°ΠΉΠ»Ρ‹ ΠΎΡ‚Π΄Π°ΡŽΡ‚ΡΡ ΠΈΠ· `./public` Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ Π΄Ρ€ΡƒΠ³ΠΎΠ΅
300
+ мСсто, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ ΠΎΠΏΡ†ΠΈΡŽ `:public_folder`:
301
+
302
+ ```ruby
303
+ set :public_folder, File.dirname(__FILE__) + '/static'
304
+ ```
305
+
306
+ Π£Ρ‡Ρ‚ΠΈΡ‚Π΅, Ρ‡Ρ‚ΠΎ имя Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ со статичСскими Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ Π½Π΅ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ Π² URL.
307
+ НапримСр, Ρ„Π°ΠΉΠ» `./public/css/style.css` Π±ΡƒΠ΄Π΅Ρ‚ доступСн ΠΊΠ°ΠΊ
308
+ `http://example.com/css/style.css`.
309
+
310
+ Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ ΠΎΠΏΡ†ΠΈΡŽ `:static_cache_control` (см. Π½ΠΈΠΆΠ΅), Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ
311
+ `Cache-Control`.
312
+
313
+ ## ΠŸΡ€Π΅Π΄ΡΡ‚Π°Π²Π»Π΅Π½ΠΈΡ / Π¨Π°Π±Π»ΠΎΠ½Ρ‹
314
+
315
+ ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΡˆΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°Ρ‚ΠΎΡ€ прСдставлСн своим собствСнным ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ. Π­Ρ‚ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ попросту
316
+ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ строку:
317
+
318
+ ```ruby
319
+ get '/' do
320
+ erb :index
321
+ end
322
+ ```
323
+
324
+ ΠžΡ‚ΠΎΠ±Ρ€Π°Π·ΠΈΡ‚ `views/index.erb`.
325
+
326
+ ВмСсто ΠΈΠΌΠ΅Π½ΠΈ шаблона Π²Ρ‹ Ρ‚Π°ΠΊ ΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ нСпосрСдствСнно само
327
+ содСрТимоС шаблона:
328
+
329
+ ```ruby
330
+ get '/' do
331
+ code = "<%= Time.now %>"
332
+ erb code
333
+ end
334
+ ```
335
+
336
+ Π­Ρ‚ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‚ Π²Ρ‚ΠΎΡ€ΠΎΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚, Ρ…Π΅Ρˆ с опциями:
337
+
338
+ ```ruby
339
+ get '/' do
340
+ erb :index, :layout => :post
341
+ end
342
+ ```
343
+
344
+ ΠžΡ‚ΠΎΠ±Ρ€Π°Π·ΠΈΡ‚ `views/index.erb`, Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΌ Π² `views/post.erb` (ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ:
345
+ `views/layout.erb`, Ссли сущСствуСт).
346
+
347
+ Π›ΡŽΠ±Ρ‹Π΅ ΠΎΠΏΡ†ΠΈΠΈ, Π½Π΅ ΠΏΠΎΠ½ΠΈΠΌΠ°Π΅ΠΌΡ‹Π΅ Sinatra, Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Ρ‹ Π² ΡˆΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°Ρ‚ΠΎΡ€:
348
+
349
+ ```ruby
350
+ get '/' do
351
+ haml :index, :format => :html5
352
+ end
353
+ ```
354
+
355
+ Π’Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π·Π°Π΄Π°Π²Π°Ρ‚ΡŒ ΠΎΠΏΡ†ΠΈΠΈ для ΡˆΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°Ρ‚ΠΎΡ€ΠΎΠ² Π² ΠΎΠ±Ρ‰Π΅ΠΌ:
356
+
357
+ ```ruby
358
+ set :haml, :format => :html5
359
+
360
+ get '/' do
361
+ haml :index
362
+ end
363
+ ```
364
+
365
+ ΠžΠΏΡ†ΠΈΠΈ, ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Π΅ Π² ΠΌΠ΅Ρ‚ΠΎΠ΄, ΠΏΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‚ ΠΎΠΏΡ†ΠΈΠΈ, Π·Π°Π΄Π°Π½Π½Ρ‹Π΅ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ `set`.
366
+
367
+ ДоступныС ΠΎΠΏΡ†ΠΈΠΈ:
368
+
369
+ <dl>
370
+ <dt>locals</dt>
371
+ <dd>
372
+ Бписок Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Ρ… ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…, ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡ‹Ρ… Π² Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚.
373
+ НапримСр: <tt>erb "<%= foo %>", :locals => {:foo => "bar"}</tt>
374
+ </dd>
375
+
376
+ <dt>default_encoding</dt>
377
+ <dd>
378
+ ΠšΠΎΠ΄ΠΈΡ€ΠΎΠ²ΠΊΠ°, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ слСдуСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ, Ссли Π½Π΅ ΡƒΠ΄Π°Π»ΠΎΡΡŒ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ
379
+ ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½ΡƒΡŽ. По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ: <tt>settings.default_encoding</tt>.
380
+ </dd>
381
+
382
+ <dt>views</dt>
383
+ <dd>
384
+ ДирСктория с шаблонами. По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ: <tt>settings.views</tt>.
385
+ </dd>
386
+
387
+ <dt>layout</dt>
388
+ <dd>
389
+ Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΠ»ΠΈ Π½Π΅Ρ‚ лэйаут (<tt>true</tt> ΠΈΠ»ΠΈ <tt>false</tt>). Если ΠΆΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Symbol,
390
+ Ρ‚ΠΎ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, ΠΊΠ°ΠΊΠΎΠΉ шаблон ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² качСствС лэйаута. НапримСр:
391
+ <tt>erb :index, :layout => !request.xhr?</tt>
392
+ </dd>
393
+
394
+ <dt>content_type</dt>
395
+ <dd>
396
+ Content-Type ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ шаблона. По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ: задаСтся ΡˆΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°Ρ‚ΠΎΡ€ΠΎΠΌ.
397
+ </dd>
398
+
399
+ <dt>scope</dt>
400
+ <dd>
401
+ ΠžΠ±Π»Π°ΡΡ‚ΡŒ видимости, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ рСндСрятся ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹. По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ: экзСмпляр
402
+ прилоТСния. Если Π²Ρ‹ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚Π΅ эту ΠΎΠΏΡ†ΠΈΡŽ, Ρ‚ΠΎ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ экзСмпляра ΠΈ
403
+ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹-ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠΈ станут нСдоступными Π² Π²Π°ΡˆΠΈΡ… ΡˆΠ°Π±Π»ΠΎΠ½Π°Ρ….
404
+ </dd>
405
+
406
+ <dt>layout_engine</dt>
407
+ <dd>
408
+ Π¨Π°Π±Π»ΠΎΠ½ΠΈΠ·Π°Ρ‚ΠΎΡ€, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ слСдуСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для отобраТСния лэйаута.
409
+ ПолСзная опция для ΡˆΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°Ρ‚ΠΎΡ€ΠΎΠ², Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π½Π΅Ρ‚ Π½ΠΈΠΊΠ°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ
410
+ лэйаутов. По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ: Ρ‚ΠΎΡ‚ ΠΆΠ΅ ΡˆΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°Ρ‚ΠΎΡ€, Ρ‡Ρ‚ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΈ для самого
411
+ шаблона. ΠŸΡ€ΠΈΠΌΠ΅Ρ€: <tt>set :rdoc, :layout_engine => :erb</tt>
412
+ </dd>
413
+ </dl>
414
+
415
+ По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ считаСтся, Ρ‡Ρ‚ΠΎ ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹ находятся Π² Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ `./views`. Π§Ρ‚ΠΎΠ±Ρ‹
416
+ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΄Ρ€ΡƒΠ³ΡƒΡŽ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΡŽ с шаблонами:
417
+
418
+ ```ruby
419
+ set :views, settings.root + '/templates'
420
+ ```
421
+
422
+ Π’Π°ΠΆΠ½ΠΎΠ΅ Π·Π°ΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅: Π²Ρ‹ всСгда Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡΡΡ‹Π»Π°Ρ‚ΡŒΡΡ Π½Π° ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ символов
423
+ (Symbol), Π΄Π°ΠΆΠ΅ ΠΊΠΎΠ³Π΄Π° ΠΎΠ½ΠΈ Π² ΠΏΠΎΠ΄Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ (Π² этом случаС ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅
424
+ `:'subdir/template'`). Π’Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ символы, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΈΠ½Π°Ρ‡Π΅
425
+ ΡˆΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°Ρ‚ΠΎΡ€Ρ‹ попросту ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°ΡŽΡ‚ Π»ΡŽΠ±Ρ‹Π΅ строки, ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΠΌ.
426
+
427
+ ### Π‘ΡƒΠΊΠ²Π°Π»ΡŒΠ½Ρ‹Π΅ ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹
428
+
429
+ ```ruby
430
+ get '/' do
431
+ haml '%div.title Hello World'
432
+ end
433
+ ```
434
+
435
+ ΠžΡ‚ΠΎΠ±Ρ€Π°Π·ΠΈΡ‚ шаблон, ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹ΠΉ строкой.
436
+
437
+ ### ДоступныС ΡˆΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°Ρ‚ΠΎΡ€Ρ‹
438
+
439
+ НСкоторыС языки шаблонов ΠΈΠΌΠ΅ΡŽΡ‚ нСсколько Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΉ. Π§Ρ‚ΠΎΠ±Ρ‹ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ, ΠΊΠ°ΠΊΡƒΡŽ
440
+ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ, Π²Π°ΠΌ слСдуСт просто ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Π½ΡƒΠΆΠ½ΡƒΡŽ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ:
441
+
442
+ ```ruby
443
+ require 'rdiscount' # ΠΈΠ»ΠΈ require 'bluecloth'
444
+ get('/') { markdown :index }
445
+ ```
446
+
447
+ #### Haml ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹
448
+
449
+ <table>
450
+ <tr>
451
+ <td>Зависимости</td>
452
+ <td><a href="http://haml.info/" title="haml">haml</a></td>
453
+ </tr>
454
+ <tr>
455
+ <td>Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ Ρ„Π°ΠΉΠ»ΠΎΠ²</td>
456
+ <td><tt>.haml</tt></td>
457
+ </tr>
458
+ <tr>
459
+ <td>ΠŸΡ€ΠΈΠΌΠ΅Ρ€</td>
460
+ <td><tt>haml :index, :format => :html5</tt></td>
461
+ </tr>
462
+ </table>
463
+
464
+ #### Erb ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹
465
+
466
+ <table>
467
+ <tr>
468
+ <td>Зависимости</td>
469
+ <td>
470
+ <a href="http://www.kuwata-lab.com/erubis/" title="erubis">erubis</a>
471
+ ΠΈΠ»ΠΈ erb (Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ Π² Ruby)
472
+ </td>
473
+ </tr>
474
+ <tr>
475
+ <td>Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ Ρ„Π°ΠΉΠ»ΠΎΠ²</td>
476
+ <td><tt>.erb</tt>, <tt>.rhtml</tt> or <tt>.erubis</tt> (Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Erubis)</td>
477
+ </tr>
478
+ <tr>
479
+ <td>ΠŸΡ€ΠΈΠΌΠ΅Ρ€</td>
480
+ <td><tt>erb :index</tt></td>
481
+ </tr>
482
+ </table>
483
+
484
+ #### Builder ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹
485
+
486
+ <table>
487
+ <tr>
488
+ <td>Зависимости</td>
489
+ <td>
490
+ <a href="http://builder.rubyforge.org/" title="builder">builder</a>
491
+ </td>
492
+ </tr>
493
+ <tr>
494
+ <td>Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ Ρ„Π°ΠΉΠ»ΠΎΠ²</td>
495
+ <td><tt>.builder</tt></td>
496
+ </tr>
497
+ <tr>
498
+ <td>ΠŸΡ€ΠΈΠΌΠ΅Ρ€</td>
499
+ <td><tt>builder { |xml| xml.em "hi" }</tt></td>
500
+ </tr>
501
+ </table>
502
+
503
+ Π‘Π»ΠΎΠΊ Ρ‚Π°ΠΊΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΈ для встроСнных шаблонов (см. ΠΏΡ€ΠΈΠΌΠ΅Ρ€).
504
+
505
+ #### Nokogiri ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹
506
+
507
+ <table>
508
+ <tr>
509
+ <td>Зависимости</td>
510
+ <td><a href="http://nokogiri.org/" title="nokogiri">nokogiri</a></td>
511
+ </tr>
512
+ <tr>
513
+ <td>Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ Ρ„Π°ΠΉΠ»ΠΎΠ²</td>
514
+ <td><tt>.nokogiri</tt></td>
515
+ </tr>
516
+ <tr>
517
+ <td>ΠŸΡ€ΠΈΠΌΠ΅Ρ€</td>
518
+ <td><tt>nokogiri { |xml| xml.em "hi" }</tt></td>
519
+ </tr>
520
+ </table>
521
+
522
+ Π‘Π»ΠΎΠΊ Ρ‚Π°ΠΊΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΈ для встроСнных шаблонов (см. ΠΏΡ€ΠΈΠΌΠ΅Ρ€).
523
+
524
+ #### Sass ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹
525
+
526
+ <table>
527
+ <tr>
528
+ <td>Зависимости</td>
529
+ <td><a href="http://sass-lang.com/" title="sass">sass</a></td>
530
+ </tr>
531
+ <tr>
532
+ <td>Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ Ρ„Π°ΠΉΠ»ΠΎΠ²</td>
533
+ <td><tt>.sass</tt></td>
534
+ </tr>
535
+ <tr>
536
+ <td>ΠŸΡ€ΠΈΠΌΠ΅Ρ€</td>
537
+ <td><tt>sass :stylesheet, :style => :expanded</tt></td>
538
+ </tr>
539
+ </table>
540
+
541
+ #### SCSS ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹
542
+
543
+ <table>
544
+ <tr>
545
+ <td>Зависимости</td>
546
+ <td><a href="http://sass-lang.com/" title="sass">sass</a></td>
547
+ </tr>
548
+ <tr>
549
+ <td>Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ Ρ„Π°ΠΉΠ»ΠΎΠ²</td>
550
+ <td><tt>.scss</tt></td>
551
+ </tr>
552
+ <tr>
553
+ <td>ΠŸΡ€ΠΈΠΌΠ΅Ρ€</td>
554
+ <td><tt>scss :stylesheet, :style => :expanded</tt></td>
555
+ </tr>
556
+ </table>
557
+
558
+ #### Less ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹
559
+
560
+ <table>
561
+ <tr>
562
+ <td>Зависимости</td>
563
+ <td><a href="http://www.lesscss.org/" title="less">less</a></td>
564
+ </tr>
565
+ <tr>
566
+ <td>Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ Ρ„Π°ΠΉΠ»ΠΎΠ²</td>
567
+ <td><tt>.less</tt></td>
568
+ </tr>
569
+ <tr>
570
+ <td>ΠŸΡ€ΠΈΠΌΠ΅Ρ€</td>
571
+ <td><tt>less :stylesheet</tt></td>
572
+ </tr>
573
+ </table>
574
+
575
+ #### Liquid ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹
576
+
577
+ <table>
578
+ <tr>
579
+ <td>Зависимости</td>
580
+ <td><a href="http://www.liquidmarkup.org/" title="liquid">liquid</a></td>
581
+ </tr>
582
+ <tr>
583
+ <td>Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ Ρ„Π°ΠΉΠ»ΠΎΠ²</td>
584
+ <td><tt>.liquid</tt></td>
585
+ </tr>
586
+ <tr>
587
+ <td>ΠŸΡ€ΠΈΠΌΠ΅Ρ€</td>
588
+ <td><tt>liquid :index, :locals => { :key => 'value' }</tt></td>
589
+ </tr>
590
+ </table>
591
+
592
+ Π’Π°ΠΊ ΠΊΠ°ΠΊ Π² Liquid ΡˆΠ°Π±Π»ΠΎΠ½Π°Ρ… Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΈΠ· Ruby (ΠΊΡ€ΠΎΠΌΠ΅ `yield`), Ρ‚ΠΎ
593
+ Π²Ρ‹ ΠΏΠΎΡ‡Ρ‚ΠΈ всСгда Π±ΡƒΠ΄Π΅Ρ‚Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Π² шаблон Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅.
594
+
595
+ #### Markdown ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹
596
+
597
+ <table>
598
+ <tr>
599
+ <td>Зависимости</td>
600
+ <td>
601
+ Π›ΡŽΠ±Π°Ρ ΠΈΠ· Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ:
602
+ <a href="https://github.com/rtomayko/rdiscount" title="RDiscount">RDiscount</a>,
603
+ <a href="https://github.com/vmg/redcarpet" title="RedCarpet">RedCarpet</a>,
604
+ <a href="http://deveiate.org/projects/BlueCloth" title="BlueCloth">BlueCloth</a>,
605
+ <a href="http://kramdown.rubyforge.org/" title="kramdown">kramdown</a>,
606
+ <a href="http://maruku.rubyforge.org/" title="maruku">maruku</a>
607
+ </td>
608
+ </tr>
609
+ <tr>
610
+ <td>Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ Ρ„Π°ΠΉΠ»ΠΎΠ²</td>
611
+ <td><tt>.markdown</tt>, <tt>.mkd</tt> and <tt>.md</tt></td>
612
+ </tr>
613
+ <tr>
614
+ <td>ΠŸΡ€ΠΈΠΌΠ΅Ρ€</td>
615
+ <td><tt>markdown :index, :layout_engine => :erb</tt></td>
616
+ </tr>
617
+ </table>
618
+
619
+ Π’ Markdown Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΈΠ»ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅.
620
+ Π‘Π»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, Π²Π°ΠΌ, скорСС всСго, придСтся ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ этот шаблон совмСстно
621
+ с Π΄Ρ€ΡƒΠ³ΠΈΠΌ ΡˆΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°Ρ‚ΠΎΡ€ΠΎΠΌ:
622
+
623
+ ```ruby
624
+ erb :overview, :locals => { :text => markdown(:introduction) }
625
+ ```
626
+
627
+ Π—Π°ΠΌΠ΅Ρ‚ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄ `markdown` ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΈΡ… шаблонов:
628
+
629
+ ```ruby
630
+ %h1 Hello From Haml!
631
+ %p= markdown(:greetings)
632
+ ```
633
+
634
+ Π’Ρ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Ruby ΠΈΠ· Markdown, соотвСтствСнно, Π²Ρ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅
635
+ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ лэйауты Π½Π° Markdown. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, Π΅ΡΡ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ
636
+ ΠΎΠ΄ΠΈΠ½ ΡˆΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°Ρ‚ΠΎΡ€ для отобраТСния шаблона, Π° Π΄Ρ€ΡƒΠ³ΠΎΠΉ для лэйаута с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ
637
+ ΠΎΠΏΡ†ΠΈΠΈ `:layout_engine`.
638
+
639
+ #### Textile ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹
640
+
641
+ <table>
642
+ <tr>
643
+ <td>Зависимости</td>
644
+ <td><a href="http://redcloth.org/" title="RedCloth">RedCloth</a></td>
645
+ </tr>
646
+ <tr>
647
+ <td>Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ Ρ„Π°ΠΉΠ»ΠΎΠ²</td>
648
+ <td><tt>.textile</tt></td>
649
+ </tr>
650
+ <tr>
651
+ <td>ΠŸΡ€ΠΈΠΌΠ΅Ρ€</td>
652
+ <td><tt>textile :index, :layout_engine => :erb</tt></td>
653
+ </tr>
654
+ </table>
655
+
656
+ Π’ Textile Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΈΠ»ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅.
657
+ Π‘Π»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, Π²Π°ΠΌ, скорСС всСго, придСтся ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ этот шаблон совмСстно
658
+ с Π΄Ρ€ΡƒΠ³ΠΈΠΌ ΡˆΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°Ρ‚ΠΎΡ€ΠΎΠΌ:
659
+
660
+ ```ruby
661
+ erb :overview, :locals => { :text => textile(:introduction) }
662
+ ```
663
+
664
+ Π—Π°ΠΌΠ΅Ρ‚ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄ `textile` ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΈΡ… шаблонов:
665
+
666
+ ```ruby
667
+ %h1 Hello From Haml!
668
+ %p= textile(:greetings)
669
+ ```
670
+
671
+ Π’Ρ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Ruby ΠΈΠ· Textile, соотвСтствСнно, Π²Ρ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅
672
+ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ лэйауты Π½Π° Textile. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, Π΅ΡΡ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ
673
+ ΠΎΠ΄ΠΈΠ½ ΡˆΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°Ρ‚ΠΎΡ€ для отобраТСния шаблона, Π° Π΄Ρ€ΡƒΠ³ΠΎΠΉ для лэйаута с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ
674
+ ΠΎΠΏΡ†ΠΈΠΈ `:layout_engine`.
675
+
676
+ #### RDoc ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹
677
+
678
+ <table>
679
+ <tr>
680
+ <td>Зависимости</td>
681
+ <td><a href="http://rdoc.rubyforge.org/" title="RDoc">RDoc</a></td>
682
+ </tr>
683
+ <tr>
684
+ <td>Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ Ρ„Π°ΠΉΠ»ΠΎΠ²</td>
685
+ <td><tt>.rdoc</tt></td>
686
+ </tr>
687
+ <tr>
688
+ <td>ΠŸΡ€ΠΈΠΌΠ΅Ρ€</td>
689
+ <td><tt>rdoc :README, :layout_engine => :erb</tt></td>
690
+ </tr>
691
+ </table>
692
+
693
+ Π’ RDoc Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΈΠ»ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅.
694
+ Π‘Π»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, Π²Π°ΠΌ, скорСС всСго, придСтся ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ этот шаблон совмСстно
695
+ с Π΄Ρ€ΡƒΠ³ΠΈΠΌ ΡˆΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°Ρ‚ΠΎΡ€ΠΎΠΌ:
696
+
697
+ ```ruby
698
+ erb :overview, :locals => { :text => rdoc(:introduction) }
699
+ ```
700
+
701
+ Π—Π°ΠΌΠ΅Ρ‚ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄ `rdoc` ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΈΡ… шаблонов:
702
+
703
+ ```ruby
704
+ %h1 Hello From Haml!
705
+ %p= rdoc(:greetings)
706
+ ```
707
+
708
+ Π’Ρ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Ruby ΠΈΠ· RDoc, соотвСтствСнно, Π²Ρ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ
709
+ лэйауты Π½Π° RDoc. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, Π΅ΡΡ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½ ΡˆΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°Ρ‚ΠΎΡ€
710
+ для отобраТСния шаблона, Π° Π΄Ρ€ΡƒΠ³ΠΎΠΉ для лэйаута с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΎΠΏΡ†ΠΈΠΈ
711
+ `:layout_engine`.
712
+
713
+ #### AsciiDoc ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹
714
+
715
+ <table>
716
+ <tr>
717
+ <td>Зависимости</td>
718
+ <td><a href="http://asciidoctor.org/" title="Asciidoctor">Asciidoctor</a></td>
719
+ </tr>
720
+ <tr>
721
+ <td>Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ Ρ„Π°ΠΉΠ»ΠΎΠ²</td>
722
+ <td><tt>.asciidoc</tt>, <tt>.adoc</tt> ΠΈ <tt>.ad</tt></td>
723
+ </tr>
724
+ <tr>
725
+ <td>ΠŸΡ€ΠΈΠΌΠ΅Ρ€</td>
726
+ <td><tt>asciidoc :README, :layout_engine => :erb</tt></td>
727
+ </tr>
728
+ </table>
729
+
730
+ Π’Π°ΠΊ ΠΊΠ°ΠΊ Π² AsciiDoc ΡˆΠ°Π±Π»ΠΎΠ½Π°Ρ… Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΈΠ· Ruby Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ, Ρ‚ΠΎ Π²Ρ‹
731
+ ΠΏΠΎΡ‡Ρ‚ΠΈ всСгда Π±ΡƒΠ΄Π΅Ρ‚Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Π² шаблон Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅.
732
+
733
+ #### Radius ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹
734
+
735
+ <table>
736
+ <tr>
737
+ <td>Зависимости</td>
738
+ <td><a href="http://radius.rubyforge.org/" title="Radius">Radius</a></td>
739
+ </tr>
740
+ <tr>
741
+ <td>Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ Ρ„Π°ΠΉΠ»ΠΎΠ²</td>
742
+ <td><tt>.radius</tt></td>
743
+ </tr>
744
+ <tr>
745
+ <td>ΠŸΡ€ΠΈΠΌΠ΅Ρ€</td>
746
+ <td><tt>radius :index, :locals => { :key => 'value' }</tt></td>
747
+ </tr>
748
+ </table>
749
+
750
+ Π’Π°ΠΊ ΠΊΠ°ΠΊ Π² Radius ΡˆΠ°Π±Π»ΠΎΠ½Π°Ρ… Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΈΠ· Ruby Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ, Ρ‚ΠΎ Π²Ρ‹
751
+ ΠΏΠΎΡ‡Ρ‚ΠΈ всСгда Π±ΡƒΠ΄Π΅Ρ‚Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Π² шаблон Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅.
752
+
753
+ #### Markaby ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹
754
+
755
+ <table>
756
+ <tr>
757
+ <td>Зависимости</td>
758
+ <td><a href="http://markaby.github.com/" title="Markaby">Markaby</a></td>
759
+ </tr>
760
+ <tr>
761
+ <td>Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ Ρ„Π°ΠΉΠ»ΠΎΠ²</td>
762
+ <td><tt>.mab</tt></td>
763
+ </tr>
764
+ <tr>
765
+ <td>ΠŸΡ€ΠΈΠΌΠ΅Ρ€</td>
766
+ <td><tt>markaby { h1 "Welcome!" }</tt></td>
767
+ </tr>
768
+ </table>
769
+
770
+ Π‘Π»ΠΎΠΊ Ρ‚Π°ΠΊΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΈ для встроСнных шаблонов (см. ΠΏΡ€ΠΈΠΌΠ΅Ρ€).
771
+
772
+ #### RABL ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹
773
+
774
+ <table>
775
+ <tr>
776
+ <td>Зависимости</td>
777
+ <td><a href="https://github.com/nesquena/rabl" title="Rabl">Rabl</a></td>
778
+ </tr>
779
+ <tr>
780
+ <td>Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ Ρ„Π°ΠΉΠ»ΠΎΠ²</td>
781
+ <td><tt>.rabl</tt></td>
782
+ </tr>
783
+ <tr>
784
+ <td>ΠŸΡ€ΠΈΠΌΠ΅Ρ€</td>
785
+ <td><tt>rabl :index</tt></td>
786
+ </tr>
787
+ </table>
788
+
789
+ #### Slim ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹
790
+
791
+ <table>
792
+ <tr>
793
+ <td>Зависимости</td>
794
+ <td><a href="http://slim-lang.com/" title="Slim Lang">Slim Lang</a></td>
795
+ </tr>
796
+ <tr>
797
+ <td>Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ Ρ„Π°ΠΉΠ»ΠΎΠ²</td>
798
+ <td><tt>.slim</tt></td>
799
+ </tr>
800
+ <tr>
801
+ <td>ΠŸΡ€ΠΈΠΌΠ΅Ρ€</td>
802
+ <td><tt>slim :index</tt></td>
803
+ </tr>
804
+ </table>
805
+
806
+ #### Creole ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹
807
+
808
+ <table>
809
+ <tr>
810
+ <td>Зависимости</td>
811
+ <td><a href="https://github.com/minad/creole" title="Creole">Creole</a></td>
812
+ </tr>
813
+ <tr>
814
+ <td>Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ Ρ„Π°ΠΉΠ»ΠΎΠ²</td>
815
+ <td><tt>.creole</tt></td>
816
+ </tr>
817
+ <tr>
818
+ <td>ΠŸΡ€ΠΈΠΌΠ΅Ρ€</td>
819
+ <td><tt>creole :wiki, :layout_engine => :erb</tt></td>
820
+ </tr>
821
+ </table>
822
+
823
+ Π’ Creole Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΈΠ»ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅.
824
+ Π‘Π»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, Π²Π°ΠΌ, скорСС всСго, придСтся ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ этот шаблон совмСстно
825
+ с Π΄Ρ€ΡƒΠ³ΠΈΠΌ ΡˆΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°Ρ‚ΠΎΡ€ΠΎΠΌ:
826
+
827
+ ```ruby
828
+ erb :overview, :locals => { :text => creole(:introduction) }
829
+ ```
830
+
831
+ Π—Π°ΠΌΠ΅Ρ‚ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄ `creole` ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΈΡ… шаблонов:
832
+
833
+ ```ruby
834
+ %h1 Hello From Haml!
835
+ %p= creole(:greetings)
836
+ ```
837
+
838
+ Π’Ρ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Ruby ΠΈΠ· Creole, соотвСтствСнно, Π²Ρ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅
839
+ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ лэйауты Π½Π° Creole. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, Π΅ΡΡ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ
840
+ ΠΎΠ΄ΠΈΠ½ ΡˆΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°Ρ‚ΠΎΡ€ для отобраТСния шаблона, Π° Π΄Ρ€ΡƒΠ³ΠΎΠΉ для лэйаута с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ
841
+ ΠΎΠΏΡ†ΠΈΠΈ `:layout_engine`.
842
+
843
+ #### MediaWiki ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹
844
+
845
+ <table>
846
+ <tr>
847
+ <td>Зависимости</td>
848
+ <td><a href="https://github.com/nricciar/wikicloth" title="WikiCloth">WikiCloth</a></td>
849
+ </tr>
850
+ <tr>
851
+ <td>Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ Ρ„Π°ΠΉΠ»ΠΎΠ²</td>
852
+ <td><tt>.mediawiki</tt> ΠΈ <tt>.mw</tt></td>
853
+ </tr>
854
+ <tr>
855
+ <td>ΠŸΡ€ΠΈΠΌΠ΅Ρ€</td>
856
+ <td><tt>mediawiki :wiki, :layout_engine => :erb</tt></td>
857
+ </tr>
858
+ </table>
859
+
860
+ Π’ Ρ€Π°Π·ΠΌΠ΅Ρ‚ΠΊΠ΅ MediaWiki Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΈΠ»ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅.
861
+ Π‘Π»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, Π²Π°ΠΌ, скорСС всСго, придСтся ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ этот шаблон совмСстно
862
+ с Π΄Ρ€ΡƒΠ³ΠΈΠΌ ΡˆΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°Ρ‚ΠΎΡ€ΠΎΠΌ:
863
+
864
+ ```ruby
865
+ erb :overview, :locals => { :text => mediawiki(:introduction) }
866
+ ```
867
+
868
+ Π—Π°ΠΌΠ΅Ρ‚ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄ `mediawiki` ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΈΡ… шаблонов:
869
+
870
+ ```ruby
871
+ %h1 Hello From Haml!
872
+ %p= mediawiki(:greetings)
873
+ ```
874
+
875
+ Π’Ρ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Ruby ΠΈΠ· MediaWiki, соотвСтствСнно, Π²Ρ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅
876
+ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ лэйауты Π½Π° MediaWiki. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, Π΅ΡΡ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ
877
+ ΠΎΠ΄ΠΈΠ½ ΡˆΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°Ρ‚ΠΎΡ€ для отобраТСния шаблона, Π° Π΄Ρ€ΡƒΠ³ΠΎΠΉ для лэйаута с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ
878
+ ΠΎΠΏΡ†ΠΈΠΈ `:layout_engine`.
879
+
880
+ #### CoffeeScript ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹
881
+
882
+ <table>
883
+ <tr>
884
+ <td>Зависимости</td>
885
+ <td>
886
+ <a href="https://github.com/josh/ruby-coffee-script" title="Ruby CoffeeScript">
887
+ CoffeeScript
888
+ </a> и способ
889
+ <a href="https://github.com/sstephenson/execjs/blob/master/README.md#readme" title="ExecJS">
890
+ Π·Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ JavaScript
891
+ </a>
892
+ </td>
893
+ </tr>
894
+ <tr>
895
+ <td>Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ Ρ„Π°ΠΉΠ»ΠΎΠ²</td>
896
+ <td><tt>.coffee</tt></td>
897
+ </tr>
898
+ <tr>
899
+ <td>ΠŸΡ€ΠΈΠΌΠ΅Ρ€</td>
900
+ <td><tt>coffee :index</tt></td>
901
+ </tr>
902
+ </table>
903
+
904
+ #### Yajl ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹
905
+
906
+ <table>
907
+ <tr>
908
+ <td>Зависимости</td>
909
+ <td><a href="https://github.com/brianmario/yajl-ruby" title="yajl-ruby">yajl-ruby</a></td>
910
+ </tr>
911
+ <tr>
912
+ <td>Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ Ρ„Π°ΠΉΠ»ΠΎΠ²</td>
913
+ <td><tt>.yajl</tt></td>
914
+ </tr>
915
+ <tr>
916
+ <td>ΠŸΡ€ΠΈΠΌΠ΅Ρ€</td>
917
+ <td>
918
+ <tt>
919
+ yajl :index,
920
+ :locals => { :key => 'qux' },
921
+ :callback => 'present',
922
+ :variable => 'resource'
923
+ </tt>
924
+ </td>
925
+ </tr>
926
+ </table>
927
+
928
+ Π‘ΠΎΠ΄Π΅Ρ€ΠΆΠΈΠΌΠΎΠ΅ шаблона интСрпрСтируСтся ΠΊΠ°ΠΊ ΠΊΠΎΠ΄ Π½Π° Ruby, Π° Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π°Ρ
929
+ пСрСмСнная json Π·Π°Ρ‚Π΅ΠΌ конвСртируСтся с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ `#to_json`.
930
+
931
+ ```ruby
932
+ json = { :foo => 'bar' }
933
+ json[:baz] = key
934
+ ```
935
+
936
+ ΠžΠΏΡ†ΠΈΠΈ `:callback` ΠΈ `:variable` ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ для "дСкорирования" ΠΈΡ‚ΠΎΠ³ΠΎΠ²ΠΎΠ³ΠΎ
937
+ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.
938
+
939
+ ```ruby
940
+ var resource = {"foo":"bar","baz":"qux"}; present(resource);
941
+ ```
942
+
943
+ #### WLang ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹
944
+
945
+ <table>
946
+ <tr>
947
+ <td>Зависимости</td>
948
+ <td><a href="https://github.com/blambeau/wlang/" title="wlang">wlang</a></td>
949
+ </tr>
950
+ <tr>
951
+ <td>Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ Ρ„Π°ΠΉΠ»ΠΎΠ²</td>
952
+ <td><tt>.wlang</tt></td>
953
+ </tr>
954
+ <tr>
955
+ <td>ΠŸΡ€ΠΈΠΌΠ΅Ρ€</td>
956
+ <td><tt>wlang :index, :locals => { :key => 'value' }</tt></td>
957
+ </tr>
958
+ </table>
959
+
960
+ Π’Π°ΠΊ ΠΊΠ°ΠΊ Π² WLang ΡˆΠ°Π±Π»ΠΎΠ½Π°Ρ… Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΈΠ· Ruby Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ (Π·Π°
961
+ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ `yield`), Ρ‚ΠΎ Π²Ρ‹ ΠΏΠΎΡ‡Ρ‚ΠΈ всСгда Π±ΡƒΠ΄Π΅Ρ‚Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Π² шаблон Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅
962
+ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅.
963
+
964
+ ### Доступ ΠΊ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌ Π² ΡˆΠ°Π±Π»ΠΎΠ½Π°Ρ…
965
+
966
+ Π¨Π°Π±Π»ΠΎΠ½Ρ‹ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚ΠΈΡ€ΡƒΡŽΡ‚ΡΡ Π² Ρ‚ΠΎΠΌ ΠΆΠ΅ контСкстС, Ρ‡Ρ‚ΠΎ ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΎΠ².
967
+ ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ экзСмпляра, установлСнныС Π² процСссС ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΎΠ², Π±ΡƒΠ΄ΡƒΡ‚
968
+ доступны Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ Π² ΡˆΠ°Π±Π»ΠΎΠ½Π°Ρ…:
969
+
970
+ ```ruby
971
+ get '/:id' do
972
+ @foo = Foo.find(params[:id])
973
+ haml '%h1= @foo.name'
974
+ end
975
+ ```
976
+
977
+ Π›ΠΈΠ±ΠΎ установитС ΠΈΡ… Ρ‡Π΅Ρ€Π΅Π· Ρ…Π΅Ρˆ Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Ρ… ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…:
978
+
979
+ ```ruby
980
+ get '/:id' do
981
+ foo = Foo.find(params[:id])
982
+ haml '%h1= bar.name', :locals => { :bar => foo }
983
+ end
984
+ ```
985
+
986
+ Π­Ρ‚ΠΎ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄, ΠΊΠΎΠ³Π΄Π° ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹ рСндСрятся ΠΊΠ°ΠΊ части Π΄Ρ€ΡƒΠ³ΠΈΡ… шаблонов.
987
+
988
+ ### Π¨Π°Π±Π»ΠΎΠ½Ρ‹ с `yield` ΠΈ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ раскладки (layout)
989
+
990
+ Раскладка (layout) ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ прСдставляСт собой шаблон, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ исполняСт
991
+ `yield`.
992
+ Π’Π°ΠΊΠΎΠΉ шаблон ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π»ΠΈΠ±ΠΎ использован с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΎΠΏΡ†ΠΈΠΈ `:template`,
993
+ ΠΊΠ°ΠΊ описано Π²Ρ‹ΡˆΠ΅, Π»ΠΈΠ±ΠΎ ΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ Π±Π»ΠΎΠΊΠΎΠΌ:
994
+
995
+ ```ruby
996
+ erb :post, :layout => false do
997
+ erb :index
998
+ end
999
+ ```
1000
+
1001
+ Π­Ρ‚ΠΈ инструкции Π² основном эквивалСнтны `erb :index, :layout => :post`.
1002
+
1003
+ ΠŸΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° Π±Π»ΠΎΠΊΠΎΠ² ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΌ ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹ ΠΌΠ΅Ρ‚ΠΎΠ΄Π°ΠΌ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ»Π΅Π·Π½Π° для
1004
+ создания Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Ρ… раскладок:
1005
+
1006
+ ```ruby
1007
+ erb :main_layout, :layout => false do
1008
+ erb :admin_layout do
1009
+ erb :user
1010
+ end
1011
+ end
1012
+ ```
1013
+
1014
+ Π­Ρ‚ΠΎ ΠΆΠ΅ самоС ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ сдСлано ΠΊΠΎΡ€ΠΎΡ‡Π΅:
1015
+
1016
+ ```ruby
1017
+ erb :admin_layout, :layout => :main_layout do
1018
+ erb :user
1019
+ end
1020
+ ```
1021
+
1022
+ Π’ настоящСС врСмя, ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠ΅ ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹
1023
+ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‚ Π±Π»ΠΎΠΊ:
1024
+ `erb`, `haml`, `liquid`, `slim `, `wlang`.
1025
+ ΠžΠ±Ρ‰ΠΈΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ заполнСния шаблонов `render` Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π±Π»ΠΎΠΊ.
1026
+
1027
+ ### Π’ΠΊΠ»ΡŽΡ‡Ρ‘Π½Π½Ρ‹Π΅ ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹
1028
+
1029
+ Π¨Π°Π±Π»ΠΎΠ½Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Ρ‹ Π² ΠΊΠΎΠ½Ρ†Π΅ исходного Ρ„Π°ΠΉΠ»Π°:
1030
+
1031
+ ```ruby
1032
+ require 'sinatra'
1033
+
1034
+ get '/' do
1035
+ haml :index
1036
+ end
1037
+
1038
+ __END__
1039
+
1040
+ @@ layout
1041
+ %html
1042
+ = yield
1043
+
1044
+ @@ index
1045
+ %div.title Hello world.
1046
+ ```
1047
+
1048
+ Π—Π°ΠΌΠ΅Ρ‚ΡŒΡ‚Π΅: Π²ΠΊΠ»ΡŽΡ‡Ρ‘Π½Π½Ρ‹Π΅ ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹, ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Π΅ Π² исходном Ρ„Π°ΠΉΠ»Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΠ»
1049
+ Sinatra, Π±ΡƒΠ΄ΡƒΡ‚ Π·Π°Π³Ρ€ΡƒΠΆΠ΅Π½Ρ‹ автоматичСски. Π’Ρ‹Π·ΠΎΠ²ΠΈΡ‚Π΅ `enable :inline_templates`
1050
+ Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ, Ссли ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ Π²ΠΊΠ»ΡŽΡ‡Ρ‘Π½Π½Ρ‹Π΅ ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹ Π² Π΄Ρ€ΡƒΠ³ΠΈΡ… Ρ„Π°ΠΉΠ»Π°Ρ….
1051
+
1052
+ ### Π˜ΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹Π΅ ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹
1053
+
1054
+ Π¨Π°Π±Π»ΠΎΠ½Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Ρ‹ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ `template` ΠΌΠ΅Ρ‚ΠΎΠ΄Π°:
1055
+
1056
+ ```ruby
1057
+ template :layout do
1058
+ "%html\n =yield\n"
1059
+ end
1060
+
1061
+ template :index do
1062
+ '%div.title Hello World!'
1063
+ end
1064
+
1065
+ get '/' do
1066
+ haml :index
1067
+ end
1068
+ ```
1069
+
1070
+ Если шаблон с ΠΈΠΌΠ΅Π½Π΅ΠΌ "layout" сущСствуСт, Ρ‚ΠΎ ΠΎΠ½ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ
1071
+ Ρ€Π°Π· ΠΏΡ€ΠΈ Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠ½Π³Π΅. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ лэйаут Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΌ случаС с
1072
+ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ `:layout => false` ΠΈΠ»ΠΈ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Π΅Π³ΠΎ для всСго прилоТСния: `set :haml,
1073
+ :layout => false`:
1074
+
1075
+ ```ruby
1076
+ get '/' do
1077
+ haml :index, :layout => !request.xhr?
1078
+ end
1079
+ ```
1080
+
1081
+ ### ΠŸΡ€ΠΈΠ²ΡΠ·ΠΊΠ° Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹Ρ… Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠΉ
1082
+
1083
+ Π§Ρ‚ΠΎΠ±Ρ‹ ΡΠ²ΡΠ·Π°Ρ‚ΡŒ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ Ρ„Π°ΠΉΠ»Π° с Π΄Π²ΠΈΠΆΠΊΠΎΠΌ Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠ½Π³Π°, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅
1084
+ `Tilt.register`. НапримСр, Ссли Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ `tt` для
1085
+ шаблонов Textile:
1086
+
1087
+ ```ruby
1088
+ Tilt.register :tt, Tilt[:textile]
1089
+ ```
1090
+
1091
+ ### Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ собствСнного Π΄Π²ΠΈΠΆΠΊΠ° Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠ½Π³Π°
1092
+
1093
+ Π‘Π½Π°Ρ‡Π°Π»Π° зарСгистрируйтС свой Π΄Π²ΠΈΠΆΠΎΠΊ Π² Tilt, Π° Π·Π°Ρ‚Π΅ΠΌ создайтС ΠΌΠ΅Ρ‚ΠΎΠ΄, ΠΎΡ‚Π²Π΅Ρ‡Π°ΡŽΡ‰ΠΈΠΉ
1094
+ Π·Π° Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠ½Π³:
1095
+
1096
+ ```ruby
1097
+ Tilt.register :myat, MyAwesomeTemplateEngine
1098
+
1099
+ helpers do
1100
+ def myat(*args) render(:myat, *args) end
1101
+ end
1102
+
1103
+ get '/' do
1104
+ myat :index
1105
+ end
1106
+ ```
1107
+
1108
+ ΠžΡ‚ΠΎΠ±Ρ€Π°Π·ΠΈΡ‚ `./views/index.myat`. Π§Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ·Π½Π°Ρ‚ΡŒ большС ΠΎ Tilt, смотритС
1109
+ https://github.com/rtomayko/tilt
1110
+
1111
+ ## Π€ΠΈΠ»ΡŒΡ‚Ρ€Ρ‹
1112
+
1113
+ `before`-Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Ρ‹ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ ΠΏΠ΅Ρ€Π΅Π΄ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΌ запросом Π² Ρ‚ΠΎΠΌ ΠΆΠ΅ контСкстС, Ρ‡Ρ‚ΠΎ ΠΈ
1114
+ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Ρ‹, ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ ΠΊΠ°ΠΊ запрос, Ρ‚Π°ΠΊ ΠΈ ΠΎΡ‚Π²Π΅Ρ‚ Π½Π° Π½Π΅Π³ΠΎ. ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅
1115
+ экзСмпляра, установлСнныС Π² Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°Ρ…, доступны Π² ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π°Ρ… ΠΈ ΡˆΠ°Π±Π»ΠΎΠ½Π°Ρ…:
1116
+
1117
+ ```ruby
1118
+ before do
1119
+ @note = 'Hi!'
1120
+ request.path_info = '/foo/bar/baz'
1121
+ end
1122
+
1123
+ get '/foo/*' do
1124
+ @note #=> 'Hi!'
1125
+ params[:splat] #=> 'bar/baz'
1126
+ end
1127
+ ```
1128
+
1129
+ `after`-Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Ρ‹ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ послС ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ запроса Π² Ρ‚ΠΎΠΌ ΠΆΠ΅ контСкстС
1130
+ ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ ΠΊΠ°ΠΊ запрос, Ρ‚Π°ΠΊ ΠΈ ΠΎΡ‚Π²Π΅Ρ‚ Π½Π° Π½Π΅Π³ΠΎ. ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅
1131
+ экзСмпляра, установлСнныС Π² `before`-Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°Ρ… ΠΈ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π°Ρ…, Π±ΡƒΠ΄ΡƒΡ‚ доступны Π²
1132
+ `after`-Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°Ρ…:
1133
+
1134
+ ```ruby
1135
+ after do
1136
+ puts response.status
1137
+ end
1138
+ ```
1139
+
1140
+ Π—Π°ΠΌΠ΅Ρ‚ΡŒΡ‚Π΅: Ссли Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄ `body`, Π° Π½Π΅ просто Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚Π΅ строку ΠΈΠ·
1141
+ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π°, Ρ‚ΠΎ Ρ‚Π΅Π»ΠΎ ΠΎΡ‚Π²Π΅Ρ‚Π° Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ доступно Π² `after`-Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°Ρ…, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΎΠ½ΠΎ
1142
+ Π±ΡƒΠ΄Π΅Ρ‚ сгСнСрировано ΠΏΠΎΠ·Π΄Π½Π΅Π΅.
1143
+
1144
+ Π€ΠΈΠ»ΡŒΡ‚Ρ€Ρ‹ ΠΌΠΎΠ³ΡƒΡ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹ URL ΠΈ Π±ΡƒΠ΄ΡƒΡ‚ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ссли
1145
+ ΠΏΡƒΡ‚ΡŒ запроса совпадСт с этим шаблоном:
1146
+
1147
+ ```ruby
1148
+ before '/protected/*' do
1149
+ authenticate!
1150
+ end
1151
+
1152
+ after '/create/:slug' do |slug|
1153
+ session[:last_slug] = slug
1154
+ end
1155
+ ```
1156
+
1157
+ Как ΠΈ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Ρ‹, Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Ρ‹ ΠΌΠΎΠ³ΡƒΡ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ условия:
1158
+
1159
+ ```ruby
1160
+ before :agent => /Songbird/ do
1161
+ # ...
1162
+ end
1163
+
1164
+ after '/blog/*', :host_name => 'example.com' do
1165
+ # ...
1166
+ end
1167
+ ```
1168
+
1169
+ ## ΠœΠ΅Ρ‚ΠΎΠ΄Ρ‹-ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠΈ
1170
+
1171
+ Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄ `helpers`, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹-ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²
1172
+ дальнСйшСм ΠΌΠΎΠΆΠ½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°Ρ… ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΎΠ² ΠΈ ΡˆΠ°Π±Π»ΠΎΠ½Π°Ρ…:
1173
+
1174
+ ```ruby
1175
+ helpers do
1176
+ def bar(name)
1177
+ "#{name}bar"
1178
+ end
1179
+ end
1180
+
1181
+ get '/:name' do
1182
+ bar(params[:name])
1183
+ end
1184
+ ```
1185
+
1186
+ Π’Π°ΠΊΠΆΠ΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹-ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Π·Π°Π΄Π°Π½Ρ‹ Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Ρ… модулях:
1187
+
1188
+ ```ruby
1189
+ module FooUtils
1190
+ def foo(name) "#{name}foo" end
1191
+ end
1192
+
1193
+ module BarUtils
1194
+ def bar(name) "#{name}bar" end
1195
+ end
1196
+
1197
+ helpers FooUtils, BarUtils
1198
+ ```
1199
+
1200
+ Π­Ρ„Ρ„Π΅ΠΊΡ‚ равносилСн Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡŽ ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ Π² класс прилоТСния.
1201
+
1202
+ ### ИспользованиС сСссий
1203
+
1204
+ БСссия ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠΎΡ…Ρ€Π°Π½ΡΡ‚ΡŒ состояниС ΠΌΠ΅ΠΆΠ΄Ρƒ запросами. Если эта опция
1205
+ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½Π°, Ρ‚ΠΎ Ρƒ вас Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠ΄ΠΈΠ½ Ρ…Π΅Ρˆ сСссии Π½Π° ΠΎΠ΄Π½Ρƒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΡƒΡŽ сСссию:
1206
+
1207
+ ```ruby
1208
+ enable :sessions
1209
+
1210
+ get '/' do
1211
+ "value = " << session[:value].inspect
1212
+ end
1213
+
1214
+ get '/:value' do
1215
+ session[:value] = params[:value]
1216
+ end
1217
+ ```
1218
+
1219
+ Π—Π°ΠΌΠ΅Ρ‚ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈ использовании `enable :sessions` всС Π΄Π°Π½Π½Ρ‹Π΅ ΡΠΎΡ…Ρ€Π°Π½ΡΡŽΡ‚ΡΡ Π²
1220
+ ΠΊΡƒΠΊΠ°Ρ… (cookies). Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π½Π΅ совсСм Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€,
1221
+ сохранСниС Π±ΠΎΠ»ΡŒΡˆΠΈΡ… объСмов Π΄Π°Π½Π½Ρ‹Ρ… ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΡ‚ ваш Ρ‚Ρ€Π°Ρ„ΠΈΠΊ). Π’ Ρ‚Π°ΠΊΠΎΠΌ случаС Π²Ρ‹
1222
+ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π°Π»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π½ΡƒΡŽ Rack "прослойку" (middleware), Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‰ΡƒΡŽ
1223
+ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ сСссий. Для этого *Π½Π΅ Π½Π°Π΄ΠΎ* Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ `enable :sessions`, вмСсто этого
1224
+ слСдуСт ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Π΅Π΅ Ρ‚Π°ΠΊ ΠΆΠ΅, ΠΊΠ°ΠΊ ΠΈ Π»ΡŽΠ±ΡƒΡŽ Π΄Ρ€ΡƒΠ³ΡƒΡŽ "прослойку":
1225
+
1226
+ ```ruby
1227
+ use Rack::Session::Pool, :expire_after => 2592000
1228
+
1229
+ get '/' do
1230
+ "value = " << session[:value].inspect
1231
+ end
1232
+
1233
+ get '/:value' do
1234
+ session[:value] = params[:value]
1235
+ end
1236
+ ```
1237
+
1238
+ Для ΠΏΠΎΠ²Ρ‹ΡˆΠ΅Π½ΠΈΡ бСзопасности Π΄Π°Π½Π½Ρ‹Π΅ сСссии Π² ΠΊΡƒΠΊΠ°Ρ… ΠΏΠΎΠ΄ΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ΡΡ сСкрСтным
1239
+ ΠΊΠ»ΡŽΡ‡ΠΎΠΌ. Π‘Π΅ΠΊΡ€Π΅Ρ‚Π½Ρ‹ΠΉ ΠΊΠ»ΡŽΡ‡ гСнСрируСтся Sinatra. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ этот ΠΊΠ»ΡŽΡ‡
1240
+ Π±ΡƒΠ΄Π΅Ρ‚ ΠΌΠ΅Π½ΡΡ‚ΡŒΡΡ с ΠΊΠ°ΠΆΠ΄Ρ‹ΠΌ запуском прилоТСния, Π²Ρ‹, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π·Π°Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ
1241
+ ΠΊΠ»ΡŽΡ‡ Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρƒ всСх экзСмпляров вашСго прилоТСния Π±Ρ‹Π» ΠΎΠ΄ΠΈΠ½ ΠΈ Ρ‚ΠΎΡ‚ ΠΆΠ΅
1242
+ ΠΊΠ»ΡŽΡ‡:
1243
+
1244
+ ```ruby
1245
+ set :session_secret, 'super secret'
1246
+ ```
1247
+
1248
+ Если Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ большС настроСк для сСссий, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π·Π°Π΄Π°Ρ‚ΡŒ ΠΈΡ…, ΠΏΠ΅Ρ€Π΅Π΄Π°Π² Ρ…Π΅Ρˆ
1249
+ ΠΎΠΏΡ†ΠΈΠΉ Π² ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ `sessions`:
1250
+
1251
+ ```ruby
1252
+ set :sessions, :domain => 'foo.com'
1253
+ ```
1254
+
1255
+ Π§Ρ‚ΠΎΠ±Ρ‹ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ сСссию доступной Π΄Ρ€ΡƒΠ³ΠΈΠΌ прилоТСниям, Ρ€Π°Π·ΠΌΠ΅Ρ‰Π΅Π½Π½Ρ‹ΠΌ Π½Π° ΠΏΠΎΠ΄Π΄ΠΎΠΌΠ΅Π½Π°Ρ…
1256
+ foo.com, Π΄ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ *.* ΠΏΠ΅Ρ€Π΅Π΄ Π΄ΠΎΠΌΠ΅Π½ΠΎΠΌ:
1257
+
1258
+ ``` ruby
1259
+ set :sessions, :domain => '.foo.com'
1260
+ ```
1261
+
1262
+ ### ΠŸΡ€Π΅Ρ€Ρ‹Π²Π°Π½ΠΈΠ΅
1263
+
1264
+ Π§Ρ‚ΠΎΠ±Ρ‹ Π½Π΅Π·Π°ΠΌΠ΅Π΄Π»ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΏΡ€Π΅Ρ€Π²Π°Ρ‚ΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ запроса Π²Π½ΡƒΡ‚Ρ€ΠΈ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π° ΠΈΠ»ΠΈ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π°,
1265
+ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅:
1266
+
1267
+ ```ruby
1268
+ halt
1269
+ ```
1270
+
1271
+ МоТно Ρ‚Π°ΠΊΠΆΠ΅ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ статус ΠΏΡ€ΠΈ ΠΏΡ€Π΅Ρ€Ρ‹Π²Π°Π½ΠΈΠΈ:
1272
+
1273
+ ```ruby
1274
+ halt 410
1275
+ ```
1276
+
1277
+ Π’Π΅Π»ΠΎ:
1278
+
1279
+ ```ruby
1280
+ halt 'this will be the body'
1281
+ ```
1282
+
1283
+ И Ρ‚ΠΎ, ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠ΅:
1284
+
1285
+ ```ruby
1286
+ halt 401, 'go away!'
1287
+ ```
1288
+
1289
+ МоТно ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ:
1290
+
1291
+ ```ruby
1292
+ halt 402, {'Content-Type' => 'text/plain'}, 'revenge'
1293
+ ```
1294
+
1295
+ И, ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ, ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹ с `halt`:
1296
+
1297
+ ```ruby
1298
+ halt erb(:error)
1299
+ ```
1300
+
1301
+ ### ΠŸΠ΅Ρ€Π΅Π΄Π°Ρ‡Π°
1302
+
1303
+ ΠœΠ°Ρ€ΡˆΡ€ΡƒΡ‚ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ запроса ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌΡƒ ΡΠΎΠ²ΠΏΠ°Π΄Π°ΡŽΡ‰Π΅ΠΌΡƒ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Ρƒ,
1304
+ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ `pass`:
1305
+
1306
+ ```ruby
1307
+ get '/guess/:who' do
1308
+ pass unless params[:who] == 'Frank'
1309
+ 'You got me!'
1310
+ end
1311
+
1312
+ get '/guess/*' do
1313
+ 'You missed!'
1314
+ end
1315
+ ```
1316
+
1317
+ Π‘Π»ΠΎΠΊ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π° сразу ΠΆΠ΅ прСрываСтся, ΠΈ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚ ΠΊ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌΡƒ
1318
+ ΡΠΎΠ²ΠΏΠ°Π΄Π°ΡŽΡ‰Π΅ΠΌΡƒ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Ρƒ. Если ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½, Ρ‚ΠΎ ΠΎΡ‚Π²Π΅Ρ‚ΠΎΠΌ Π½Π°
1319
+ запрос Π±ΡƒΠ΄Π΅Ρ‚ 404.
1320
+
1321
+ ### Π’Ρ‹Π·ΠΎΠ² Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π°
1322
+
1323
+ Иногда `pass` Π½Π΅ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ссли Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Π²Ρ‹Π·ΠΎΠ²Π°
1324
+ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π°. Π’ Ρ‚Π°ΠΊΠΎΠΌ случаС просто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ `call`:
1325
+
1326
+ ```ruby
1327
+ get '/foo' do
1328
+ status, headers, body = call env.merge("PATH_INFO" => '/bar')
1329
+ [status, headers, body.map(&:upcase)]
1330
+ end
1331
+
1332
+ get '/bar' do
1333
+ "bar"
1334
+ end
1335
+ ```
1336
+
1337
+ Π—Π°ΠΌΠ΅Ρ‚ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ Π² ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±Π»Π΅Π³Ρ‡ΠΈΡ‚ΡŒ тСстированиС ΠΈ ΠΏΠΎΠ²Ρ‹ΡΠΈΡ‚ΡŒ
1338
+ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ, пСрСнСся `"bar"` Π² ΠΌΠ΅Ρ‚ΠΎΠ΄-ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΉ ΠΈ Π²
1339
+ `/foo`, ΠΈ Π² `/bar`.
1340
+
1341
+ Если Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅, Ρ‡Ρ‚ΠΎΠ±Ρ‹ запрос Π±Ρ‹Π» ΠΎΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½ Π² Ρ‚ΠΎΡ‚ ΠΆΠ΅ экзСмпляр прилоТСния, Π° Π½Π΅
1342
+ Π² Π΅Π³ΠΎ копию, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ `call!` вмСсто `call`.
1343
+
1344
+ Если Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΡƒΠ·Π½Π°Ρ‚ΡŒ большС ΠΎ `call`, смотритС ΡΠΏΠ΅Ρ†ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΡŽ Rack.
1345
+
1346
+ ### Π—Π°Π΄Π°Π½ΠΈΠ΅ Ρ‚Π΅Π»Π°, ΠΊΠΎΠ΄Π° ΠΈ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ² ΠΎΡ‚Π²Π΅Ρ‚Π°
1347
+
1348
+ Π₯ΠΎΡ€ΠΎΡˆΠΈΠΌ Ρ‚ΠΎΠ½ΠΎΠΌ являСтся установка ΠΊΠΎΠ΄Π° состояния HTTP ΠΈ Ρ‚Π΅Π»Π° ΠΎΡ‚Π²Π΅Ρ‚Π° Π²
1349
+ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π°. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, Π² Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ…
1350
+ ситуациях Π²Π°ΠΌ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, понадобится Π·Π°Π΄Π°Ρ‚ΡŒ Ρ‚Π΅Π»ΠΎ ΠΎΡ‚Π²Π΅Ρ‚Π° Π² ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½ΠΎΠΉ Ρ‚ΠΎΡ‡ΠΊΠ΅
1351
+ ΠΏΠΎΡ‚ΠΎΠΊΠ° исполнСния. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ это с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΠ΅Ρ‚ΠΎΠ΄Π°-ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ° `body`.
1352
+ Если Π²Ρ‹ задСйствуСтС ΠΌΠ΅Ρ‚ΠΎΠ΄ `body`, Ρ‚ΠΎ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ ΠΈ Π²
1353
+ дальнСйшСм, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ доступ ΠΊ Ρ‚Π΅Π»Ρƒ ΠΎΡ‚Π²Π΅Ρ‚Π°.
1354
+
1355
+ ```ruby
1356
+ get '/foo' do
1357
+ body "bar"
1358
+ end
1359
+
1360
+ after do
1361
+ puts body
1362
+ end
1363
+ ```
1364
+
1365
+ Π’Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Π±Π»ΠΎΠΊ Π² ΠΌΠ΅Ρ‚ΠΎΠ΄ `body`, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π·Π°Ρ‚Π΅ΠΌ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π·Π²Π°Π½
1366
+ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠΌ Rack (Ρ‚Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ использован для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ
1367
+ ΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠ³ΠΎ ΠΎΡ‚Π²Π΅Ρ‚Π°, см. "Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Π΅ значСния").
1368
+
1369
+ Аналогично Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΊΠΎΠ΄ ΠΎΡ‚Π²Π΅Ρ‚Π° ΠΈ Π΅Π³ΠΎ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ:
1370
+
1371
+ ```ruby
1372
+ get '/foo' do
1373
+ status 418
1374
+ headers \
1375
+ "Allow" => "BREW, POST, GET, PROPFIND, WHEN",
1376
+ "Refresh" => "Refresh: 20; http://www.ietf.org/rfc/rfc2324.txt"
1377
+ body "I'm a tea pot!"
1378
+ end
1379
+ ```
1380
+
1381
+ Как ΠΈ `body`, ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ `headers` ΠΈ `status`, Π²Ρ‹Π·Π²Π°Π½Π½Ρ‹Π΅ Π±Π΅Π· Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ²,
1382
+ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ свои Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠ΅ значСния.
1383
+
1384
+ ### Π‘Ρ‚Ρ€ΠΈΠΌΠΈΠ½Π³ ΠΎΡ‚Π²Π΅Ρ‚ΠΎΠ²
1385
+
1386
+ Иногда трСбуСтся Π½Π°Ρ‡Π°Ρ‚ΡŒ ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ прямо Π² процСссС
1387
+ гСнСрирования частСй этих Π΄Π°Π½Π½Ρ‹Ρ…. Π’ особых случаях трСбуСтся постоянно
1388
+ ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π½Π΅ Π·Π°ΠΊΡ€ΠΎΠ΅Ρ‚ соСдинСниС. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅
1389
+ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄ `stream` вмСсто написания собствСнных "ΠΎΠ±Π΅Ρ€Ρ‚ΠΎΠΊ".
1390
+
1391
+ ```ruby
1392
+ get '/' do
1393
+ stream do |out|
1394
+ out << "It's gonna be legen -\n"
1395
+ sleep 0.5
1396
+ out << " (wait for it) \n"
1397
+ sleep 1
1398
+ out << "- dary!\n"
1399
+ end
1400
+ end
1401
+ ```
1402
+
1403
+ Π§Ρ‚ΠΎ позволяСт Π²Π°ΠΌ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ стриминговыС API,
1404
+ [Server Sent Events](http://dev.w3.org/html5/eventsource/),
1405
+ ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠ»ΡƒΠΆΠΈΡ‚ΡŒ основой для [WebSockets](http://en.wikipedia.org/wiki/WebSocket).
1406
+ Π’Π°ΠΊΠΆΠ΅ Ρ‚Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для увСличСния ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Π² случаС,
1407
+ ΠΊΠΎΠ³Π΄Π° какая-Ρ‚ΠΎ Ρ‡Π°ΡΡ‚ΡŒ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π° зависит ΠΎΡ‚ ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎΠ³ΠΎ рСсурса.
1408
+
1409
+ Π—Π°ΠΌΠ΅Ρ‚ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ возмоТности стриминга, особСнно количСство ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ
1410
+ обслуТиваСмых запросов, ΠΎΡ‡Π΅Π½ΡŒ сильно зависят ΠΎΡ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠ³ΠΎ Π²Π΅Π±-сСрвСра.
1411
+ НСкоторыС сСрвСры, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, WEBRick, ΠΌΠΎΠ³ΡƒΡ‚ ΠΈ вовсС Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ стриминг.
1412
+ Если сСрвСр Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ стриминг, Ρ‚ΠΎ всС Π΄Π°Π½Π½Ρ‹Π΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΎΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½Ρ‹ Π·Π° ΠΎΠ΄ΠΈΠ½
1413
+ Ρ€Π°Π· сразу послС Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ Π±Π»ΠΎΠΊ, ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹ΠΉ Π² `stream`, Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡΡ. Π‘Ρ‚Ρ€ΠΈΠΌΠΈΠ½Π³
1414
+ Π²ΠΎΠΎΠ±Ρ‰Π΅ Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΠΏΡ€ΠΈ использовании Shotgun.
1415
+
1416
+ Если ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ с ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠΌ `keep_open`, Ρ‚ΠΎ ΠΎΠ½ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ
1417
+ `close` Ρƒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΏΠΎΡ‚ΠΎΠΊΠ°, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ Π²Π°ΠΌ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΡŒ Π΅Π³ΠΎ ΠΏΠΎΠ·ΠΆΠ΅ Π² любом Π΄Ρ€ΡƒΠ³ΠΎΠΌ
1418
+ мСстС. Π­Ρ‚ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ с событийными сСрвСрами, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, с Thin ΠΈ
1419
+ Rainbows. Π”Ρ€ΡƒΠ³ΠΈΠ΅ ΠΆΠ΅ сСрвСры всС Ρ€Π°Π²Π½ΠΎ Π±ΡƒΠ΄ΡƒΡ‚ Π·Π°ΠΊΡ€Ρ‹Π²Π°Ρ‚ΡŒ ΠΏΠΎΡ‚ΠΎΠΊ:
1420
+
1421
+ ```ruby
1422
+ # long polling
1423
+
1424
+ set :server, :thin
1425
+ connections = []
1426
+
1427
+ get '/subscribe' do
1428
+ # рСгистрация ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°
1429
+ stream(:keep_open) { |out| connections << out }
1430
+
1431
+ # ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ "ΠΌΠ΅Ρ€Ρ‚Π²Ρ‹Ρ… ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ²"
1432
+ connections.reject!(&:closed?)
1433
+
1434
+ # допуск
1435
+ "subscribed"
1436
+ end
1437
+
1438
+ post '/message' do
1439
+ connections.each do |out|
1440
+ # ΡƒΠ²Π΅Π΄ΠΎΠΌΠΈΡ‚ΡŒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΎ Π½ΠΎΠ²ΠΎΠΌ сообщСнии
1441
+ out << params[:message] << "\n"
1442
+
1443
+ #Β ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ Π½Π° Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒ снова ΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒΡΡ
1444
+ out.close
1445
+ end
1446
+
1447
+ # допуск
1448
+ "message received"
1449
+ end
1450
+ ```
1451
+
1452
+ ### Π›ΠΎΠ³ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅
1453
+
1454
+ Π’ области видимости запроса ΠΌΠ΅Ρ‚ΠΎΠ΄ `logger` прСдоставляСт доступ ΠΊ экзСмпляру
1455
+ `Logger`:
1456
+
1457
+ ```ruby
1458
+ get '/' do
1459
+ logger.info "loading data"
1460
+ # ...
1461
+ end
1462
+ ```
1463
+
1464
+ Π­Ρ‚ΠΎΡ‚ Π»ΠΎΠ³Π΅Ρ€ автоматичСски ΡƒΡ‡ΠΈΡ‚Ρ‹Π²Π°Π΅Ρ‚ ваши настройки логирования Π² Rack. Если
1465
+ Π»ΠΎΠ³ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ, Ρ‚ΠΎ этот ΠΌΠ΅Ρ‚ΠΎΠ΄ Π²Π΅Ρ€Π½Π΅Ρ‚ пустой (dummy) ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, поэтому Π²Ρ‹
1466
+ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ смСло ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ Π² ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π°Ρ… ΠΈ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°Ρ….
1467
+
1468
+ Π—Π°ΠΌΠ΅Ρ‚ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ Π»ΠΎΠ³ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для
1469
+ `Sinatra::Application`, Π° Ссли вашС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ β€” подкласс `Sinatra::Base`, Ρ‚ΠΎ
1470
+ Π²Ρ‹, Π½Π°Π²Π΅Ρ€Π½ΠΎΠ΅, Π·Π°Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Π΅Π³ΠΎ Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ:
1471
+
1472
+ ```ruby
1473
+ class MyApp < Sinatra::Base
1474
+ configure :production, :development do
1475
+ enable :logging
1476
+ end
1477
+ end
1478
+ ```
1479
+
1480
+ Π§Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ использования любой Π»ΠΎΠ³ΠΈΡ€ΡƒΡŽΡ‰Π΅ΠΉ "прослойки", Π·Π°Π΄Π°ΠΉΡ‚Π΅ ΠΎΠΏΡ†ΠΈΠΈ
1481
+ `logging` Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ `nil`. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, Π½Π΅ Π·Π°Π±Ρ‹Π²Π°ΠΉΡ‚Π΅, Ρ‡Ρ‚ΠΎ Π² Ρ‚Π°ΠΊΠΎΠΉ ситуации
1482
+ `logger` Π²Π΅Ρ€Π½Π΅Ρ‚ `nil`. Π§Π°Ρ‰Π΅ всСго Ρ‚Π°ΠΊ Π΄Π΅Π»Π°ΡŽΡ‚, ΠΊΠΎΠ³Π΄Π° Π·Π°Π΄Π°ΡŽΡ‚ свой собствСнный
1483
+ Π»ΠΎΠ³Π΅Ρ€. Sinatra Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ находится Π² `env['rack.logger']`.
1484
+
1485
+ ### Mime-Ρ‚ΠΈΠΏΡ‹
1486
+
1487
+ Когда Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ `send_file` ΠΈΠ»ΠΈ статичСскиС Ρ„Π°ΠΉΠ»Ρ‹, Ρƒ вас ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ
1488
+ mime-Ρ‚ΠΈΠΏΡ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Sinatra Π½Π΅ ΠΏΠΎΠ½ΠΈΠΌΠ°Π΅Ρ‚ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ `mime_type`
1489
+ для ΠΈΡ… рСгистрации ΠΏΠΎ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡŽ Ρ„Π°ΠΉΠ»Π°:
1490
+
1491
+ ```ruby
1492
+ configure do
1493
+ mime_type :foo, 'text/foo'
1494
+ end
1495
+ ```
1496
+
1497
+ Π’Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ это Π² `content_type` ΠΌΠ΅Ρ‚ΠΎΠ΄Π΅-ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ΅:
1498
+
1499
+ ```ruby
1500
+ get '/' do
1501
+ content_type :foo
1502
+ "foo foo foo"
1503
+ end
1504
+ ```
1505
+
1506
+ ### Π“Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ URL
1507
+
1508
+ Π§Ρ‚ΠΎΠ±Ρ‹ ΡΡ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ URL, Π²Π°ΠΌ слСдуСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄ `url`, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π² Haml:
1509
+
1510
+ ```ruby
1511
+ %a{:href => url('/foo')} foo
1512
+ ```
1513
+
1514
+ Π­Ρ‚ΠΎΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ ΡƒΡ‡ΠΈΡ‚Ρ‹Π²Π°Π΅Ρ‚ ΠΎΠ±Ρ€Π°Ρ‚Π½Ρ‹Π΅ прокси ΠΈ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΈΠ·Π°Ρ‚ΠΎΡ€Ρ‹ Rack, Ссли ΠΎΠ½ΠΈ
1515
+ ΠΏΡ€ΠΈΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‚.
1516
+
1517
+ Наряду с `url` Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ `to` (смотритС ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π½ΠΈΠΆΠ΅).
1518
+
1519
+ ### ΠŸΠ΅Ρ€Π΅Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ (Ρ€Π΅Π΄ΠΈΡ€Π΅ΠΊΡ‚)
1520
+
1521
+ Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠ΅Ρ€Π΅Π½Π°ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° `redirect`:
1522
+
1523
+ ```ruby
1524
+ get '/foo' do
1525
+ redirect to('/bar')
1526
+ end
1527
+ ```
1528
+
1529
+ Π›ΡŽΠ±Ρ‹Π΅ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ ΠΏΠΎ Π°Π½Π°Π»ΠΎΠ³ΠΈΠΈ с Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°ΠΌΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄Π°
1530
+ `halt`:
1531
+
1532
+ ```ruby
1533
+ redirect to('/bar'), 303
1534
+ redirect 'http://google.com', 'wrong place, buddy'
1535
+ ```
1536
+
1537
+ Π’Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠ΅Ρ€Π΅Π½Π°ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ, Π½Π° страницу, с ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΎΠ½
1538
+ ΠΏΡ€ΠΈΡˆΠ΅Π», с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ `redirect back`:
1539
+
1540
+ ```ruby
1541
+ get '/foo' do
1542
+ "<a href='/bar'>do something</a>"
1543
+ end
1544
+
1545
+ get '/bar' do
1546
+ do_something
1547
+ redirect back
1548
+ end
1549
+ ```
1550
+
1551
+ Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ ΠΊΠ°ΠΊΠΈΠ΅-Π»ΠΈΠ±ΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ вмСстС с ΠΏΠ΅Ρ€Π΅Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ΠΌ, Π»ΠΈΠ±ΠΎ Π΄ΠΎΠ±Π°Π²ΡŒΡ‚Π΅
1552
+ ΠΈΡ… Π² строку запроса:
1553
+
1554
+ ```ruby
1555
+ redirect to('/bar?sum=42')
1556
+ ```
1557
+
1558
+ Π»ΠΈΠ±ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ сСссию:
1559
+
1560
+ ```ruby
1561
+ enable :sessions
1562
+
1563
+ get '/foo' do
1564
+ session[:secret] = 'foo'
1565
+ redirect to('/bar')
1566
+ end
1567
+
1568
+ get '/bar' do
1569
+ session[:secret]
1570
+ end
1571
+ ```
1572
+
1573
+ ### Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ
1574
+
1575
+ Установка ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹Ρ… Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ² β€” основа ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠ³ΠΎ HTTP ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ.
1576
+
1577
+ Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π»Π΅Π³ΠΊΠΎ Π²Ρ‹ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Cache-Control Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:
1578
+
1579
+ ```ruby
1580
+ get '/' do
1581
+ cache_control :public
1582
+ "cache it!"
1583
+ end
1584
+ ```
1585
+
1586
+ Π‘ΠΎΠ²Π΅Ρ‚: Π·Π°Π΄Π°Π²Π°ΠΉΡ‚Π΅ ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² `before`-Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π΅:
1587
+
1588
+ ```ruby
1589
+ before do
1590
+ cache_control :public, :must_revalidate, :max_age => 60
1591
+ end
1592
+ ```
1593
+
1594
+ Если Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄ `expires` для задания ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π³ΠΎ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°, Ρ‚ΠΎ
1595
+ `Cache-Control` Π±ΡƒΠ΄Π΅Ρ‚ выставлСн автоматичСски:
1596
+
1597
+ ```ruby
1598
+ before do
1599
+ expires 500, :public, :must_revalidate
1600
+ end
1601
+ ```
1602
+
1603
+ Π§Ρ‚ΠΎΠ±Ρ‹ ΠΊΠ°ΠΊ слСдуСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅, Π²Π°ΠΌ слСдуСт ΠΏΠΎΠ΄ΡƒΠΌΠ°Ρ‚ΡŒ ΠΎΠ±
1604
+ использовании `etag` ΠΈΠ»ΠΈ `last_modified`. РСкомСндуСтся ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ эти
1605
+ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹-ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠΈ *Π΄ΠΎ* выполнСния рСсурсоСмких вычислСний, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΎΠ½ΠΈ
1606
+ Π½Π΅ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ отправят ΠΎΡ‚Π²Π΅Ρ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ, Ссли тСкущая вСрсия ΡƒΠΆΠ΅ Π΅ΡΡ‚ΡŒ Π² ΠΈΡ… кэшС:
1607
+
1608
+ ```ruby
1609
+ get '/article/:id' do
1610
+ @article = Article.find params[:id]
1611
+ last_modified @article.updated_at
1612
+ etag @article.sha1
1613
+ erb :article
1614
+ end
1615
+ ```
1616
+
1617
+ Π’Π°ΠΊΠΆΠ΅ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ
1618
+ [weak ETag](http://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation):
1619
+
1620
+ ```ruby
1621
+ etag @article.sha1, :weak
1622
+ ```
1623
+
1624
+ Π­Ρ‚ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹-ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠΈ Π½Π΅ станут Π½ΠΈΡ‡Π΅Π³ΠΎ ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ для вас, Π½ΠΎ ΠΎΠ½ΠΈ Π΄Π°Π΄ΡƒΡ‚
1625
+ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ для вашСго кэша. Если Π²Ρ‹ ΠΈΡ‰Π΅Ρ‚Π΅ Π»Π΅Π³ΠΊΠΎΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ для
1626
+ ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ, ΠΏΠΎΠΏΡ€ΠΎΠ±ΡƒΠΉΡ‚Π΅ [rack-cache](https://github.com/rtomayko/rack-cache):
1627
+
1628
+ ```ruby
1629
+ require 'rack/cache'
1630
+ require 'sinatra'
1631
+
1632
+ use Rack::Cache
1633
+
1634
+ get '/' do
1635
+ cache_control :public, :max_age => 36000
1636
+ sleep 5
1637
+ "hello"
1638
+ end
1639
+ ```
1640
+
1641
+ Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ ΠΎΠΏΡ†ΠΈΡŽ `:static_cache_control` (см. Π½ΠΈΠΆΠ΅), Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ
1642
+ `Cache-Control` ΠΊ статичСским Ρ„Π°ΠΉΠ»Π°ΠΌ.
1643
+
1644
+ Π’ соотвСтствии с RFC 2616 вашС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ вСсти сСбя ΠΏΠΎ-Ρ€Π°Π·Π½ΠΎΠΌΡƒ, ΠΊΠΎΠ³Π΄Π°
1645
+ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ If-Match ΠΈΠ»ΠΈ If-None-Match ΠΈΠΌΠ΅ΡŽΡ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ `*`, Π² зависимости ΠΎΡ‚
1646
+ Ρ‚ΠΎΠ³ΠΎ, сущСствуСт ΠΈΠ»ΠΈ Π½Π΅Ρ‚ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅ΠΌΡ‹ΠΉ рСсурс. Sinatra ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ
1647
+ рСсурсы, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ ΠΎΠ±Ρ€Π°Ρ‰Π°ΡŽΡ‚ΡΡ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ бСзопасных (GET) ΠΈ ΠΈΠ΄Π΅ΠΌΠΏΠΎΡ‚Π΅Π½Ρ‚Π½Ρ‹Ρ… (PUT)
1648
+ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ², ΡƒΠΆΠ΅ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚, Π° ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ рСсурсы (ΠΊ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ ΠΎΠ±Ρ€Π°Ρ‰Π°ΡŽΡ‚ΡΡ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€,
1649
+ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ POST) считаСт Π½ΠΎΠ²Ρ‹ΠΌΠΈ. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π΄Π°Π½Π½ΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ
1650
+ ΠΎΠΏΡ†ΠΈΠΈ `:new_resource`:
1651
+
1652
+ ```ruby
1653
+ get '/create' do
1654
+ etag '', :new_resource => true
1655
+ Article.create
1656
+ erb :new_article
1657
+ end
1658
+ ```
1659
+
1660
+ Если Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ weak ETag, Π·Π°Π΄Π°ΠΉΡ‚Π΅ ΠΎΠΏΡ†ΠΈΡŽ `:kind`:
1661
+
1662
+ ```ruby
1663
+ etag '', :new_resource => true, :kind => :weak
1664
+ ```
1665
+
1666
+ ### ΠžΡ‚ΠΏΡ€Π°Π²ΠΊΠ° Ρ„Π°ΠΉΠ»ΠΎΠ²
1667
+
1668
+ Для ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ Ρ„Π°ΠΉΠ»ΠΎΠ² ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄ `send_file`:
1669
+
1670
+ ```ruby
1671
+ get '/' do
1672
+ send_file 'foo.png'
1673
+ end
1674
+ ```
1675
+
1676
+ Π­Ρ‚ΠΎΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΈΠΌΠ΅Π΅Ρ‚ нСсколько ΠΎΠΏΡ†ΠΈΠΉ:
1677
+
1678
+ ```ruby
1679
+ send_file 'foo.png', :type => :jpg
1680
+ ```
1681
+
1682
+ Π’ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ ΠΎΠΏΡ†ΠΈΠΈ:
1683
+
1684
+ <dl>
1685
+ <dt>filename</dt>
1686
+ <dd>имя Ρ„Π°ΠΉΠ»Π°, ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ: Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠ΅ имя Ρ„Π°ΠΉΠ»Π°.</dd>
1687
+
1688
+ <dt>last_modified</dt>
1689
+ <dd>Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ для Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° Last-Modified, ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ: mtime (врСмя
1690
+ измСнСния) Ρ„Π°ΠΉΠ»Π°.</dd>
1691
+
1692
+ <dt>type</dt>
1693
+ <dd>Ρ‚ΠΈΠΏ Ρ„Π°ΠΉΠ»Π°, ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ: опрСдСляСтся ΠΏΠΎ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡŽ Ρ„Π°ΠΉΠ»Π°.</dd>
1694
+
1695
+ <dt>disposition</dt>
1696
+ <dd>ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° Content-Disposition, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ значСния: <tt>nil</tt>
1697
+ (ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ), <tt>:attachment</tt> ΠΈ <tt>:inline</tt>.</dd>
1698
+
1699
+ <dt>length</dt>
1700
+ <dd>значСния для Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° Content-Length, ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ: Ρ€Π°Π·ΠΌΠ΅Ρ€ Ρ„Π°ΠΉΠ»Π°.</dd>
1701
+
1702
+ <dt>status</dt>
1703
+ <dd>Код ΠΎΡ‚Π²Π΅Ρ‚Π°. ПолСзно, ΠΊΠΎΠ³Π΄Π° отдаСтся статичСский Ρ„Π°ΠΉΠ» Π² качСствС страницы с
1704
+ сообщСниСм ΠΎΠ± ошибкС.</dd>
1705
+ </dl>
1706
+
1707
+ Π­Ρ‚ΠΎΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ возмоТности Rack сСрвСра для ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ Ρ„Π°ΠΉΠ»ΠΎΠ²,
1708
+ Ссли ΠΎΠ½ΠΈ доступны, Π² ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС Π±ΡƒΠ΄Π΅Ρ‚ Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ ΠΎΡ‚Π΄Π°Π²Π°Ρ‚ΡŒ Ρ„Π°ΠΉΠ» ΠΈΠ· Ruby
1709
+ процСсса. ΠœΠ΅Ρ‚ΠΎΠ΄ `send_file` Ρ‚Π°ΠΊΠΆΠ΅ обСспСчиваСт Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΡ‡Π΅ΡΠΊΡƒΡŽ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ
1710
+ частичных (range) запросов с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Sinatra.
1711
+
1712
+ ### Доступ ΠΊ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ запроса
1713
+
1714
+ ΠžΠ±ΡŠΠ΅ΠΊΡ‚ входящСго запроса доступСн Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ запроса (Π² Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°Ρ…,
1715
+ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π°Ρ…, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°Ρ… ошибок) с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ `request` ΠΌΠ΅Ρ‚ΠΎΠ΄Π°:
1716
+
1717
+ ```ruby
1718
+ # ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π·Π°ΠΏΡƒΡ‰Π΅Π½ΠΎ Π½Π° http://example.com/example
1719
+ get '/foo' do
1720
+ t = %w[text/css text/html application/javascript]
1721
+ request.accept # ['text/html', '*/*']
1722
+ request.accept? 'text/xml' # true
1723
+ request.preferred_type(t) # 'text/html'
1724
+ request.body # Ρ‚Π΅Π»ΠΎ запроса, посланноС ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ (см. Π½ΠΈΠΆΠ΅)
1725
+ request.scheme # "http"
1726
+ request.script_name # "/example"
1727
+ request.path_info # "/foo"
1728
+ request.port # 80
1729
+ request.request_method # "GET"
1730
+ request.query_string # ""
1731
+ request.content_length # Π΄Π»ΠΈΠ½Π° Ρ‚Π΅Π»Π° запроса
1732
+ request.media_type # ΠΌΠ΅Π΄ΠΈΠ°Ρ‚ΠΈΠΏ Ρ‚Π΅Π»Π° запроса
1733
+ request.host # "example.com"
1734
+ request.get? # true (Π΅ΡΡ‚ΡŒ Π°Π½Π°Π»ΠΎΠ³ΠΈ для Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² HTTP)
1735
+ request.form_data? # false
1736
+ request["some_param"] # Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° some_param. Π¨ΠΎΡ€Ρ‚ΠΊΠ°Ρ‚ для Ρ…Π΅ΡˆΠ° params
1737
+ request.referrer # источник запроса ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Π»ΠΈΠ±ΠΎ '/'
1738
+ request.user_agent # user agent (ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для :agent условия)
1739
+ request.cookies # Ρ…Π΅Ρˆ, содСрТащий cookies Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π°
1740
+ request.xhr? # являСтся Π»ΠΈ запрос ajax запросом?
1741
+ request.url # "http://example.com/example/foo"
1742
+ request.path # "/example/foo"
1743
+ request.ip # IP-адрСс ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°
1744
+ request.secure? # false (true, Ссли запрос сдСлан Ρ‡Π΅Ρ€Π΅Π· SSL)
1745
+ request.forwarded? # true (Ссли сСрвСр Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π·Π° ΠΎΠ±Ρ€Π°Ρ‚Π½Ρ‹ΠΌ прокси)
1746
+ request.env # "сырой" env Ρ…Π΅Ρˆ, ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹ΠΉ Rack
1747
+ end
1748
+ ```
1749
+
1750
+ НСкоторыС ΠΎΠΏΡ†ΠΈΠΈ, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ `script_name` ΠΈΠ»ΠΈ `path_info`, доступны для
1751
+ измСнСния:
1752
+
1753
+ ```ruby
1754
+ before { request.path_info = "/" }
1755
+
1756
+ get "/" do
1757
+ "all requests end up here"
1758
+ end
1759
+ ```
1760
+
1761
+ `request.body` являСтся IO ΠΈΠ»ΠΈ StringIO ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ:
1762
+
1763
+ ```ruby
1764
+ post "/api" do
1765
+ request.body.rewind # Π² случаС, Ссли ΠΊΡ‚ΠΎ-Ρ‚ΠΎ ΡƒΠΆΠ΅ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Π» Ρ‚Π΅Π»ΠΎ запроса
1766
+ data = JSON.parse request.body.read
1767
+ "Hello #{data['name']}!"
1768
+ end
1769
+ ```
1770
+
1771
+ ### ВлоТСния
1772
+
1773
+ Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄ `attachment`, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠΊΠ°Π·Π°Ρ‚ΡŒ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Ρƒ, Ρ‡Ρ‚ΠΎ ΠΎΡ‚Π²Π΅Ρ‚
1774
+ сСрвСра Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ сохранСн Π½Π° диск, Π° Π½Π΅ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½:
1775
+
1776
+ ```ruby
1777
+ get '/' do
1778
+ attachment
1779
+ "store it!"
1780
+ end
1781
+ ```
1782
+
1783
+ Π’Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ имя Ρ„Π°ΠΉΠ»Π°:
1784
+
1785
+ ```ruby
1786
+ get '/' do
1787
+ attachment "info.txt"
1788
+ "store it!"
1789
+ end
1790
+ ```
1791
+
1792
+ ### Π Π°Π±ΠΎΡ‚Π° со Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ ΠΈ Π΄Π°Ρ‚Π°ΠΌΠΈ
1793
+
1794
+ Sinatra ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅Ρ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄-ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊ `time_for`, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΠ· Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ значСния
1795
+ создаСт ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Time. Он Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΊΠΎΠ½Π²Π΅Ρ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ `DateTime`, `Date` ΠΈ
1796
+ ΠΏΠΎΠ΄ΠΎΠ±Π½Ρ‹Π΅ классы:
1797
+
1798
+ ```ruby
1799
+ get '/' do
1800
+ pass if Time.now > time_for('Dec 23, 2012')
1801
+ "still time"
1802
+ end
1803
+ ```
1804
+
1805
+ Π­Ρ‚ΠΎΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π²Π½ΡƒΡ‚Ρ€ΠΈ Sinatra ΠΌΠ΅Ρ‚ΠΎΠ΄Π°ΠΌΠΈ `expires`, `last_modified` ΠΈ
1806
+ ΠΈΠΌ ΠΏΠΎΠ΄ΠΎΠ±Π½Ρ‹ΠΌΠΈ. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Π²Ρ‹ Π»Π΅Π³ΠΊΠΎ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Ρ€Π°ΡΡˆΠΈΡ€ΠΈΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π» этих ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ²,
1807
+ ΠΏΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ² `time_for` Π² своСм ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ:
1808
+
1809
+ ```ruby
1810
+ helpers do
1811
+ def time_for(value)
1812
+ case value
1813
+ when :yesterday then Time.now - 24*60*60
1814
+ when :tomorrow then Time.now + 24*60*60
1815
+ else super
1816
+ end
1817
+ end
1818
+ end
1819
+
1820
+ get '/' do
1821
+ last_modified :yesterday
1822
+ expires :tomorrow
1823
+ "hello"
1824
+ end
1825
+ ```
1826
+
1827
+ ### Поиск шаблонов
1828
+
1829
+ Для поиска шаблонов ΠΈ ΠΈΡ… ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠ½Π³Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΌΠ΅Ρ‚ΠΎΠ΄
1830
+ `find_template`:
1831
+
1832
+ ```ruby
1833
+ find_template settings.views, 'foo', Tilt[:haml] do |file|
1834
+ puts "could be #{file}"
1835
+ end
1836
+ ```
1837
+
1838
+ Π­Ρ‚ΠΎ Π½Π΅ слишком ΠΏΠΎΠ»Π΅Π·Π½Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€. Π—Π°Ρ‚ΠΎ ΠΏΠΎΠ»Π΅Π·Π΅Π½ Ρ‚ΠΎΡ‚ Ρ„Π°ΠΊΡ‚, Ρ‡Ρ‚ΠΎ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅
1839
+ ΠΏΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ этот ΠΌΠ΅Ρ‚ΠΎΠ΄, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ свой собствСнный ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ
1840
+ поиска. НапримСр, Ссли Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ нСсколько
1841
+ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΉ с шаблонами:
1842
+
1843
+ ```ruby
1844
+ set :views, ['views', 'templates']
1845
+
1846
+ helpers do
1847
+ def find_template(views, name, engine, &block)
1848
+ Array(views).each { |v| super(v, name, engine, &block) }
1849
+ end
1850
+ end
1851
+ ```
1852
+
1853
+ Π”Ρ€ΡƒΠ³ΠΎΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ Ρ€Π°Π·Π½Ρ‹Π΅ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ для Π΄Π²ΠΈΠΆΠΊΠΎΠ²
1854
+ Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠ½Π³Π°:
1855
+
1856
+ ```ruby
1857
+ set :views, :sass => 'views/sass', :haml => 'templates', :default => 'views'
1858
+
1859
+ helpers do
1860
+ def find_template(views, name, engine, &block)
1861
+ _, folder = views.detect { |k,v| engine == Tilt[k] }
1862
+ folder ||= views[:default]
1863
+ super(folder, name, engine, &block)
1864
+ end
1865
+ end
1866
+ ```
1867
+
1868
+ Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π»Π΅Π³ΠΊΠΎ вынСсти этот ΠΊΠΎΠ΄ Π² Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ ΠΈ ΠΏΠΎΠ΄Π΅Π»ΠΈΡ‚ΡŒΡΡ ΠΈΠΌ с ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹ΠΌΠΈ!
1869
+
1870
+ Π—Π°ΠΌΠ΅Ρ‚ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ `find_template` Π½Π΅ провСряСт, сущСствуСт Π»ΠΈ Ρ„Π°ΠΉΠ» Π½Π° самом Π΄Π΅Π»Π΅,
1871
+ Π° Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Π·Π°Π΄Π°Π½Π½Ρ‹ΠΉ Π±Π»ΠΎΠΊ для всСх Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… ΠΏΡƒΡ‚Π΅ΠΉ. Π”Π΅Π»ΠΎ Ρ‚ΡƒΡ‚ Π½Π΅ Π²
1872
+ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ, Π΄Π΅Π»ΠΎ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ `render` Π²Ρ‹Π·ΠΎΠ²Π΅Ρ‚ `break`, ΠΊΠ°ΠΊ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ„Π°ΠΉΠ»
1873
+ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π½Π°ΠΉΠ΄Π΅Π½. Π‘ΠΎΠ΄Π΅Ρ€ΠΆΠΈΠΌΠΎΠ΅ ΠΈ мСстонахоТдСниС шаблонов Π±ΡƒΠ΄Π΅Ρ‚ Π·Π°ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΎ,
1874
+ Ссли ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π·Π°ΠΏΡƒΡ‰Π΅Π½ΠΎ Π½Π΅ Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ (`set :environment,
1875
+ :development`). Π’Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ ΠΎΠ± этих Π½ΡŽΠ°Π½ΡΠ°Ρ…, Ссли ΠΏΠΈΡˆΠΈΡ‚Π΅ ΠΏΠΎ-настоящСму
1876
+ "ΡΡƒΠΌΠ°ΡΡˆΠ΅Π΄ΡˆΠΈΠΉ" ΠΌΠ΅Ρ‚ΠΎΠ΄.
1877
+
1878
+ ## ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ
1879
+
1880
+ Π­Ρ‚ΠΎΡ‚ Π±Π»ΠΎΠΊ исполняСтся ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π· ΠΏΡ€ΠΈ стартС Π² любом ΠΎΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΠΈ, Ρ€Π΅ΠΆΠΈΠΌΠ΅
1881
+ (environment):
1882
+
1883
+ ```ruby
1884
+ configure do
1885
+ # Π·Π°Π΄Π°Π½ΠΈΠ΅ ΠΎΠ΄Π½ΠΎΠΉ ΠΎΠΏΡ†ΠΈΠΈ
1886
+ set :option, 'value'
1887
+
1888
+ # устанавливаСм нСсколько ΠΎΠΏΡ†ΠΈΠΉ
1889
+ set :a => 1, :b => 2
1890
+
1891
+ # Ρ‚ΠΎ ΠΆΠ΅ самоС, Ρ‡Ρ‚ΠΎ ΠΈ `set :option, true`
1892
+ enable :option
1893
+
1894
+ # Ρ‚ΠΎ ΠΆΠ΅ самоС, Ρ‡Ρ‚ΠΎ ΠΈ `set :option, false`
1895
+ disable :option
1896
+
1897
+ # Ρƒ вас ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ "динамичСскиС" ΠΎΠΏΡ†ΠΈΠΈ с Π±Π»ΠΎΠΊΠ°ΠΌΠΈ
1898
+ set(:css_dir) { File.join(views, 'css') }
1899
+ end
1900
+ ```
1901
+
1902
+ Π‘ΡƒΠ΄Π΅Ρ‚ Π·Π°ΠΏΡƒΡ‰Π΅Π½ΠΎ, ΠΊΠΎΠ³Π΄Π° ΠΎΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΠ΅ (RACK_ENV пСрСмСнная) `:production`:
1903
+
1904
+ ```ruby
1905
+ configure :production do
1906
+ ...
1907
+ end
1908
+ ```
1909
+
1910
+ Π‘ΡƒΠ΄Π΅Ρ‚ Π·Π°ΠΏΡƒΡ‰Π΅Π½ΠΎ, ΠΊΠΎΠ³Π΄Π° ΠΎΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΠ΅ `:production` ΠΈΠ»ΠΈ `:test`:
1911
+
1912
+ ```ruby
1913
+ configure :production, :test do
1914
+ ...
1915
+ end
1916
+ ```
1917
+
1918
+ Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ доступ ΠΊ этим опциям с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ `settings`:
1919
+
1920
+ ```ruby
1921
+ configure do
1922
+ set :foo, 'bar'
1923
+ end
1924
+
1925
+ get '/' do
1926
+ settings.foo? # => true
1927
+ settings.foo # => 'bar'
1928
+ ...
1929
+ end
1930
+ ```
1931
+
1932
+ ### Настройка Π·Π°Ρ‰ΠΈΡ‚Ρ‹ ΠΎΡ‚ Π°Ρ‚Π°ΠΊ
1933
+
1934
+ Sinatra ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚
1935
+ [Rack::Protection](https://github.com/rkh/rack-protection#readme) для Π·Π°Ρ‰ΠΈΡ‚Ρ‹
1936
+ прилоТСния ΠΎΡ‚ простых Π°Ρ‚Π°ΠΊ. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π»Π΅Π³ΠΊΠΎ Π²Ρ‹ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ эту Π·Π°Ρ‰ΠΈΡ‚Ρƒ (Ρ‡Ρ‚ΠΎ сдСлаСт
1937
+ вашС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Ρ‡Ρ€Π΅Π·Π²Ρ‹Ρ‡Π°ΠΉΠ½ΠΎ уязвимым):
1938
+
1939
+ ```ruby
1940
+ disable :protection
1941
+ ```
1942
+
1943
+ Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ ΠΊΠ°ΠΊΠΎΠΉ-Π»ΠΈΠ±ΠΎ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ Π·Π°Ρ‰ΠΈΡ‚Ρ‹, ΠΏΠ΅Ρ€Π΅Π΄Π°ΠΉΡ‚Π΅ Ρ…Π΅Ρˆ ΠΎΠΏΡ†ΠΈΠΉ Π² ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€
1944
+ `protection`:
1945
+
1946
+ ```ruby
1947
+ set :protection, :except => :path_traversal
1948
+ ```
1949
+
1950
+ Π’Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ сразу нСсколько ΡƒΡ€ΠΎΠ²Π½Π΅ΠΉ Π·Π°Ρ‰ΠΈΡ‚Ρ‹:
1951
+
1952
+ ```ruby
1953
+ set :protection, :except => [:path_traversal, :session_hijacking]
1954
+ ```
1955
+
1956
+ ### ДоступныС настройки
1957
+
1958
+ <dl>
1959
+ <dt>absolute_redirects</dt>
1960
+ <dd>
1961
+ Ссли ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ, Ρ‚ΠΎ Sinatra Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡ‚ΡŒ использованиС ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ…
1962
+ ΠΏΠ΅Ρ€Π΅Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠΉ, Π½ΠΎ ΠΏΡ€ΠΈ этом пСрСстанСт ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ RFC 2616 (HTTP
1963
+ 1.1), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π°Π±ΡΠΎΠ»ΡŽΡ‚Π½Ρ‹Π΅ пСрСнаправлСния.
1964
+ </dd>
1965
+ <dd>
1966
+ Π’ΠΊΠ»ΡŽΡ‡Π°ΠΉΡ‚Π΅ эту ΠΎΠΏΡ†ΠΈΡŽ, Ссли вашС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π·Π° ΠΎΠ±Ρ€Π°Ρ‚Π½Ρ‹ΠΌ прокси,
1967
+ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ настроСн Π½Π΅ совсСм ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ. ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, ΠΌΠ΅Ρ‚ΠΎΠ΄ <tt>url</tt> всС
1968
+ Ρ€Π°Π²Π½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π°Π±ΡΠΎΠ»ΡŽΡ‚Π½Ρ‹Π΅ URL, Ссли Π²Ρ‹ Π½Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΄ΠΈΡ‚Π΅ <tt>false</tt>
1969
+ Π²Ρ‚ΠΎΡ€Ρ‹ΠΌ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠΌ.
1970
+ </dd>
1971
+ <dd>ΠžΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ.</dd>
1972
+
1973
+ <dt>add_charsets</dt>
1974
+ <dd>
1975
+ mime-Ρ‚ΠΈΠΏΡ‹, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ ΠΌΠ΅Ρ‚ΠΎΠ΄ <tt>content_type</tt> Π±ΡƒΠ΄Π΅Ρ‚ автоматичСски Π΄ΠΎΠ±Π°Π²Π»ΡΡ‚ΡŒ
1976
+ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²ΠΊΠ΅. Π’Π°ΠΌ слСдуСт Π΄ΠΎΠ±Π°Π²Π»ΡΡ‚ΡŒ значСния ΠΊ этой ΠΎΠΏΡ†ΠΈΠΈ
1977
+ вмСсто Π΅Π΅ пСрСопрСдСлСния: <tt>settings.add_charsets &lt;&lt; "application/foobar"</tt>
1978
+ </dd>
1979
+
1980
+ <dt>app_file</dt>
1981
+ <dd>
1982
+ ΠΏΡƒΡ‚ΡŒ ΠΊ Π³Π»Π°Π²Π½ΠΎΠΌΡƒ Ρ„Π°ΠΉΠ»Ρƒ прилоТСния, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для нахоТдСния ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠΉ
1983
+ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°, Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΉ с шаблонами ΠΈ статичСскими Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ,
1984
+ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Ρ… шаблонов.
1985
+ </dd>
1986
+
1987
+ <dt>bind</dt>
1988
+ <dd>
1989
+ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΉ IP-адрСс (ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ: 0.0.0.0). Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ
1990
+ встроСнным сСрвСром.
1991
+ </dd>
1992
+
1993
+ <dt>default_encoding</dt>
1994
+ <dd>ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²ΠΊΠ°, Ссли нСизвСстна (ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ: <tt>"utf-8"</tt>).</dd>
1995
+
1996
+ <dt>dump_errors</dt>
1997
+ <dd>ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Ρ‚ΡŒ ошибки Π² Π»ΠΎΠ³Π΅.</dd>
1998
+
1999
+ <dt>environment</dt>
2000
+ <dd>
2001
+ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ ΠΎΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΠ΅, ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ, Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ <tt>ENV['RACK_ENV']</tt> ΠΈΠ»ΠΈ
2002
+ <tt>"development"</tt>, Ссли <tt>ENV['RACK_ENV']</tt> нСдоступна.
2003
+ </dd>
2004
+
2005
+ <dt>logging</dt>
2006
+ <dd>ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π»ΠΎΠ³Π΅Ρ€.</dd>
2007
+
2008
+ <dt>lock</dt>
2009
+ <dd>
2010
+ создаСт Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ запроса, которая Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ
2011
+ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½ΠΎΠ³ΠΎ запроса Π² Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Π² Ruby процСссС.
2012
+ </dd>
2013
+ <dd>
2014
+ Π’ΠΊΠ»ΡŽΡ‡Π°ΠΉΡ‚Π΅, Ссли вашС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π΅ ΠΏΠΎΡ‚ΠΎΠΊΠΎ-бСзопасно (thread-safe).
2015
+ ΠžΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ.</dd>
2016
+
2017
+ <dt>method_override</dt>
2018
+ <dd>
2019
+ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ "магичСский" ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ <tt>_method</tt>, для ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ
2020
+ PUT/DELETE Ρ„ΠΎΡ€ΠΌ Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π°Ρ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ эти ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹.
2021
+ </dd>
2022
+
2023
+ <dt>port</dt>
2024
+ <dd>
2025
+ ΠΏΠΎΡ€Ρ‚, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ сСрвСр.
2026
+ Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ встроСнным сСрвСром.
2027
+ </dd>
2028
+
2029
+ <dt>prefixed_redirects</dt>
2030
+ <dd>
2031
+ Π΄ΠΎΠ±Π°Π²Π»ΡΡ‚ΡŒ ΠΈΠ»ΠΈ Π½Π΅Ρ‚ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ <tt>request.script_name</tt> ΠΊ Ρ€Π΅Π΄ΠΈΡ€Π΅ΠΊΡ‚Π°ΠΌ, Ссли Π½Π΅
2032
+ Π·Π°Π΄Π°Π½ Π°Π±ΡΠΎΠ»ΡŽΡ‚Π½Ρ‹ΠΉ ΠΏΡƒΡ‚ΡŒ. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, <tt>redirect '/foo'</tt> Π±ΡƒΠ΄Π΅Ρ‚ вСсти сСбя
2033
+ ΠΊΠ°ΠΊ <tt>redirect to('/foo')</tt>. ΠžΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ.
2034
+ </dd>
2035
+
2036
+ <dt>protection</dt>
2037
+ <dd>Π²ΠΊΠ»ΡŽΡ‡Π΅Π½Π° ΠΈΠ»ΠΈ Π½Π΅Ρ‚ Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ Π°Ρ‚Π°ΠΊ. Π‘ΠΌΠΎΡ‚Ρ€ΠΈΡ‚Π΅ ΡΠ΅ΠΊΡ†ΠΈΡŽ Π²Ρ‹ΡˆΠ΅.</dd>
2038
+
2039
+ <dt>public_dir</dt>
2040
+ <dd>Алиас для <tt>public_folder</tt>.</dd>
2041
+
2042
+ <dt>public_folder</dt>
2043
+ <dd>
2044
+ ΠΏΡƒΡ‚ΡŒ ΠΊ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ, ΠΎΡ‚ΠΊΡƒΠ΄Π° Π±ΡƒΠ΄ΡƒΡ‚ Ρ€Π°Π·Π΄Π°Π²Π°Ρ‚ΡŒΡΡ статичСскиС Ρ„Π°ΠΉΠ»Ρ‹.
2045
+ Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ссли Π²ΠΊΠ»ΡŽΡ‡Π΅Π½Π° Ρ€Π°Π·Π΄Π°Ρ‡Π° статичСских Ρ„Π°ΠΉΠ»ΠΎΠ²
2046
+ (см. ΠΎΠΏΡ†ΠΈΡŽ <tt>static</tt> Π½ΠΈΠΆΠ΅).
2047
+ </dd>
2048
+
2049
+ <dt>reload_templates</dt>
2050
+ <dd>
2051
+ ΠΏΠ΅Ρ€Π΅Π·Π°Π³Ρ€ΡƒΠΆΠ°Ρ‚ΡŒ ΠΈΠ»ΠΈ Π½Π΅Ρ‚ ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹ Π½Π° ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ запрос. Π’ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅
2052
+ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ.
2053
+ </dd>
2054
+
2055
+ <dt>root</dt>
2056
+ <dd>ΠΏΡƒΡ‚ΡŒ ΠΊ ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠΉ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°.</dd>
2057
+
2058
+ <dt>raise_errors</dt>
2059
+ <dd>
2060
+ Π²Ρ‹Π±Ρ€Π°ΡΡ‹Π²Π°Ρ‚ΡŒ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ (Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅).
2061
+ По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² ΠΎΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΠΈ <tt>test</tt>.
2062
+ </dd>
2063
+
2064
+ <dt>run</dt>
2065
+ <dd>
2066
+ Ссли Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ, Sinatra Π±ΡƒΠ΄Π΅Ρ‚ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ Π·Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ Π²Π΅Π±-сСрвСр. НС
2067
+ Π²ΠΊΠ»ΡŽΡ‡Π°ΠΉΡ‚Π΅, Ссли ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ rackup ΠΈΠ»ΠΈ Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½Ρ‹Π΅ срСдства.
2068
+ </dd>
2069
+
2070
+ <dt>running</dt>
2071
+ <dd>Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π»ΠΈ сСйчас встроСнный сСрвСр? НС мСняйтС эту ΠΎΠΏΡ†ΠΈΡŽ!</dd>
2072
+
2073
+ <dt>server</dt>
2074
+ <dd>
2075
+ сСрвСр ΠΈΠ»ΠΈ список сСрвСров, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ слСдуСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² качСствС
2076
+ встроСнного сСрвСра. По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ: <tt>['thin', 'mongrel', 'webrick']</tt>, порядок
2077
+ Π·Π°Π΄Π°Π΅Ρ‚ ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚.</dd>
2078
+
2079
+ <dt>sessions</dt>
2080
+ <dd>
2081
+ Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ сСссии Π½Π° основС ΠΊΡƒΠΊ (cookie) Π½Π° Π±Π°Π·Π΅ <tt>Rack::Session::Cookie</tt>.
2082
+ Π‘ΠΌΠΎΡ‚Ρ€ΠΈΡ‚Π΅ ΡΠ΅ΠΊΡ†ΠΈΡŽ "ИспользованиС сСссий" Π²Ρ‹ΡˆΠ΅.
2083
+ </dd>
2084
+
2085
+ <dt>show_exceptions</dt>
2086
+ <dd>
2087
+ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ/стСк Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² (stack trace) Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π΅. По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ
2088
+ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² ΠΎΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΠΈ <tt>development</tt>.
2089
+ </dd>
2090
+ <dd>
2091
+ ΠœΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ установлСно Π²
2092
+ <tt>:after_handler</tt> для запуска спСцифичной для прилоТСния ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ошибок,
2093
+ ΠΏΠ΅Ρ€Π΅Π΄ ΠΏΠΎΠΊΠ°Π·ΠΎΠΌ трассировки стСка Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π΅.
2094
+ </dd>
2095
+
2096
+ <dt>static</dt>
2097
+ <dd>Π΄ΠΎΠ»ΠΆΠ½Π° Π»ΠΈ Sinatra ΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²Π»ΡΡ‚ΡŒ Ρ€Π°Π·Π΄Π°Ρ‡Ρƒ статичСских Ρ„Π°ΠΉΠ»ΠΎΠ².</dd>
2098
+ <dd>ΠžΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅, ΠΊΠΎΠ³Π΄Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ ΠΊΠ°ΠΊΠΎΠΉ-Π»ΠΈΠ±ΠΎ Π²Π΅Π±-сСрвСр для этой Ρ†Π΅Π»ΠΈ.</dd>
2099
+ <dd>ΠžΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΡƒΠ»ΡƒΡ‡ΡˆΠΈΡ‚ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ прилоТСния.</dd>
2100
+ <dd>По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ Π² классичСских ΠΈ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ Π² ΠΌΠΎΠ΄ΡƒΠ»ΡŒΠ½Ρ‹Ρ… прилоТСниях.</dd>
2101
+
2102
+ <dt>static_cache_control</dt>
2103
+ <dd>
2104
+ ΠΊΠΎΠ³Π΄Π° Sinatra ΠΎΡ‚Π΄Π°Π΅Ρ‚ статичСскиС Ρ„Π°ΠΉΠ»Ρ‹, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ эту ΠΎΠΏΡ†ΠΈΡŽ, Ρ‡Ρ‚ΠΎΠ±Ρ‹
2105
+ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΈΠΌ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ <tt>Cache-Control</tt>. Для этого ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ
2106
+ ΠΌΠ΅Ρ‚ΠΎΠ΄-ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊ <tt>cache_control</tt>. По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ.
2107
+ </dd>
2108
+ <dd>
2109
+ Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ массив, ΠΊΠΎΠ³Π΄Π° Π½Π°Π΄ΠΎ Π·Π°Π΄Π°Ρ‚ΡŒ нСсколько Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ:
2110
+ <tt>set :static_cache_control, [:public, :max_age => 300]</tt>
2111
+ </dd>
2112
+
2113
+ <dt>threaded</dt>
2114
+ <dd>
2115
+ Ссли Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ, Ρ‚ΠΎ Thin Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ <tt>EventMachine.defer</tt> для
2116
+ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ запросов.
2117
+ </dd>
2118
+
2119
+ <dt>traps</dt>
2120
+ <dd>Π΄ΠΎΠ»ΠΆΠ½Π° Π»ΠΈ Π‘ΠΈΠ½Π°Ρ‚Ρ€Π° ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ систСмныС сигналы ΠΈΠ»ΠΈ Π½Π΅Ρ‚.</tt></dd>
2121
+
2122
+ <dt>views</dt>
2123
+ <dd>ΠΏΡƒΡ‚ΡŒ ΠΊ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ с шаблонами.</dd>
2124
+ </dl>
2125
+
2126
+ ## Π Π΅ΠΆΠΈΠΌ, ΠΎΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΠ΅
2127
+
2128
+ Π•ΡΡ‚ΡŒ 3 ΠΏΡ€Π΅Π΄ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Ρ… Ρ€Π΅ΠΆΠΈΠΌΠ°, окруТСния: `"development"`, `"production"` ΠΈ
2129
+ `"test"`. Π Π΅ΠΆΠΈΠΌ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π·Π°Π΄Π°Π½ Ρ‡Π΅Ρ€Π΅Π· ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ окруТСния `RACK_ENV`.
2130
+ Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ β€” `"development"`. Π’ этом Ρ€Π΅ΠΆΠΈΠΌΠ΅ Ρ€Π°Π±ΠΎΡ‚Ρ‹ всС ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹
2131
+ ΠΏΠ΅Ρ€Π΅Π·Π°Π³Ρ€ΡƒΠΆΠ°ΡŽΡ‚ΡΡ ΠΌΠ΅ΠΆΠ΄Ρƒ запросами. А Ρ‚Π°ΠΊΠΆΠ΅ Π·Π°Π΄Π°ΡŽΡ‚ΡΡ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Π΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ
2132
+ `not_found` ΠΈ `error`, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²Ρ‹ ΠΌΠΎΠ³Π»ΠΈ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ стСк Π²Ρ‹Π·ΠΎΠ²ΠΎΠ². Π’ окруТСниях
2133
+ `"production"` ΠΈ `"test"` ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ ΠΊΡΡˆΠΈΡ€ΡƒΡŽΡ‚ΡΡ.
2134
+
2135
+ Для запуска прилоТСния Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΌ ΠΎΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ ΠΊΠ»ΡŽΡ‡ `-e`
2136
+
2137
+ ```
2138
+ ruby my_app.rb -e [ENVIRONMENT]
2139
+ ```
2140
+
2141
+ Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€Π΅Π΄ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ `development?`, `test?` ΠΈ
2142
+ +production?, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ ΠΎΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΠ΅.
2143
+
2144
+ ## ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ошибок
2145
+
2146
+ ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ ошибок ΠΈΡΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ Π² Ρ‚ΠΎΠΌ ΠΆΠ΅ контСкстС, Ρ‡Ρ‚ΠΎ ΠΈ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Ρ‹, ΠΈ
2147
+ `before`-Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Ρ‹, Π° это ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ всякиС прСлСсти Π²Ρ€ΠΎΠ΄Π΅ `haml`, `erb`,
2148
+ `halt` ΠΈ Ρ‚.Π΄. доступны ΠΈ ΠΈΠΌ.
2149
+
2150
+ ### Not Found
2151
+
2152
+ Когда Π²Ρ‹Π±Ρ€ΠΎΡˆΠ΅Π½ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ `Sinatra::NotFound`, ΠΈΠ»ΠΈ ΠΊΠΎΠ΄ΠΎΠΌ ΠΎΡ‚Π²Π΅Ρ‚Π° являСтся 404,
2153
+ Ρ‚ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π·Π²Π°Π½ `not_found` ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ:
2154
+
2155
+ ```ruby
2156
+ not_found do
2157
+ 'This is nowhere to be found.'
2158
+ end
2159
+ ```
2160
+
2161
+ ### Ошибки
2162
+
2163
+ ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ошибок `error` Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π·Π²Π°Π½, ΠΊΠΎΠ³Π΄Π° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π²Ρ‹Π±Ρ€ΠΎΡˆΠ΅Π½ΠΎ ΠΈΠ· Π±Π»ΠΎΠΊΠ°
2164
+ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π°, Π»ΠΈΠ±ΠΎ ΠΈΠ· Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°. ΠžΠ±ΡŠΠ΅ΠΊΡ‚-ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ доступСн ΠΊΠ°ΠΊ пСрСмСнная
2165
+ `sinatra.error` Π² Rack:
2166
+
2167
+ ```ruby
2168
+ error do
2169
+ 'Sorry there was a nasty error - ' + env['sinatra.error'].name
2170
+ end
2171
+ ```
2172
+
2173
+ ΠšΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹Π΅ ошибки:
2174
+
2175
+ ```ruby
2176
+ error MyCustomError do
2177
+ 'So what happened was...' + env['sinatra.error'].message
2178
+ end
2179
+ ```
2180
+
2181
+ Π’ΠΎΠ³Π΄Π°, Ссли это ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»ΠΎ:
2182
+
2183
+ ```ruby
2184
+ get '/' do
2185
+ raise MyCustomError, 'something bad'
2186
+ end
2187
+ ```
2188
+
2189
+ Π’ΠΎ Π²Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅:
2190
+
2191
+ ```
2192
+ So what happened was... something bad
2193
+ ```
2194
+
2195
+ Π’Π°ΠΊΠΆΠ΅ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ошибок для ΠΊΠΎΠ΄Π° состояния HTTP:
2196
+
2197
+ ```ruby
2198
+ error 403 do
2199
+ 'Access forbidden'
2200
+ end
2201
+
2202
+ get '/secret' do
2203
+ 403
2204
+ end
2205
+ ```
2206
+
2207
+ Π›ΠΈΠ±ΠΎ Π½Π°Π±ΠΎΡ€Π° ΠΊΠΎΠ΄ΠΎΠ²:
2208
+
2209
+ ```ruby
2210
+ error 400..510 do
2211
+ 'Boom'
2212
+ end
2213
+ ```
2214
+
2215
+ Sinatra устанавливаСт ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Π΅ `not_found` ΠΈ `error` ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ, ΠΊΠΎΠ³Π΄Π°
2216
+ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π·Π°ΠΏΡƒΡ‰Π΅Π½ΠΎ Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ (ΠΎΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΠ΅ `:development`).
2217
+
2218
+ ## Rack "прослойки"
2219
+
2220
+ Sinatra ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ [Rack](http://rack.rubyforge.org/), ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ стандартный
2221
+ интСрфСйс для Π²Π΅Π±-Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠΎΠ² Π½Π° Ruby. Одной ΠΈΠ· самых интСрСсных для
2222
+ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ² возмоТностСй Rack являСтся ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° "прослоСк" ("middleware") β€”
2223
+ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ², находящихся "ΠΌΠ΅ΠΆΠ΄Ρƒ" сСрвСром ΠΈ вашим ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΠΌ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅
2224
+ ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°ΡŽΡ‚ ΠΈ/ΠΈΠ»ΠΈ ΠΌΠ°Π½ΠΈΠΏΡƒΠ»ΠΈΡ€ΡƒΡŽΡ‚ HTTP запросами/ΠΎΡ‚Π²Π΅Ρ‚Π°ΠΌΠΈ для прСдоставлСния
2225
+ Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ.
2226
+
2227
+ Π’ Sinatra ΠΎΡ‡Π΅Π½ΡŒ просто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚Π°ΠΊΠΈΠ΅ "прослойки" с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° `use`:
2228
+
2229
+ ```ruby
2230
+ require 'sinatra'
2231
+ require 'my_custom_middleware'
2232
+
2233
+ use Rack::Lint
2234
+ use MyCustomMiddleware
2235
+
2236
+ get '/hello' do
2237
+ 'Hello World'
2238
+ end
2239
+ ```
2240
+
2241
+ Π‘Π΅ΠΌΠ°Π½Ρ‚ΠΈΠΊΠ° `use` ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ‡Π½Π° Ρ‚ΠΎΠΉ, Ρ‡Ρ‚ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π° для
2242
+ [Rack::Builder](http://rack.rubyforge.org/doc/classes/Rack/Builder.html) DSL
2243
+ (Ρ‡Π°Ρ‰Π΅ всСго ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π² rackup Ρ„Π°ΠΉΠ»Π°Ρ…). НапримСр, ΠΌΠ΅Ρ‚ΠΎΠ΄ `use` ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ ΠΊΠ°ΠΊ
2244
+ мноТСствСнныС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅, Ρ‚Π°ΠΊ ΠΈ Π±Π»ΠΎΠΊΠΈ:
2245
+
2246
+ ```ruby
2247
+ use Rack::Auth::Basic do |username, password|
2248
+ username == 'admin' && password == 'secret'
2249
+ end
2250
+ ```
2251
+
2252
+ Rack распространяСтся с Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌΠΈ стандартными "прослойками" для логирования,
2253
+ ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ, ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΈΠ·Π°Ρ†ΠΈΠΈ URL, Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ сСссий. Sinatra
2254
+ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΌΠ½ΠΎΠ³ΠΈΠ΅ ΠΈΠ· этих ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² автоматичСски, ΠΎΡΠ½ΠΎΠ²Ρ‹Π²Π°ΡΡΡŒ Π½Π°
2255
+ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²Π°ΠΌ Π½Π΅ ΠΏΡ€ΠΈΡ…ΠΎΠ΄ΠΈΠ»ΠΎΡΡŒ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ (`use`) ΠΈΡ… Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ.
2256
+
2257
+ Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π½Π°ΠΉΡ‚ΠΈ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹Π΅ прослойки Π²
2258
+ [rack](https://github.com/rack/rack/tree/master/lib/rack),
2259
+ [rack-contrib](https://github.com/rack/rack-contrib#readme),
2260
+ ΠΈΠ»ΠΈ Π²
2261
+ [Rack wiki](https://github.com/rack/rack/wiki/List-of-Middleware).
2262
+
2263
+ ## ВСстированиС
2264
+
2265
+ ВСсты для Sinatra ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ написаны с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ,
2266
+ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠΎΠ², ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‰ΠΈΡ… тСстированиС Rack.
2267
+ [Rack::Test](http://rdoc.info/github/brynary/rack-test/master/frames)
2268
+ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΠΎΠ²Π°Π½:
2269
+
2270
+ ```ruby
2271
+ require 'my_sinatra_app'
2272
+ require 'test/unit'
2273
+ require 'rack/test'
2274
+
2275
+ class MyAppTest < Test::Unit::TestCase
2276
+ include Rack::Test::Methods
2277
+
2278
+ def app
2279
+ Sinatra::Application
2280
+ end
2281
+
2282
+ def test_my_default
2283
+ get '/'
2284
+ assert_equal 'Hello World!', last_response.body
2285
+ end
2286
+
2287
+ def test_with_params
2288
+ get '/meet', :name => 'Frank'
2289
+ assert_equal 'Hello Frank!', last_response.body
2290
+ end
2291
+
2292
+ def test_with_rack_env
2293
+ get '/', {}, 'HTTP_USER_AGENT' => 'Songbird'
2294
+ assert_equal "You're using Songbird!", last_response.body
2295
+ end
2296
+ end
2297
+ ```
2298
+
2299
+ ## Sinatra::Base β€” "прослойки", Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ ΠΈ ΠΌΠΎΠ΄ΡƒΠ»ΡŒΠ½Ρ‹Π΅ прилоТСния
2300
+
2301
+ ОписаниС своСго прилоТСния самым ΠΏΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠΈΠΌ способом (с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ DSL Π²Π΅Ρ€Ρ…Π½Π΅Π³ΠΎ
2302
+ уровня, классичСский ΡΡ‚ΠΈΠ»ΡŒ) ΠΎΡ‚Π»ΠΈΡ‡Π½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ для ΠΊΡ€ΠΎΡ…ΠΎΡ‚Π½Ρ‹Ρ… ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ. Π’ Ρ‚Π°ΠΊΠΈΡ…
2303
+ случаях ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ конфигурация, рассчитанная Π½Π° ΠΌΠΈΠΊΡ€ΠΎ-прилоТСния
2304
+ (СдинствСнный Ρ„Π°ΠΉΠ» прилоТСния, `./public` ΠΈ `./views` Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ, Π»ΠΎΠ³ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅,
2305
+ страница ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎΠ± ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΈ ΠΈ Ρ‚.Π΄.). Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, Ρ‚Π°ΠΊΠΎΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΈΠΌΠ΅Π΅Ρ‚
2306
+ мноТСство нСдостатков ΠΏΡ€ΠΈ создании ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ², Ρ‚Π°ΠΊΠΈΡ… ΠΊΠ°ΠΊ Rack middleware
2307
+ ("прослоСк"), Rails metal, простых Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ с сСрвСрными ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°ΠΌΠΈ,
2308
+ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠΉ Sinatra. И Ρ‚ΡƒΡ‚ Π½Π° ΠΏΠΎΠΌΠΎΡ‰ΡŒ ΠΏΡ€ΠΈΡ…ΠΎΠ΄ΠΈΡ‚ `Sinatra::Base`:
2309
+
2310
+ ```ruby
2311
+ require 'sinatra/base'
2312
+
2313
+ class MyApp < Sinatra::Base
2314
+ set :sessions, true
2315
+ set :foo, 'bar'
2316
+
2317
+ get '/' do
2318
+ 'Hello world!'
2319
+ end
2320
+ end
2321
+ ```
2322
+
2323
+ ΠœΠ΅Ρ‚ΠΎΠ΄Ρ‹, доступныС `Sinatra::Base` подклассам ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ‡Π½Ρ‹ Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ доступны
2324
+ прилоТСниям Π² DSL Π²Π΅Ρ€Ρ…Π½Π΅Π³ΠΎ уровня. Π‘ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²ΠΎ Ρ‚Π°ΠΊΠΈΡ… ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ
2325
+ ΠΊΠΎΠ½Π²Π΅Ρ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ Π² `Sinatra::Base` ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π΄Π²ΡƒΡ… ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΉ:
2326
+
2327
+ * Π’Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ `sinatra/base` вмСсто `sinatra`, ΠΈΠ½Π°Ρ‡Π΅ всС ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹,
2328
+ прСдоставляСмыС Sinatra, Π±ΡƒΠ΄ΡƒΡ‚ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ Π² глобальноС пространство
2329
+ ΠΈΠΌΠ΅Π½.
2330
+ * ΠŸΠΎΠΌΠ΅ΡΡ‚ΠΈΡ‚Π΅ всС ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Ρ‹, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ ошибок, Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Ρ‹ ΠΈ ΠΎΠΏΡ†ΠΈΠΈ Π² подкласс
2331
+ `Sinatra::Base`.
2332
+
2333
+ `Sinatra::Base` β€” это чистый лист. Π‘ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²ΠΎ ΠΎΠΏΡ†ΠΈΠΉ, Π²ΠΊΠ»ΡŽΡ‡Π°Ρ встроСнный
2334
+ сСрвСр, ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹. Π‘ΠΌΠΎΡ‚Ρ€ΠΈΡ‚Π΅
2335
+ [ΠžΠΏΡ†ΠΈΠΈ ΠΈ конфигурация](http://www.sinatrarb.com/configuration.html)
2336
+ для Π΄Π΅Ρ‚Π°Π»ΡŒΠ½ΠΎΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎΠ± опциях ΠΈ ΠΈΡ… ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠΈ.
2337
+
2338
+ ### ΠœΠΎΠ΄ΡƒΠ»ΡŒΠ½Ρ‹Π΅ прилоТСния ΠΏΡ€ΠΎΡ‚ΠΈΠ² классичСских
2339
+
2340
+ Π’ΠΎΠΏΡ€Π΅ΠΊΠΈ всСобщСму ΡƒΠ±Π΅ΠΆΠ΄Π΅Π½ΠΈΡŽ, Π² классичСском стилС (самом простом) Π½Π΅Ρ‚ Π½ΠΈΡ‡Π΅Π³ΠΎ
2341
+ ΠΏΠ»ΠΎΡ…ΠΎΠ³ΠΎ. Если этот ΡΡ‚ΠΈΠ»ΡŒ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ Π²Π°ΡˆΠ΅ΠΌΡƒ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡŽ, Π²Ρ‹ Π½Π΅ обязаны
2342
+ ΠΏΠ΅Ρ€Π΅ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ Π΅Π³ΠΎ Π² ΠΌΠΎΠ΄ΡƒΠ»ΡŒΠ½ΠΎΠ΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅.
2343
+
2344
+ ΠžΡΠ½ΠΎΠ²Π½Ρ‹ΠΌ нСдостатком классичСского стиля являСтся Ρ‚ΠΎΡ‚ Ρ„Π°ΠΊΡ‚, Ρ‡Ρ‚ΠΎ Ρƒ вас ΠΌΠΎΠΆΠ΅Ρ‚
2345
+ Π±Ρ‹Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Sinatra Π½Π° ΠΎΠ΄ΠΈΠ½ процСсс Ruby. Если Π²Ρ‹ ΠΏΠ»Π°Π½ΠΈΡ€ΡƒΠ΅Ρ‚Π΅
2346
+ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ большС, ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π°ΠΉΡ‚Π΅ΡΡŒ Π½Π° ΠΌΠΎΠ΄ΡƒΠ»ΡŒΠ½Ρ‹ΠΉ ΡΡ‚ΠΈΠ»ΡŒ. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ смСло
2347
+ ΡΠΌΠ΅ΡˆΠΈΠ²Π°Ρ‚ΡŒ ΠΌΠΎΠ΄ΡƒΠ»ΡŒΠ½Ρ‹ΠΉ ΠΈ классичСский стили.
2348
+
2349
+ ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄Ρ с ΠΎΠ΄Π½ΠΎΠ³ΠΎ стиля Π½Π° Π΄Ρ€ΡƒΠ³ΠΎΠΉ, ΠΏΡ€ΠΈΠΌΠΈΡ‚Π΅ Π²ΠΎ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ измСнСния Π²
2350
+ настройках:
2351
+
2352
+ ΠžΠΏΡ†ΠΈΡ ΠšΠ»Π°ΡΡΠΈΡ‡Π΅ΡΠΊΠΈΠΉ ΠœΠΎΠ΄ΡƒΠ»ΡŒΠ½Ρ‹ΠΉ
2353
+
2354
+ app_file Ρ„Π°ΠΉΠ» с ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΠΌ Ρ„Π°ΠΉΠ» с подклассом Sinatra::Base
2355
+ run $0 == app_file false
2356
+ logging true false
2357
+ method_override true false
2358
+ inline_templates true false
2359
+ static true false
2360
+
2361
+ ### Запуск ΠΌΠΎΠ΄ΡƒΠ»ΡŒΠ½Ρ‹Ρ… ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ
2362
+
2363
+ Π•ΡΡ‚ΡŒ Π΄Π²Π° общСпринятых способа Π·Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ ΠΌΠΎΠ΄ΡƒΠ»ΡŒΠ½Ρ‹Π΅ прилоТСния: запуск Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ
2364
+ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ `run!`:
2365
+
2366
+ ```ruby
2367
+ # my_app.rb
2368
+ require 'sinatra/base'
2369
+
2370
+ class MyApp < Sinatra::Base
2371
+ # ... здСсь ΠΊΠΎΠ΄ прилоТСния ...
2372
+
2373
+ # запускаСм сСрвСр, Ссли исполняСтся Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ Ρ„Π°ΠΉΠ»
2374
+ run! if app_file == $0
2375
+ end
2376
+ ```
2377
+
2378
+ Π—Π°Ρ‚Π΅ΠΌ:
2379
+
2380
+ ```
2381
+ ruby my_app.rb
2382
+ ```
2383
+
2384
+ Или с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π° `config.ru`, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ позволяСт
2385
+ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ любой Rack-совмСстимый сСрвСр ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ.
2386
+
2387
+ ```ruby
2388
+ # config.ru
2389
+ require './my_app'
2390
+ run MyApp
2391
+ ```
2392
+
2393
+ ЗапускаСм:
2394
+
2395
+ ```
2396
+ rackup -p 4567
2397
+ ```
2398
+
2399
+ ### Запуск классичСских ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ с config.ru
2400
+
2401
+ Π€Π°ΠΉΠ» прилоТСния:
2402
+
2403
+ ```ruby
2404
+ # app.rb
2405
+ require 'sinatra'
2406
+
2407
+ get '/' do
2408
+ 'Hello world!'
2409
+ end
2410
+ ```
2411
+
2412
+ И ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ `config.ru`:
2413
+
2414
+ ```ruby
2415
+ require './app'
2416
+ run Sinatra::Application
2417
+ ```
2418
+
2419
+ ### Когда ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ config.ru?
2420
+
2421
+ Π’ΠΎΡ‚ нСсколько ΠΏΡ€ΠΈΡ‡ΠΈΠ½, ΠΏΠΎ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ Π²Ρ‹, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π·Π°Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ
2422
+ `config.ru`:
2423
+
2424
+ * Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Ρ‚ΡŒ своС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π° Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… Rack-совмСстимых
2425
+ сСрвСрах (Passenger, Unicorn, Heroku, ...);
2426
+ * Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ подкласса `Sinatra::Base`;
2427
+ * Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Sinatra Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² качСствС "прослойки" Rack.
2428
+
2429
+ **БовсСм Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒ Π½Π° использованиС `config.ru` лишь ΠΏΠΎΡ‚ΠΎΠΌΡƒ,
2430
+ Ρ‡Ρ‚ΠΎ Π²Ρ‹ стали ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠΎΠ΄ΡƒΠ»ΡŒΠ½Ρ‹ΠΉ ΡΡ‚ΠΈΠ»ΡŒ прилоТСния. И Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ
2431
+ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠΎΠ΄ΡƒΠ»ΡŒΠ½Ρ‹ΠΉ ΡΡ‚ΠΈΠ»ΡŒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π·Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ
2432
+ `config.ru`.**
2433
+
2434
+ ### ИспользованиС Sinatra Π² качСствС "прослойки"
2435
+
2436
+ НС Ρ‚ΠΎΠ»ΡŒΠΊΠΎ сама Sinatra ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ "прослойки" Rack, Π½ΠΎ ΠΈ любоС Sinatra
2437
+ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ само ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΎ ΠΊ Π»ΡŽΠ±ΠΎΠΌΡƒ Rack endpoint Π² качСствС
2438
+ "прослойки". Π­Ρ‚ΠΈΠΌ endpoint (ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎΠΉ Ρ‚ΠΎΡ‡ΠΊΠΎΠΉ) ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π΄Ρ€ΡƒΠ³ΠΎΠ΅ Sinatra
2439
+ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ΠΈΠ»ΠΈ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, основанноС Π½Π° Rack (Rails/Ramaze/Camping/...):
2440
+
2441
+ ```ruby
2442
+ require 'sinatra/base'
2443
+
2444
+ class LoginScreen < Sinatra::Base
2445
+ enable :sessions
2446
+
2447
+ get('/login') { haml :login }
2448
+
2449
+ post('/login') do
2450
+ if params[:name] == 'admin' && params[:password] == 'admin'
2451
+ session['user_name'] = params[:name]
2452
+ else
2453
+ redirect '/login'
2454
+ end
2455
+ end
2456
+ end
2457
+
2458
+ class MyApp < Sinatra::Base
2459
+ # "прослойка" Π±ΡƒΠ΄Π΅Ρ‚ Π·Π°ΠΏΡƒΡ‰Π΅Π½Π° ΠΏΠ΅Ρ€Π΅Π΄ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°ΠΌΠΈ
2460
+ use LoginScreen
2461
+
2462
+ before do
2463
+ unless session['user_name']
2464
+ halt "Access denied, please <a href='/login'>login</a>."
2465
+ end
2466
+ end
2467
+
2468
+ get('/') { "Hello #{session['user_name']}." }
2469
+ end
2470
+ ```
2471
+
2472
+ ### Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ "Π½Π° Π»Π΅Ρ‚Ρƒ"
2473
+
2474
+ Иногда трСбуСтся ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Sinatra прилоТСния "Π½Π° Π»Π΅Ρ‚Ρƒ" (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ
2475
+ прилоТСния). Π­Ρ‚ΠΎ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ `Sinatra.new`:
2476
+
2477
+ ```ruby
2478
+ require 'sinatra/base'
2479
+ my_app = Sinatra.new { get('/') { "hi" } }
2480
+ my_app.run!
2481
+ ```
2482
+
2483
+ Π­Ρ‚ΠΎΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠΌ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ΠΎΡ‚ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ слСдуСт
2484
+ Π½Π°ΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚ΡŒΡΡ:
2485
+
2486
+ ```ruby
2487
+ # config.ru
2488
+ require 'sinatra/base'
2489
+
2490
+ controller = Sinatra.new do
2491
+ enable :logging
2492
+ helpers MyHelpers
2493
+ end
2494
+
2495
+ map('/a') do
2496
+ run Sinatra.new(controller) { get('/') { 'a' } }
2497
+ end
2498
+
2499
+ map('/b') do
2500
+ run Sinatra.new(controller) { get('/') { 'b' } }
2501
+ end
2502
+ ```
2503
+
2504
+ Π­Ρ‚ΠΎ особСнно ΠΏΠΎΠ»Π΅Π·Π½ΠΎ для тСстирования Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠΉ Sinatra ΠΈ ΠΏΡ€ΠΈ использовании
2505
+ Sinatra Π²Π½ΡƒΡ‚Ρ€ΠΈ вашСй Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ.
2506
+
2507
+ Благодаря этому, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Sinatra ΠΊΠ°ΠΊ "прослойку" ΠΎΡ‡Π΅Π½ΡŒ просто:
2508
+
2509
+ ```ruby
2510
+ require 'sinatra/base'
2511
+
2512
+ use Sinatra do
2513
+ get('/') { ... }
2514
+ end
2515
+
2516
+ run RailsProject::Application
2517
+ ```
2518
+
2519
+ ## ΠžΠ±Π»Π°ΡΡ‚ΠΈ видимости ΠΈ привязка
2520
+
2521
+ ВСкущая ΠΎΠ±Π»Π°ΡΡ‚ΡŒ видимости опрСдСляСт ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅, доступныС Π² Π΄Π°Π½Π½Ρ‹ΠΉ
2522
+ ΠΌΠΎΠΌΠ΅Π½Ρ‚.
2523
+
2524
+ ### ΠžΠ±Π»Π°ΡΡ‚ΡŒ видимости прилоТСния / класса
2525
+
2526
+ Π›ΡŽΠ±ΠΎΠ΅ Sinatra ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ соотвСтствуСт подклассу `Sinatra::Base`. Если Π²Ρ‹
2527
+ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ DSL Π²Π΅Ρ€Ρ…Π½Π΅Π³ΠΎ уровня (`require 'sinatra'`), Ρ‚ΠΎ этим классом Π±ΡƒΠ΄Π΅Ρ‚
2528
+ `Sinatra::Application`, ΠΈΠ½Π°Ρ‡Π΅ это Π±ΡƒΠ΄Π΅Ρ‚ подкласс, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²Ρ‹ создали Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ.
2529
+ На ΡƒΡ€ΠΎΠ²Π½Π΅ класса Π²Π°ΠΌ Π±ΡƒΠ΄ΡƒΡ‚ доступны Ρ‚Π°ΠΊΠΈΠ΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹, ΠΊΠ°ΠΊ `get` ΠΈΠ»ΠΈ `before`, Π½ΠΎ
2530
+ Π²Ρ‹ Π½Π΅ смоТСтС ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ доступ ΠΊ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌ `request` ΠΈΠ»ΠΈ `session`, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ
2531
+ сущСствуСт Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ класс прилоТСния для всСх запросов.
2532
+
2533
+ ΠžΠΏΡ†ΠΈΠΈ, созданныС с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ `set`, ΡΠ²Π»ΡΡŽΡ‚ΡΡ ΠΌΠ΅Ρ‚ΠΎΠ΄Π°ΠΌΠΈ уровня класса:
2534
+
2535
+ ```ruby
2536
+ class MyApp < Sinatra::Base
2537
+ # Π― Π² области видимости прилоТСния!
2538
+ set :foo, 42
2539
+ foo # => 42
2540
+
2541
+ get '/foo' do
2542
+ # Π― большС Π½Π΅ Π² области видимости прилоТСния!
2543
+ end
2544
+ end
2545
+ ```
2546
+
2547
+ Π£ вас Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠ±Π»Π°ΡΡ‚ΡŒ видимости прилоТСния Π²Π½ΡƒΡ‚Ρ€ΠΈ:
2548
+
2549
+ * Ρ‚Π΅Π»Π° вашСго класса прилоТСния;
2550
+ * ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ², ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Ρ… Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡΠΌΠΈ;
2551
+ * Π±Π»ΠΎΠΊΠ°, ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΠΎΠ³ΠΎ Π² `helpers`;
2552
+ * Π±Π»ΠΎΠΊΠΎΠ², ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π½Π½Ρ‹Ρ… ΠΊΠ°ΠΊ значСния для `set`;
2553
+ * Π±Π»ΠΎΠΊΠ°, ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΠΎΠ³ΠΎ Π² `Sinatra.new`.
2554
+
2555
+ Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ доступ ΠΊ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ области видимости (классу прилоТСния)
2556
+ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌΠΈ способами:
2557
+
2558
+ * Ρ‡Π΅Ρ€Π΅Π· ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹ΠΉ Π±Π»ΠΎΠΊΠ°ΠΌ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ (`configure { |c| ... }`);
2559
+ * `settings` Π²Π½ΡƒΡ‚Ρ€ΠΈ области видимости запроса.
2560
+
2561
+ ### ΠžΠ±Π»Π°ΡΡ‚ΡŒ видимости запроса/экзСмпляра
2562
+
2563
+ Для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ входящСго запроса Π±ΡƒΠ΄Π΅Ρ‚ создан Π½ΠΎΠ²Ρ‹ΠΉ экзСмпляр вашСго прилоТСния,
2564
+ ΠΈ всС Π±Π»ΠΎΠΊΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° Π±ΡƒΠ΄ΡƒΡ‚ Π·Π°ΠΏΡƒΡ‰Π΅Π½Ρ‹ Π² этом контСкстС. Π’ этой области
2565
+ видимости Π²Π°ΠΌ доступны `request` ΠΈ `session` ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, Π²Ρ‹Π·ΠΎΠ²Ρ‹ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ²
2566
+ Ρ€Π΅Π½Π΄Π΅Ρ€ΠΈΠ½Π³Π°, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ `erb` ΠΈΠ»ΠΈ `haml`. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ доступ ΠΊ области
2567
+ видимости прилоТСния ΠΈΠ· контСкста запроса, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ ΠΌΠ΅Ρ‚ΠΎΠ΄-ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊ
2568
+ `settings`:
2569
+
2570
+ ```ruby
2571
+ class MyApp < Sinatra::Base
2572
+ # Π― Π² области видимости прилоТСния!
2573
+ get '/define_route/:name' do
2574
+ # ΠžΠ±Π»Π°ΡΡ‚ΡŒ видимости запроса '/define_route/:name'
2575
+ @value = 42
2576
+
2577
+ settings.get("/#{params[:name]}") do
2578
+ # ΠžΠ±Π»Π°ΡΡ‚ΡŒ видимости запроса "/#{params[:name]}"
2579
+ @value # => nil (Π΄Ρ€ΡƒΠ³ΠΎΠΉ запрос)
2580
+ end
2581
+
2582
+ "Route defined!"
2583
+ end
2584
+ end
2585
+ ```
2586
+
2587
+ Π£ вас Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠ±Π»Π°ΡΡ‚ΡŒ видимости запроса Π²:
2588
+
2589
+ * get/head/post/put/delete/options Π±Π»ΠΎΠΊΠ°Ρ…;
2590
+ * before/after Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°Ρ…;
2591
+ * ΠΌΠ΅Ρ‚ΠΎΠ΄Π°Ρ…-ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΠΊΠ°Ρ…;
2592
+ * ΡˆΠ°Π±Π»ΠΎΠ½Π°Ρ…/отобраТСниях.
2593
+
2594
+ ### ΠžΠ±Π»Π°ΡΡ‚ΡŒ видимости дСлСгирования
2595
+
2596
+ ΠžΠ±Π»Π°ΡΡ‚ΡŒ видимости дСлСгирования просто пСрСнаправляСт ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ Π² ΠΎΠ±Π»Π°ΡΡ‚ΡŒ
2597
+ видимости класса. Однако, ΠΎΠ½Π° Π½Π΅ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ Π²Π΅Π΄Π΅Ρ‚ сСбя ΠΊΠ°ΠΊ ΠΎΠ±Π»Π°ΡΡ‚ΡŒ видимости
2598
+ класса, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Ρƒ вас Π½Π΅Ρ‚ привязки ΠΊ классу. Волько ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹, явно ΠΏΠΎΠΌΠ΅Ρ‡Π΅Π½Π½Ρ‹Π΅
2599
+ для дСлСгирования, Π±ΡƒΠ΄ΡƒΡ‚ доступны, Π° ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…/состояний области видимости
2600
+ класса Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ (ΠΈΠ½Π°Ρ‡Π΅ говоря, Ρƒ вас Π±ΡƒΠ΄Π΅Ρ‚ Π΄Ρ€ΡƒΠ³ΠΎΠΉ `self` ΠΎΠ±ΡŠΠ΅ΠΊΡ‚). Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅
2601
+ нСпосрСдствСнно Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ дСлСгирования, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ
2602
+ `Sinatra::Delegator.delegate :method_name`.
2603
+
2604
+ Π£ вас Π±ΡƒΠ΄Π΅Ρ‚ контСкст дСлСгирования Π²Π½ΡƒΡ‚Ρ€ΠΈ:
2605
+
2606
+ * привязки Π²Π΅Ρ€Ρ…Π½Π΅Π³ΠΎ уровня, Ссли Π²Ρ‹ сдСлали `require 'sinatra'`;
2607
+ * ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½Π½ΠΎΠ³ΠΎ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ `Sinatra::Delegator`.
2608
+
2609
+ ΠŸΠΎΡΠΌΠΎΡ‚Ρ€ΠΈΡ‚Π΅ сами Π² ΠΊΠΎΠ΄: Π²ΠΎΡ‚
2610
+ [ΠΏΡ€ΠΈΠΌΠ΅ΡΡŒ Sinatra::Delegator](https://github.com/sinatra/sinatra/blob/ca06364/lib/sinatra/base.rb#L1609-1633)
2611
+ [Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅Ρ‚ Π³Π»Π°Π²Π½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚](https://github.com/sinatra/sinatra/blob/ca06364/lib/sinatra/main.rb#L28-30).
2612
+
2613
+ ## Командная строка
2614
+
2615
+ Sinatra прилоТСния ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Π·Π°ΠΏΡƒΡ‰Π΅Π½Ρ‹ Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ:
2616
+
2617
+ ```
2618
+ ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-o HOST] [-s HANDLER]
2619
+ ```
2620
+
2621
+ ΠžΠΏΡ†ΠΈΠΈ Π²ΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‚:
2622
+
2623
+ ```
2624
+ -h # Ρ€Π°Π·Π΄Π΅Π» ΠΏΠΎΠΌΠΎΡ‰ΠΈ
2625
+ -p # ΡƒΠΊΠ°Π·Π°Π½ΠΈΠ΅ ΠΏΠΎΡ€Ρ‚Π° (ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ 4567)
2626
+ -o # ΡƒΠΊΠ°Π·Π°Π½ΠΈΠ΅ хоста (ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ 0.0.0.0)
2627
+ -e # ΡƒΠΊΠ°Π·Π°Π½ΠΈΠ΅ окруТСния, Ρ€Π΅ΠΆΠΈΠΌΠ° (ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ development)
2628
+ -s # ΡƒΠΊΠ°Π·Π°Π½ΠΈΠ΅ rack сСрвСра/ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° (ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ thin)
2629
+ -x # Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ-Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ (ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π²Ρ‹ΠΊΠ»ΡŽΡ‡Π΅Π½Π°)
2630
+ ```
2631
+
2632
+ ## БистСмныС трСбования
2633
+
2634
+ Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ вСрсии Ruby ΠΎΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½ΠΎ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ΡΡ:
2635
+
2636
+ <dl>
2637
+ <dt>Ruby 1.8.7</dt>
2638
+ <dd>1.8.7 ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ поддСрТиваСтся, Ρ‚Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, Ссли вас Π½ΠΈΡ‡Ρ‚ΠΎ Π½Π΅ Π΄Π΅Ρ€ΠΆΠΈΡ‚ Π½Π°
2639
+ этой вСрсии, Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅ΠΌ ΠΎΠ±Π½ΠΎΠ²ΠΈΡ‚ΡŒΡΡ Π΄ΠΎ 1.9.2 ΠΈΠ»ΠΈ ΠΏΠ΅Ρ€Π΅ΠΉΡ‚ΠΈ Π½Π° JRuby ΠΈΠ»ΠΈ
2640
+ Rubinius. ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° 1.8.7 Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€Π΅ΠΊΡ€Π°Ρ‰Π΅Π½Π° Π΄ΠΎ Π²Ρ‹Ρ…ΠΎΠ΄Π° Sinatra 2.0 ΠΈ Ruby
2641
+ 2.0, Ρ€Π°Π·Π²Π΅ Ρ‡Ρ‚ΠΎ Π² случаС Ρ€Π΅Π»ΠΈΠ·Π° 1.8.8 (Ρ‡Ρ‚ΠΎ маловСроятно). Но Π΄Π°ΠΆΠ΅ Ρ‚ΠΎΠ³Π΄Π°,
2642
+ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€Π΅ΠΊΡ€Π°Ρ‰Π΅Π½Π°. <b>Ruby 1.8.6 большС Π½Π΅
2643
+ поддСрТиваСтся.</b> Если Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ 1.8.6, ΠΎΡ‚ΠΊΠ°Ρ‚ΠΈΡ‚Π΅ΡΡŒ Π΄ΠΎ Sinatra
2644
+ 1.2, которая Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ всС исправлСния ошибок Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° Π½Π΅
2645
+ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΡƒΡ‰Π΅Π½Π° Sinatra 1.4.0.</dd>
2646
+
2647
+ <dt>Ruby 1.9.2</dt>
2648
+ <dd>1.9.2 ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ поддСрТиваСтся ΠΈ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΠΎΠ²Π°Π½Π° ΠΊ использованию.
2649
+ НС ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ 1.9.2p0,
2650
+ извСстно, Ρ‡Ρ‚ΠΎ эта вСрсия ΠΎΡ‡Π΅Π½ΡŒ Π½Π΅ΡΡ‚Π°Π±ΠΈΠ»ΡŒΠ½Π° ΠΏΡ€ΠΈ использовании Sinatra. Π­Ρ‚Π°
2651
+ вСрсия Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒΡΡ ΠΏΠΎ ΠΊΡ€Π°ΠΉΠ½Π΅ΠΉ ΠΌΠ΅Ρ€Π΅ Π΄ΠΎ Π²Ρ‹Ρ…ΠΎΠ΄Π° Ruby 1.9.4/2.0, Π°
2652
+ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° послСднСй вСрсии 1.9 Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²Π»ΡΡ‚ΡŒΡΡ Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° ΠΎΠ½Π°
2653
+ поддСрТиваСтся ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ² Ruby.</dd>
2654
+
2655
+ <dt>Ruby 1.9.3</dt>
2656
+ <dd>1.9.3 ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ поддСрТиваСтся. Π—Π°ΠΌΠ΅Ρ‚ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ Π½Π° 1.9.3 с
2657
+ Ρ€Π°Π½Π½ΠΈΡ… вСрсий сдСлаСт Π½Π΅Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ всС сСссии.</dd>
2658
+
2659
+ <dt>Rubinius</dt>
2660
+ <dd>Rubinius ΠΎΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½ΠΎ поддСрТиваСтся (Rubinius &gt;= 1.2.4), всё, Π²ΠΊΠ»ΡŽΡ‡Π°Ρ всС
2661
+ языки шаблонов, Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚. ΠŸΡ€Π΅Π΄ΡΡ‚ΠΎΡΡ‰ΠΈΠΉ Ρ€Π΅Π»ΠΈΠ· 2.0 Ρ‚Π°ΠΊΠΆΠ΅ поддСрТиваСтся.</dd>
2662
+
2663
+ <dt>JRuby</dt>
2664
+ <dd>JRuby ΠΎΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½ΠΎ поддСрТиваСтся (JRuby &gt;= 1.6.5). НСт Π½ΠΈΠΊΠ°ΠΊΠΈΡ… ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ с
2665
+ использованиСм Π°Π»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π½Ρ‹Ρ… шаблонов. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, Ссли Π²Ρ‹ Π²Ρ‹Π±ΠΈΡ€Π°Π΅Ρ‚Π΅
2666
+ JRuby, Ρ‚ΠΎ, поТалуйста, посмотритС Π½Π° JRuby Rack-сСрвСры, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Thin Π½Π΅
2667
+ поддСрТиваСтся ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ Π½Π° JRuby. ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠΉ Π½Π° C Π² JRuby всС
2668
+ Π΅Ρ‰Π΅ ΡΠΊΡΠΏΠ΅Ρ€ΠΈΠΌΠ΅Π½Ρ‚Π°Π»ΡŒΠ½Π°Ρ, Ρ‡Ρ‚ΠΎ Π½Π° Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π·Π°Ρ‚Ρ€Π°Π³ΠΈΠ²Π°Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ RDiscount,
2669
+ Redcarpet ΠΈ RedCloth.</dd>
2670
+ </dl>
2671
+
2672
+ ΠœΡ‹ Ρ‚Π°ΠΊΠΆΠ΅ слСдим Π·Π° прСдстоящими ΠΊ Π²Ρ‹Ρ…ΠΎΠ΄Ρƒ вСрсиями Ruby.
2673
+
2674
+ Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Ruby Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ΡΡ ΠΎΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½ΠΎ, Π½ΠΎ извСстно, Ρ‡Ρ‚ΠΎ Π½Π°
2675
+ Π½ΠΈΡ… запускаСтся Sinatra:
2676
+
2677
+ * старыС вСрсии JRuby ΠΈ Rubinius;
2678
+ * Ruby Enterprise Edition;
2679
+ * MacRuby, Maglev, IronRuby;
2680
+ * Ruby 1.9.0 ΠΈ 1.9.1 (Π½Π°ΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ Π½Π΅ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΡŽΡ‚ΡΡ ΠΊ использованию).
2681
+
2682
+ Π’ΠΎ, Ρ‡Ρ‚ΠΎ вСрсия ΠΎΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½ΠΎ Π½Π΅ поддСрТиваСтся, ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ, Ссли Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Π½Π΅
2683
+ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π½Π° этой вСрсии, Π° Π½Π° ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΠΎΠΉ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ β€” это Π½Π΅ наша ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°,
2684
+ Π° ΠΈΡ….
2685
+
2686
+ ΠœΡ‹ Ρ‚Π°ΠΊΠΆΠ΅ запускаСм наши CI-тСсты Π½Π° вСрсии Ruby, находящСйся Π² Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅
2687
+ (прСдстоящСй 2.0.0), ΠΈ Π½Π° 1.9.4, Π½ΠΎ ΠΌΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ Π½ΠΈΡ‡Π΅Π³ΠΎ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ
2688
+ ΠΎΠ½ΠΈ находятся Π² Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅. ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅Ρ‚ΡΡ, Ρ‡Ρ‚ΠΎ 1.9.4p0 ΠΈ 2.0.0p0 Π±ΡƒΠ΄ΡƒΡ‚
2689
+ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒΡΡ.
2690
+
2691
+ Sinatra Π΄ΠΎΠ»ΠΆΠ½Π° Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π½Π° любой ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠΉ систСмС, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π΅ΡΡ‚ΡŒ ΠΎΠ΄Π½Π° ΠΈΠ·
2692
+ ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹Ρ… Π²Ρ‹ΡˆΠ΅ вСрсий Ruby.
2693
+
2694
+ Пока Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ Sinatra Π½Π° Cardinal, SmallRuby, BlueRuby ΠΈ Π½Π° любой
2695
+ вСрсии Ruby Π΄ΠΎ 1.8.7.
2696
+
2697
+ ## На остриС
2698
+
2699
+ Если Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ самый послСдний ΠΊΠΎΠ΄ Sinatra, Π½Π΅ Π±ΠΎΠΉΡ‚Π΅ΡΡŒ Π·Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ
2700
+ своС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ вмСстС с ΠΊΠΎΠ΄ΠΎΠΌ ΠΈΠ· master Π²Π΅Ρ‚ΠΊΠΈ Sinatra, ΠΎΠ½Π° вСсьма ΡΡ‚Π°Π±ΠΈΠ»ΡŒΠ½Π°.
2701
+
2702
+ ΠœΡ‹ Ρ‚Π°ΠΊΠΆΠ΅ врСмя ΠΎΡ‚ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ выпускаСм ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ вСрсии, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅
2703
+ Π΄Π΅Π»Π°Ρ‚ΡŒ Ρ‚Π°ΠΊ:
2704
+
2705
+ ```
2706
+ gem install sinatra --pre
2707
+ ```
2708
+
2709
+ Π§Ρ‚ΠΎΠ±Ρ‹ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌΠΈ самыми послСдними возмоТностями.
2710
+
2711
+ ### Π‘ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Bundler
2712
+
2713
+ Если Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ Π·Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ своС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ с послСднСй вСрсиСй Sinatra, Ρ‚ΠΎ
2714
+ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ [Bundler](http://gembundler.com/).
2715
+
2716
+ Π‘Π½Π°Ρ‡Π°Π»Π° установитС Bundler, Ссли Ρƒ вас Π΅Π³ΠΎ Π΅Ρ‰Π΅ Π½Π΅Ρ‚:
2717
+
2718
+ ```
2719
+ gem install bundler
2720
+ ```
2721
+
2722
+ Π—Π°Ρ‚Π΅ΠΌ создайтС Ρ„Π°ΠΉΠ» `Gemfile` Π² Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ вашСго ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°:
2723
+
2724
+ ```ruby
2725
+ source :rubygems
2726
+ gem 'sinatra', :git => "git://github.com/sinatra/sinatra.git"
2727
+
2728
+ # Π΄Ρ€ΡƒΠ³ΠΈΠ΅ зависимости
2729
+ gem 'haml' # Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ссли ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ haml
2730
+ gem 'activerecord', '~> 3.0' # ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ, Π²Π°ΠΌ Π½ΡƒΠΆΠ΅Π½ ΠΈ ActiveRecord 3.x
2731
+ ```
2732
+
2733
+ ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Π²Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ всС зависимости вашСго прилоТСния
2734
+ Π² этом Ρ„Π°ΠΉΠ»Π΅. Однако, нСпосрСдствСнныС зависимости Sinatra (Rack ΠΈ Tilt)
2735
+ Bundler автоматичСски скачаСт ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚.
2736
+
2737
+ Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π·Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ своС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Ρ‚Π°ΠΊ:
2738
+
2739
+ ```
2740
+ bundle exec ruby myapp.rb
2741
+ ```
2742
+
2743
+ ### Π’Ρ€ΡƒΡ‡Π½ΡƒΡŽ
2744
+
2745
+ Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΠΊΠ»ΠΎΠ½ рСпозитория ΠΈ запускайтС своС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ с
2746
+ `sinatra/lib` Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠ΅ΠΉ Π² `$LOAD_PATH`:
2747
+
2748
+ ```
2749
+ cd myapp
2750
+ git clone git://github.com/sinatra/sinatra.git
2751
+ ruby -Isinatra/lib myapp.rb
2752
+ ```
2753
+
2754
+ Π§Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ±Π½ΠΎΠ²ΠΈΡ‚ΡŒ исходники Sinatra:
2755
+
2756
+ ```
2757
+ cd myapp/sinatra
2758
+ git pull
2759
+ ```
2760
+
2761
+ ### Установка глобально
2762
+
2763
+ Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ ΡΠΎΠ±Ρ€Π°Ρ‚ΡŒ gem:
2764
+
2765
+ ```
2766
+ git clone git://github.com/sinatra/sinatra.git
2767
+ cd sinatra
2768
+ rake sinatra.gemspec
2769
+ rake install
2770
+ ```
2771
+
2772
+ Если Π²Ρ‹ устанавливаСтС ΠΏΠ°ΠΊΠ΅Ρ‚Ρ‹ (gem) ΠΎΡ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ root, Ρ‚ΠΎ вашим послСдним
2773
+ шагом Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ ΠΊΠΎΠΌΠ°Π½Π΄Π°
2774
+
2775
+ ```
2776
+ sudo rake install
2777
+ ```
2778
+
2779
+ ## ВСрсии
2780
+
2781
+ Sinatra ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ [Semantic Versioning](http://semver.org/), SemVer ΠΈ
2782
+ SemVerTag.
2783
+
2784
+ ## Π”Π°Π»ΡŒΠ½Π΅ΠΉΡˆΠ΅Π΅ Ρ‡Ρ‚Π΅Π½ΠΈΠ΅
2785
+
2786
+ * [Π’Π΅Π±-сайт ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°](http://www.sinatrarb.com/) β€” Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ
2787
+ докумСнтация, новости ΠΈ ссылки Π½Π° Π΄Ρ€ΡƒΠ³ΠΈΠ΅ рСсурсы.
2788
+ * [УчастиС Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅](http://www.sinatrarb.com/contributing) β€” ΠžΠ±Π½Π°Ρ€ΡƒΠΆΠΈΠ»ΠΈ
2789
+ Π±Π°Π³? НуТна ΠΏΠΎΠΌΠΎΡ‰ΡŒ? Написали ΠΏΠ°Ρ‚Ρ‡?
2790
+ * [Π‘Π»Π΅ΠΆΠ΅Π½ΠΈΠ΅ Π·Π° ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°ΠΌΠΈ/ошибками](http://github.com/sinatra/sinatra/issues)
2791
+ * [Twitter](http://twitter.com/sinatra)
2792
+ * [Π“Ρ€ΡƒΠΏΠΏΡ‹ рассылки](http://groups.google.com/group/sinatrarb/topics)
2793
+ * [#sinatra](irc://chat.freenode.net/#sinatra) Π½Π° http://freenode.net
2794
+ * [Sinatra Book](http://sinatra-book.gittr.com) ΡƒΡ‡Π΅Π±Π½ΠΈΠΊ ΠΈ сборник Ρ€Π΅Ρ†Π΅ΠΏΡ‚ΠΎΠ²
2795
+ * [Sinatra Recipes](http://recipes.sinatrarb.com/) сборник Ρ€Π΅Ρ†Π΅ΠΏΡ‚ΠΎΠ²
2796
+ * API докумСнтация ΠΊ [послСднСму Ρ€Π΅Π»ΠΈΠ·Ρƒ](http://rubydoc.info/gems/sinatra)
2797
+ ΠΈΠ»ΠΈ [Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌΡƒ HEAD](http://rubydoc.info/github/sinatra/sinatra) Π½Π°
2798
+ http://rubydoc.info
2799
+ * [Π‘Π΅Ρ€Π²Π΅Ρ€ Π½Π΅ΠΏΡ€Π΅Ρ€Ρ‹Π²Π½ΠΎΠΉ ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΈ](http://travis-ci.org/sinatra/sinatra)