sinatra 1.4.8 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sinatra might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/AUTHORS.md +1 -0
- data/CHANGELOG.md +272 -54
- data/CONTRIBUTING.md +8 -8
- data/Gemfile +48 -47
- data/LICENSE +4 -1
- data/MAINTENANCE.md +42 -0
- data/README.de.md +651 -443
- data/README.es.md +738 -357
- data/README.fr.md +197 -100
- data/README.hu.md +40 -6
- data/README.ja.md +125 -67
- data/README.ko.md +15 -15
- data/README.malayalam.md +3141 -0
- data/README.md +592 -432
- data/README.pt-br.md +2362 -335
- data/README.pt-pt.md +5 -5
- data/README.ru.md +857 -608
- data/README.zh.md +91 -29
- data/Rakefile +77 -51
- data/SECURITY.md +35 -0
- data/VERSION +1 -0
- data/examples/chat.rb +2 -1
- data/examples/rainbows.conf +3 -0
- data/examples/rainbows.rb +20 -0
- data/examples/stream.ru +4 -4
- data/lib/sinatra/base.rb +243 -265
- data/lib/sinatra/indifferent_hash.rb +200 -0
- data/lib/sinatra/main.rb +30 -10
- data/lib/sinatra/show_exceptions.rb +67 -62
- data/lib/sinatra/version.rb +1 -1
- data/sinatra.gemspec +44 -8
- metadata +43 -167
- data/lib/sinatra/ext.rb +0 -17
- data/test/asciidoctor_test.rb +0 -72
- data/test/base_test.rb +0 -167
- data/test/builder_test.rb +0 -91
- data/test/coffee_test.rb +0 -96
- data/test/compile_test.rb +0 -183
- data/test/contest.rb +0 -91
- data/test/creole_test.rb +0 -65
- data/test/delegator_test.rb +0 -160
- data/test/encoding_test.rb +0 -20
- data/test/erb_test.rb +0 -116
- data/test/extensions_test.rb +0 -98
- data/test/filter_test.rb +0 -487
- data/test/haml_test.rb +0 -109
- data/test/helper.rb +0 -132
- data/test/helpers_test.rb +0 -1917
- data/test/integration/app.rb +0 -79
- data/test/integration_helper.rb +0 -236
- data/test/integration_test.rb +0 -104
- data/test/less_test.rb +0 -69
- data/test/liquid_test.rb +0 -77
- data/test/mapped_error_test.rb +0 -285
- data/test/markaby_test.rb +0 -80
- data/test/markdown_test.rb +0 -85
- data/test/mediawiki_test.rb +0 -68
- data/test/middleware_test.rb +0 -68
- data/test/nokogiri_test.rb +0 -67
- data/test/public/favicon.ico +0 -0
- data/test/public/hello+world.txt +0 -1
- data/test/rabl_test.rb +0 -89
- data/test/rack_test.rb +0 -45
- data/test/radius_test.rb +0 -59
- data/test/rdoc_test.rb +0 -66
- data/test/readme_test.rb +0 -130
- data/test/request_test.rb +0 -100
- data/test/response_test.rb +0 -63
- data/test/result_test.rb +0 -76
- data/test/route_added_hook_test.rb +0 -59
- data/test/routing_test.rb +0 -1456
- data/test/sass_test.rb +0 -115
- data/test/scss_test.rb +0 -88
- data/test/server_test.rb +0 -56
- data/test/settings_test.rb +0 -582
- data/test/sinatra_test.rb +0 -12
- data/test/slim_test.rb +0 -102
- data/test/static_test.rb +0 -266
- data/test/streaming_test.rb +0 -149
- data/test/stylus_test.rb +0 -90
- data/test/templates_test.rb +0 -382
- data/test/textile_test.rb +0 -65
- data/test/views/a/in_a.str +0 -1
- data/test/views/ascii.erb +0 -2
- data/test/views/b/in_b.str +0 -1
- data/test/views/calc.html.erb +0 -1
- data/test/views/error.builder +0 -3
- data/test/views/error.erb +0 -3
- data/test/views/error.haml +0 -3
- data/test/views/error.sass +0 -2
- data/test/views/explicitly_nested.str +0 -1
- data/test/views/foo/hello.test +0 -1
- data/test/views/hello.asciidoc +0 -1
- data/test/views/hello.builder +0 -1
- data/test/views/hello.coffee +0 -1
- data/test/views/hello.creole +0 -1
- data/test/views/hello.erb +0 -1
- data/test/views/hello.haml +0 -1
- data/test/views/hello.less +0 -5
- data/test/views/hello.liquid +0 -1
- data/test/views/hello.mab +0 -1
- data/test/views/hello.md +0 -1
- data/test/views/hello.mediawiki +0 -1
- data/test/views/hello.nokogiri +0 -1
- data/test/views/hello.rabl +0 -2
- data/test/views/hello.radius +0 -1
- data/test/views/hello.rdoc +0 -1
- data/test/views/hello.sass +0 -2
- data/test/views/hello.scss +0 -3
- data/test/views/hello.slim +0 -1
- data/test/views/hello.str +0 -1
- data/test/views/hello.styl +0 -2
- data/test/views/hello.test +0 -1
- data/test/views/hello.textile +0 -1
- data/test/views/hello.wlang +0 -1
- data/test/views/hello.yajl +0 -1
- data/test/views/layout2.builder +0 -3
- data/test/views/layout2.erb +0 -2
- data/test/views/layout2.haml +0 -2
- data/test/views/layout2.liquid +0 -2
- data/test/views/layout2.mab +0 -2
- data/test/views/layout2.nokogiri +0 -3
- data/test/views/layout2.rabl +0 -3
- data/test/views/layout2.radius +0 -2
- data/test/views/layout2.slim +0 -3
- data/test/views/layout2.str +0 -2
- data/test/views/layout2.test +0 -1
- data/test/views/layout2.wlang +0 -2
- data/test/views/nested.str +0 -1
- data/test/views/utf8.erb +0 -2
- data/test/wlang_test.rb +0 -87
- data/test/yajl_test.rb +0 -86
data/README.ru.md
CHANGED
@@ -1,12 +1,52 @@
|
|
1
1
|
# Sinatra
|
2
2
|
|
3
|
+
[![Build Status](https://secure.travis-ci.org/sinatra/sinatra.svg)](https://travis-ci.org/sinatra/sinatra)
|
4
|
+
|
5
|
+
*Внимание: Этот документ является переводом английской версии и может быть
|
6
|
+
устаревшим*
|
7
|
+
|
8
|
+
Sinatra — это предметно-ориентированный каркас
|
9
|
+
([DSL](https://ru.wikipedia.org/wiki/Предметно-ориентированный_язык))
|
10
|
+
для быстрого создания функциональных веб-приложений на Ruby с минимумом усилий:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
# myapp.rb
|
14
|
+
require 'sinatra'
|
15
|
+
|
16
|
+
get '/' do
|
17
|
+
'Hello world!'
|
18
|
+
end
|
19
|
+
```
|
20
|
+
|
21
|
+
Установите gem:
|
22
|
+
|
23
|
+
```shell
|
24
|
+
gem install sinatra
|
25
|
+
```
|
26
|
+
|
27
|
+
и запустите приложение при помощи:
|
28
|
+
|
29
|
+
```shell
|
30
|
+
ruby myapp.rb
|
31
|
+
```
|
32
|
+
|
33
|
+
Оцените результат: [http://localhost:4567](http://localhost:4567)
|
34
|
+
|
35
|
+
Имейте ввиду, что изменения в коде не будут видны до тех пор, пока вы не перезапустите
|
36
|
+
сервер. Пожалуйста, перезагружайте сервер каждый раз как вносите изменения или добавьте
|
37
|
+
в проект [sinatra/reloader](http://www.sinatrarb.com/contrib/reloader).
|
38
|
+
|
39
|
+
Рекомендуется также установить Thin сервер (`gem install thin`), который автоматически
|
40
|
+
работает с Sinatra приложениями.
|
41
|
+
|
3
42
|
## Содержание
|
4
43
|
|
5
44
|
* [Sinatra](#sinatra)
|
45
|
+
* [Содержание](#Содержание)
|
6
46
|
* [Маршруты](#Маршруты)
|
7
|
-
|
8
|
-
|
9
|
-
|
47
|
+
* [Условия](#Условия)
|
48
|
+
* [Возвращаемые значения](#Возвращаемые-значения)
|
49
|
+
* [Собственные детекторы совпадений для маршрутов](#Собственные-детекторы-совпадений-для-маршрутов)
|
10
50
|
* [Статические файлы](#Статические-файлы)
|
11
51
|
* [Представления / Шаблоны](#Представления--Шаблоны)
|
12
52
|
* [Буквальные шаблоны](#Буквальные-шаблоны)
|
@@ -34,19 +74,23 @@
|
|
34
74
|
* [Yajl шаблоны](#yajl-шаблоны)
|
35
75
|
* [WLang шаблоны](#wlang-шаблоны)
|
36
76
|
* [Доступ к переменным в шаблонах](#Доступ-к-переменным-в-шаблонах)
|
37
|
-
* [Шаблоны с `yield` и вложенные
|
77
|
+
* [Шаблоны с `yield` и вложенные лэйауты](#Шаблоны-с-yield-и-вложенные-лэйауты)
|
38
78
|
* [Включённые шаблоны](#Включённые-шаблоны)
|
39
79
|
* [Именованные шаблоны](#Именованные-шаблоны)
|
40
80
|
* [Привязка файловых расширений](#Привязка-файловых-расширений)
|
41
81
|
* [Добавление собственного движка рендеринга](#Добавление-собственного-движка-рендеринга)
|
82
|
+
* [Использование пользовательской логики для поиска шаблона](#Использование-пользовательской-логики-для-поиска-шаблона)
|
42
83
|
* [Фильтры](#Фильтры)
|
43
84
|
* [Методы-помощники](#Методы-помощники)
|
44
85
|
* [Использование сессий](#Использование-сессий)
|
86
|
+
* [Безопасность сессии](#Безопасность-сессии)
|
87
|
+
* [Конфигурация сессии](#Конфигурация-сессии)
|
88
|
+
* [Выбор вашей собственной "прослойки" сессии](#Выбор-вашей-собственной-прослойки-сессии)
|
45
89
|
* [Прерывание](#Прерывание)
|
46
90
|
* [Передача](#Передача)
|
47
91
|
* [Вызов другого маршрута](#Вызов-другого-маршрута)
|
48
|
-
* [
|
49
|
-
* [
|
92
|
+
* [Установка тела, статус кода и заголовков ответа](#Установка-тела-статус-кода-и-заголовков-ответа)
|
93
|
+
* [Потоковые ответы](#Потоковые-ответы)
|
50
94
|
* [Логирование](#Логирование)
|
51
95
|
* [Mime-типы](#mime-типы)
|
52
96
|
* [Генерирование URL](#Генерирование-url)
|
@@ -56,7 +100,7 @@
|
|
56
100
|
* [Доступ к объекту запроса](#Доступ-к-объекту-запроса)
|
57
101
|
* [Вложения](#Вложения)
|
58
102
|
* [Работа со временем и датами](#Работа-со-временем-и-датами)
|
59
|
-
* [Поиск шаблонов](
|
103
|
+
* [Поиск файлов шаблонов](#Поиск-файлов-шаблонов)
|
60
104
|
* [Конфигурация](#Конфигурация)
|
61
105
|
* [Настройка защиты от атак](#Настройка-защиты-от-атак)
|
62
106
|
* [Доступные настройки](#Доступные-настройки)
|
@@ -78,49 +122,13 @@
|
|
78
122
|
* [Область видимости запроса / экземпляра](#Область-видимости-запроса--экземпляра)
|
79
123
|
* [Область видимости делегирования](#Область-видимости-делегирования)
|
80
124
|
* [Командная строка](#Командная-строка)
|
81
|
-
* [
|
125
|
+
* [Многопоточность](#Многопоточность)
|
82
126
|
* [Системные требования](#Системные-требования)
|
83
|
-
* [
|
84
|
-
* [
|
85
|
-
* [Вручную](#Вручную)
|
86
|
-
* [Установка глобально](#Установка-глобально)
|
127
|
+
* [Самая свежая версия](#Самая-свежая-версия)
|
128
|
+
* [При помощи Bundler](#При-помощи-bundler)
|
87
129
|
* [Версии](#Версии)
|
88
130
|
* [Дальнейшее чтение](#Дальнейшее-чтение)
|
89
131
|
|
90
|
-
*Внимание: Этот документ является переводом английской версии и может быть
|
91
|
-
устаревшим*
|
92
|
-
|
93
|
-
Sinatra — это предметно-ориентированный каркас
|
94
|
-
([DSL](https://ru.wikipedia.org/wiki/Предметно-ориентированный_язык))
|
95
|
-
для быстрого создания функциональных веб-приложений на Ruby с минимумом усилий:
|
96
|
-
|
97
|
-
```ruby
|
98
|
-
# myapp.rb
|
99
|
-
require 'sinatra'
|
100
|
-
|
101
|
-
get '/' do
|
102
|
-
'Hello world!'
|
103
|
-
end
|
104
|
-
```
|
105
|
-
|
106
|
-
Установите gem:
|
107
|
-
|
108
|
-
```shell
|
109
|
-
gem install sinatra
|
110
|
-
```
|
111
|
-
|
112
|
-
и запустите приложение с помощью:
|
113
|
-
|
114
|
-
```shell
|
115
|
-
ruby myapp.rb
|
116
|
-
```
|
117
|
-
|
118
|
-
Оцените результат: [http://localhost:4567](http://localhost:4567)
|
119
|
-
|
120
|
-
Рекомендуется также установить Thin, сделать это можно командой: `gem install
|
121
|
-
thin`. Thin — это более производительный и функциональный сервер для
|
122
|
-
разработки приложений на Sinatra.
|
123
|
-
|
124
132
|
## Маршруты
|
125
133
|
|
126
134
|
В Sinatra маршрут — это пара: <HTTP метод> и <шаблон URL>. Каждый маршрут
|
@@ -152,38 +160,49 @@ options '/' do
|
|
152
160
|
end
|
153
161
|
|
154
162
|
link '/' do
|
155
|
-
.. что-то подключить ..
|
163
|
+
# .. что-то подключить ..
|
156
164
|
end
|
157
165
|
|
158
166
|
unlink '/' do
|
159
|
-
.. что-то отключить ..
|
167
|
+
# .. что-то отключить ..
|
160
168
|
end
|
161
169
|
```
|
162
170
|
|
163
|
-
Маршруты сверяются с запросом в порядке
|
171
|
+
Маршруты сверяются с запросом в порядке очерёдности их записи в файле
|
164
172
|
приложения. Первый же совпавший с запросом маршрут и будет вызван.
|
165
173
|
|
174
|
+
Маршруты с конечным слэшем отличаются от маршрутов без него:
|
175
|
+
|
176
|
+
```ruby
|
177
|
+
get '/foo' do
|
178
|
+
# не соответствует "GET /foo/"
|
179
|
+
end
|
180
|
+
```
|
181
|
+
|
166
182
|
Шаблоны маршрутов могут включать в себя именованные параметры, доступные в xэше
|
167
183
|
`params`:
|
168
184
|
|
169
185
|
```ruby
|
170
186
|
get '/hello/:name' do
|
171
187
|
# соответствует "GET /hello/foo" и "GET /hello/bar",
|
172
|
-
# где params['name'] 'foo' или 'bar'
|
188
|
+
# где params['name'] - это 'foo' или 'bar'
|
173
189
|
"Hello #{params['name']}!"
|
174
190
|
end
|
175
191
|
```
|
176
192
|
|
177
|
-
Также можно
|
193
|
+
Также можно получить доступ к именованным параметрам через параметры блока:
|
178
194
|
|
179
195
|
```ruby
|
180
196
|
get '/hello/:name' do |n|
|
197
|
+
# соответствует "GET /hello/foo" и "GET /hello/bar",
|
198
|
+
# где params['name'] - это 'foo' или 'bar'
|
199
|
+
# n хранит params['name']
|
181
200
|
"Hello #{n}!"
|
182
201
|
end
|
183
202
|
```
|
184
203
|
|
185
|
-
Шаблоны маршрутов также могут включать в себя splat (или '*' маску,
|
186
|
-
обозначающую любой символ)
|
204
|
+
Шаблоны маршрутов также могут включать в себя splat параметры (или '*' маску,
|
205
|
+
обозначающую любой символ), доступные в массиве `params['splat']`:
|
187
206
|
|
188
207
|
```ruby
|
189
208
|
get '/say/*/to/*' do
|
@@ -205,10 +224,10 @@ get '/download/*.*' do |path, ext|
|
|
205
224
|
end
|
206
225
|
```
|
207
226
|
|
208
|
-
|
227
|
+
Можно также использовать регулярные выражения в качестве шаблонов маршрутов:
|
209
228
|
|
210
229
|
```ruby
|
211
|
-
get
|
230
|
+
get /\/hello\/([\w]+)/ do
|
212
231
|
"Hello, #{params['captures'].first}!"
|
213
232
|
end
|
214
233
|
```
|
@@ -216,7 +235,7 @@ end
|
|
216
235
|
Или с параметром блока:
|
217
236
|
|
218
237
|
```ruby
|
219
|
-
#
|
238
|
+
# Соответствует "GET /meta/hello/world", "GET /hello/world/1234" и т.д.
|
220
239
|
get %r{/hello/([\w]+)} do |c|
|
221
240
|
"Hello, #{c}!"
|
222
241
|
end
|
@@ -230,14 +249,37 @@ get '/posts/:format?' do
|
|
230
249
|
end
|
231
250
|
```
|
232
251
|
|
233
|
-
|
234
|
-
|
235
|
-
|
252
|
+
Маршруты также могут использовать параметры запроса:
|
253
|
+
|
254
|
+
```ruby
|
255
|
+
get '/posts' do
|
256
|
+
# соответствует "GET /posts?title=foo&author=bar"
|
257
|
+
title = params['title']
|
258
|
+
author = params['author']
|
259
|
+
# используются переменные title и author; запрос не обязателен для маршрута /posts
|
260
|
+
end
|
261
|
+
```
|
262
|
+
|
263
|
+
**Имеейте ввиду**: если вы не отключите защиту от обратного пути в директориях
|
264
|
+
(_path traversal_, см. ниже), путь запроса может быть изменён до начала
|
265
|
+
поиска подходящего маршрута.
|
266
|
+
|
267
|
+
Вы можете настроить Mustermann опции, используемые для данного маршрута, путём передачи в `:mustermann_opts` хэш:
|
268
|
+
|
269
|
+
```ruby
|
270
|
+
get '\A/posts\z', :mustermann_opts => { :type => :regexp, :check_anchors => false } do
|
271
|
+
# в точности соответствует /posts, с явной привязкой
|
272
|
+
"If you match an anchored pattern clap your hands!"
|
273
|
+
end
|
274
|
+
```
|
275
|
+
|
276
|
+
Это похоже на [условие](#Условия), но это не так! Эти опции будут объеденины в глобальный `:mustermann_opts` хэш, описанный
|
277
|
+
[ниже](#Доступные-настройки).
|
236
278
|
|
237
279
|
### Условия
|
238
280
|
|
239
|
-
Маршруты могут включать различные условия совпадений, например,
|
240
|
-
|
281
|
+
Маршруты могут включать в себя различные условия совпадений, такие как, например,
|
282
|
+
строка агента пользователя (user agent):
|
241
283
|
|
242
284
|
```ruby
|
243
285
|
get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
|
@@ -265,7 +307,9 @@ get '/', :provides => ['rss', 'atom', 'xml'] do
|
|
265
307
|
end
|
266
308
|
```
|
267
309
|
|
268
|
-
|
310
|
+
`provides` ищет заголовок запроса `Accept`.
|
311
|
+
|
312
|
+
Вы можете с лёгкостью задавать собственные условия:
|
269
313
|
|
270
314
|
```ruby
|
271
315
|
set(:probability) { |value| condition { rand <= value } }
|
@@ -279,10 +323,10 @@ get '/win_a_car' do
|
|
279
323
|
end
|
280
324
|
```
|
281
325
|
|
282
|
-
|
326
|
+
Ипользуйте splat-оператор (`*`) для условий, которые принимают несколько аргументов:
|
283
327
|
|
284
328
|
```ruby
|
285
|
-
set(:auth) do |*roles| # <- обратите внимание на
|
329
|
+
set(:auth) do |*roles| # <- обратите внимание на звёздочку
|
286
330
|
condition do
|
287
331
|
unless logged_in? && roles.any? {|role| current_user.in_role? role }
|
288
332
|
redirect "/login/", 303
|
@@ -302,23 +346,22 @@ end
|
|
302
346
|
### Возвращаемые значения
|
303
347
|
|
304
348
|
Возвращаемое значение блока маршрута ограничивается телом ответа, которое
|
305
|
-
будет передано HTTP клиенту,
|
306
|
-
стеке. Чаще всего это
|
349
|
+
будет передано HTTP клиенту, или, по крайней мере, следующей "прослойке" (middleware)
|
350
|
+
в Rack стеке. Чаще всего это строка как в примерах выше. Но также приемлемы и
|
307
351
|
другие значения.
|
308
352
|
|
309
353
|
Вы можете вернуть любой объект, который будет либо корректным Rack ответом,
|
310
|
-
объектом Rack body, либо кодом состояния HTTP:
|
354
|
+
либо объектом Rack body, либо кодом состояния HTTP:
|
311
355
|
|
312
|
-
* массив с тремя переменными: `[код (
|
356
|
+
* массив с тремя переменными: `[код (Integer), заголовки (Hash), тело ответа
|
313
357
|
(должно отвечать на #each)]`;
|
314
|
-
* массив с двумя переменными: `[код (
|
358
|
+
* массив с двумя переменными: `[код (Integer), тело ответа (должно отвечать
|
315
359
|
на #each)]`;
|
316
360
|
* объект, отвечающий на `#each`, который передает только строковые типы
|
317
361
|
данных в этот блок;
|
318
|
-
*
|
362
|
+
* Integer, представляющий код состояния HTTP.
|
319
363
|
|
320
|
-
|
321
|
-
Таким образом, легко можно реализовать, например, поточный пример:
|
364
|
+
Таким образом легко можно реализовать, например, потоковую передачу:
|
322
365
|
|
323
366
|
```ruby
|
324
367
|
class Stream
|
@@ -330,14 +373,14 @@ end
|
|
330
373
|
get('/') { Stream.new }
|
331
374
|
```
|
332
375
|
|
333
|
-
Вы также можете использовать метод `stream` (
|
334
|
-
уменьшить количество
|
335
|
-
|
376
|
+
Вы также можете использовать вспомогательный метод `stream` (описанный ниже)
|
377
|
+
для того, чтобы уменьшить количество шаблонного кода и встроить потоковую
|
378
|
+
логику прямо в маршрут.
|
336
379
|
|
337
380
|
### Собственные детекторы совпадений для маршрутов
|
338
381
|
|
339
382
|
Как показано выше, Sinatra поставляется со встроенной поддержкой строк и
|
340
|
-
регулярных выражений в качестве шаблонов URL. Но и это
|
383
|
+
регулярных выражений в качестве шаблонов URL. Но и это ещё не всё. Вы можете
|
341
384
|
легко определить свои собственные детекторы совпадений (matchers) для
|
342
385
|
маршрутов:
|
343
386
|
|
@@ -364,8 +407,8 @@ get all_but("/index") do
|
|
364
407
|
end
|
365
408
|
```
|
366
409
|
|
367
|
-
|
368
|
-
может быть реализован
|
410
|
+
Обратите внимание на то, что предыдущий пример, возможно, чересчур усложнён, потому что он
|
411
|
+
может быть реализован следующим образом:
|
369
412
|
|
370
413
|
```ruby
|
371
414
|
get // do
|
@@ -374,29 +417,29 @@ get // do
|
|
374
417
|
end
|
375
418
|
```
|
376
419
|
|
377
|
-
Или с использованием
|
420
|
+
Или с использованием негативной опережающей проверки (отрицательное look-ahead условие):
|
378
421
|
|
379
422
|
```ruby
|
380
|
-
get %r{
|
423
|
+
get %r{(?!/index)} do
|
381
424
|
# ...
|
382
425
|
end
|
383
426
|
```
|
384
427
|
|
385
428
|
## Статические файлы
|
386
429
|
|
387
|
-
Статические файлы
|
388
|
-
|
430
|
+
Статические файлы раздаются из `./public` директории. Вы можете указать другое
|
431
|
+
месторасположение при помощи опции `:public_folder`:
|
389
432
|
|
390
433
|
```ruby
|
391
|
-
set :public_folder,
|
434
|
+
set :public_folder, __dir__ + '/static'
|
392
435
|
```
|
393
436
|
|
394
437
|
Учтите, что имя директории со статическими файлами не включено в URL.
|
395
438
|
Например, файл `./public/css/style.css` будет доступен как
|
396
439
|
`http://example.com/css/style.css`.
|
397
440
|
|
398
|
-
Используйте опцию `:static_cache_control` (см. ниже)
|
399
|
-
`Cache-Control`.
|
441
|
+
Используйте опцию `:static_cache_control` (см. ниже) для того, чтобы добавить
|
442
|
+
заголовок `Cache-Control`.
|
400
443
|
|
401
444
|
## Представления / Шаблоны
|
402
445
|
|
@@ -409,7 +452,7 @@ get '/' do
|
|
409
452
|
end
|
410
453
|
```
|
411
454
|
|
412
|
-
|
455
|
+
Данный код отрендерит файл `views/index.erb`.
|
413
456
|
|
414
457
|
Вместо имени шаблона вы так же можете передавать непосредственно само
|
415
458
|
содержимое шаблона:
|
@@ -421,7 +464,7 @@ get '/' do
|
|
421
464
|
end
|
422
465
|
```
|
423
466
|
|
424
|
-
|
467
|
+
Метод рендеринга шаблона принимает в качестве второго аргумента хэш с опциями:
|
425
468
|
|
426
469
|
```ruby
|
427
470
|
get '/' do
|
@@ -429,10 +472,10 @@ get '/' do
|
|
429
472
|
end
|
430
473
|
```
|
431
474
|
|
432
|
-
|
433
|
-
`views/layout.erb`, если существует).
|
475
|
+
Данный метод отрендерит шаблон `views/index.erb`, который будет вложен в `views/post.erb`
|
476
|
+
(по умолчанию: `views/layout.erb`, если файл существует).
|
434
477
|
|
435
|
-
Любые опции, не
|
478
|
+
Любые опции, которые Sinatra не распознает, будут переданы в шаблонизатор:
|
436
479
|
|
437
480
|
```ruby
|
438
481
|
get '/' do
|
@@ -440,7 +483,7 @@ get '/' do
|
|
440
483
|
end
|
441
484
|
```
|
442
485
|
|
443
|
-
Вы также можете задавать опции для
|
486
|
+
Вы также можете глобально задавать опции для шаблонизаторов:
|
444
487
|
|
445
488
|
```ruby
|
446
489
|
set :haml, :format => :html5
|
@@ -450,7 +493,7 @@ get '/' do
|
|
450
493
|
end
|
451
494
|
```
|
452
495
|
|
453
|
-
Опции, переданные в метод, переопределяют опции, заданные
|
496
|
+
Опции, переданные в метод, переопределяют опции, заданные при помощи `set`.
|
454
497
|
|
455
498
|
Доступные опции:
|
456
499
|
|
@@ -458,13 +501,13 @@ end
|
|
458
501
|
<dt>locals</dt>
|
459
502
|
<dd>
|
460
503
|
Список локальных переменных, передаваемых в документ.
|
461
|
-
|
504
|
+
Пример: <tt>erb "<%= foo %>", :locals => {:foo => "bar"}</tt>
|
462
505
|
</dd>
|
463
506
|
|
464
507
|
<dt>default_encoding</dt>
|
465
508
|
<dd>
|
466
|
-
Кодировка, которую следует
|
467
|
-
оригинальную. По умолчанию: <tt>settings.default_encoding</tt>.
|
509
|
+
Кодировка, которую следует использовать в том случае, если не удалось
|
510
|
+
определить оригинальную. По умолчанию: <tt>settings.default_encoding</tt>.
|
468
511
|
</dd>
|
469
512
|
|
470
513
|
<dt>views</dt>
|
@@ -474,14 +517,15 @@ end
|
|
474
517
|
|
475
518
|
<dt>layout</dt>
|
476
519
|
<dd>
|
477
|
-
|
478
|
-
|
479
|
-
|
520
|
+
Определяет необходимость использования лэйаута (<tt>true</tt> или <tt>false</tt>).
|
521
|
+
Если же в качестве значения передан символ, то его значение будет интерпретировано
|
522
|
+
как наименования файла шаблона лэйаута.
|
523
|
+
Пример: <tt>erb :index, :layout => !request.xhr?</tt>
|
480
524
|
</dd>
|
481
525
|
|
482
526
|
<dt>content_type</dt>
|
483
527
|
<dd>
|
484
|
-
Content-Type отображенного шаблона. По умолчанию:
|
528
|
+
Content-Type отображенного шаблона. По умолчанию: задаётся шаблонизатором.
|
485
529
|
</dd>
|
486
530
|
|
487
531
|
<dt>scope</dt>
|
@@ -494,23 +538,30 @@ end
|
|
494
538
|
<dt>layout_engine</dt>
|
495
539
|
<dd>
|
496
540
|
Шаблонизатор, который следует использовать для отображения лэйаута.
|
497
|
-
Полезная опция для шаблонизаторов, в которых
|
541
|
+
Полезная опция для шаблонизаторов, в которых отсутствует поддержка
|
498
542
|
лэйаутов. По умолчанию: тот же шаблонизатор, что используется и для самого
|
499
543
|
шаблона. Пример: <tt>set :rdoc, :layout_engine => :erb</tt>
|
500
544
|
</dd>
|
545
|
+
|
546
|
+
<dt>layout_options</dt>
|
547
|
+
<dd>
|
548
|
+
Специальные опции, используемые только для рендеринга лэйаута. Пример:
|
549
|
+
<tt>set :rdoc, :layout_options => { :views => 'views/layouts' }</tt>
|
550
|
+
</dd>
|
501
551
|
</dl>
|
502
552
|
|
503
|
-
По умолчанию
|
504
|
-
|
553
|
+
По умолчанию в качестве пути для хранения шаблонов принята директория `./views`.
|
554
|
+
Чтобы назначить другую директорию с шаблонами необходимо изменить настройки:
|
505
555
|
|
506
556
|
```ruby
|
507
557
|
set :views, settings.root + '/templates'
|
508
558
|
```
|
509
559
|
|
510
|
-
Важное замечание: вы всегда должны ссылаться на шаблоны
|
511
|
-
(Symbol), даже когда они в поддиректории (в этом случае
|
512
|
-
`:'subdir/template'`). Вы должны использовать
|
513
|
-
|
560
|
+
Важное замечание: вы всегда должны ссылаться на шаблоны при помощи символов
|
561
|
+
(Symbol), даже тогда, когда они расположены в поддиректории (в этом случае
|
562
|
+
используйте конструкции вида `:'subdir/template'`). Вы должны использовать
|
563
|
+
символы в связи с тем, что в ином случае шаблонизаторы попросту отображают
|
564
|
+
любые строки, переданные им.
|
514
565
|
|
515
566
|
### Буквальные шаблоны
|
516
567
|
|
@@ -520,12 +571,22 @@ get '/' do
|
|
520
571
|
end
|
521
572
|
```
|
522
573
|
|
523
|
-
Отобразит шаблон,
|
574
|
+
Отобразит шаблон, содержимое которого передано строкой. Опционально можно
|
575
|
+
указать дополнительные опции `:path` и `:line` для того, чтобы улучшить бэктрейс.
|
576
|
+
Делайте это в том случае, если строка определена в некотором файле, к которому
|
577
|
+
можно указать путь и номер строки, где расположена исходная строка:
|
578
|
+
|
579
|
+
```ruby
|
580
|
+
get '/' do
|
581
|
+
haml '%div.title Hello World', :path => 'examples/file.haml', :line => 3
|
582
|
+
end
|
583
|
+
```
|
524
584
|
|
525
585
|
### Доступные шаблонизаторы
|
526
586
|
|
527
|
-
Некоторые языки шаблонов имеют несколько реализаций.
|
528
|
-
|
587
|
+
Некоторые языки шаблонов имеют несколько реализаций. Для того, чтобы указать
|
588
|
+
конкретную реализацию, которую вы хотите использовать, вам следует просто
|
589
|
+
подключить нужную библиотеку:
|
529
590
|
|
530
591
|
```ruby
|
531
592
|
require 'rdiscount' # или require 'bluecloth'
|
@@ -556,7 +617,7 @@ get('/') { markdown :index }
|
|
556
617
|
<td>Зависимости</td>
|
557
618
|
<td>
|
558
619
|
<a href="http://www.kuwata-lab.com/erubis/" title="erubis">erubis</a>
|
559
|
-
или erb (
|
620
|
+
или erb (включён в Ruby)
|
560
621
|
</td>
|
561
622
|
</tr>
|
562
623
|
<tr>
|
@@ -588,7 +649,7 @@ get('/') { markdown :index }
|
|
588
649
|
</tr>
|
589
650
|
</table>
|
590
651
|
|
591
|
-
|
652
|
+
Шаблонизатор также принимает блоки для включённых шаблонов ([см. пример](#Включённые-шаблоны)).
|
592
653
|
|
593
654
|
#### Nokogiri шаблоны
|
594
655
|
|
@@ -607,14 +668,14 @@ get('/') { markdown :index }
|
|
607
668
|
</tr>
|
608
669
|
</table>
|
609
670
|
|
610
|
-
|
671
|
+
Шаблонизатор также принимает блоки для включённых шаблонов ([см. пример](#Включённые-шаблоны)).
|
611
672
|
|
612
673
|
#### Sass шаблоны
|
613
674
|
|
614
675
|
<table>
|
615
676
|
<tr>
|
616
677
|
<td>Зависимости</td>
|
617
|
-
<td><a href="
|
678
|
+
<td><a href="https://sass-lang.com/" title="sass">sass</a></td>
|
618
679
|
</tr>
|
619
680
|
<tr>
|
620
681
|
<td>Расширения файлов</td>
|
@@ -631,7 +692,7 @@ get('/') { markdown :index }
|
|
631
692
|
<table>
|
632
693
|
<tr>
|
633
694
|
<td>Зависимости</td>
|
634
|
-
<td><a href="
|
695
|
+
<td><a href="https://sass-lang.com/" title="sass">sass</a></td>
|
635
696
|
</tr>
|
636
697
|
<tr>
|
637
698
|
<td>Расширения файлов</td>
|
@@ -665,7 +726,7 @@ get('/') { markdown :index }
|
|
665
726
|
<table>
|
666
727
|
<tr>
|
667
728
|
<td>Зависимости</td>
|
668
|
-
<td><a href="
|
729
|
+
<td><a href="https://shopify.github.io/liquid/" title="liquid">liquid</a></td>
|
669
730
|
</tr>
|
670
731
|
<tr>
|
671
732
|
<td>Расширения файлов</td>
|
@@ -677,8 +738,9 @@ get('/') { markdown :index }
|
|
677
738
|
</tr>
|
678
739
|
</table>
|
679
740
|
|
680
|
-
|
681
|
-
|
741
|
+
В связи с тем, что в Liquid шаблонах невозможно вызывать методы из Ruby
|
742
|
+
(за исключением `yield`), вам почти всегда понадобиться передавать в шаблон
|
743
|
+
локальные переменные.
|
682
744
|
|
683
745
|
#### Markdown шаблоны
|
684
746
|
|
@@ -689,8 +751,8 @@ get('/') { markdown :index }
|
|
689
751
|
Любая из библиотек:
|
690
752
|
<a href="https://github.com/davidfstr/rdiscount" title="RDiscount">RDiscount</a>,
|
691
753
|
<a href="https://github.com/vmg/redcarpet" title="RedCarpet">RedCarpet</a>,
|
692
|
-
<a href="
|
693
|
-
<a href="
|
754
|
+
<a href="https://github.com/ged/bluecloth" title="bluecloth">BlueCloth</a>,
|
755
|
+
<a href="https://kramdown.gettalong.org/" title="kramdown">kramdown</a>,
|
694
756
|
<a href="https://github.com/bhollis/maruku" title="maruku">maruku</a>
|
695
757
|
</td>
|
696
758
|
</tr>
|
@@ -705,23 +767,23 @@ get('/') { markdown :index }
|
|
705
767
|
</table>
|
706
768
|
|
707
769
|
В Markdown невозможно вызывать методы или передавать локальные переменные.
|
708
|
-
|
770
|
+
По этой причине вам, скорее всего, придётся использовать этот шаблон совместно
|
709
771
|
с другим шаблонизатором:
|
710
772
|
|
711
773
|
```ruby
|
712
774
|
erb :overview, :locals => { :text => markdown(:introduction) }
|
713
775
|
```
|
714
776
|
|
715
|
-
|
777
|
+
Обратите внимание на то, что вы можете вызывать метод `markdown` из других шаблонов:
|
716
778
|
|
717
779
|
```ruby
|
718
780
|
%h1 Hello From Haml!
|
719
781
|
%p= markdown(:greetings)
|
720
782
|
```
|
721
783
|
|
722
|
-
Вы не можете вызывать Ruby из Markdown,
|
723
|
-
использовать лэйауты на Markdown. Тем не менее,
|
724
|
-
один шаблонизатор для отображения шаблона, а другой для лэйаута
|
784
|
+
Вы не можете вызывать Ruby код код из Markdown, соответственно вы не можете
|
785
|
+
использовать лэйауты на Markdown. Тем не менее, существует возможность использовать
|
786
|
+
один шаблонизатор для отображения шаблона, а другой для лэйаута при помощи
|
725
787
|
опции `:layout_engine`.
|
726
788
|
|
727
789
|
#### Textile шаблоны
|
@@ -742,23 +804,23 @@ erb :overview, :locals => { :text => markdown(:introduction) }
|
|
742
804
|
</table>
|
743
805
|
|
744
806
|
В Textile невозможно вызывать методы или передавать локальные переменные.
|
745
|
-
Следовательно, вам, скорее всего,
|
746
|
-
с другим шаблонизатором:
|
807
|
+
Следовательно, вам, скорее всего, придётся использовать данный шаблон
|
808
|
+
совместно с другим шаблонизатором:
|
747
809
|
|
748
810
|
```ruby
|
749
811
|
erb :overview, :locals => { :text => textile(:introduction) }
|
750
812
|
```
|
751
813
|
|
752
|
-
|
814
|
+
Обратите внимание на то, что вы можете вызывать метод `textile` из других шаблонов:
|
753
815
|
|
754
816
|
```ruby
|
755
817
|
%h1 Hello From Haml!
|
756
818
|
%p= textile(:greetings)
|
757
819
|
```
|
758
820
|
|
759
|
-
Вы не можете вызывать Ruby из Textile,
|
760
|
-
использовать лэйауты на Textile. Тем не менее,
|
761
|
-
один шаблонизатор для отображения шаблона, а другой для лэйаута
|
821
|
+
Вы не можете вызывать Ruby код код из Textile, соответственно вы не можете
|
822
|
+
использовать лэйауты на Textile. Тем не менее, существует возможность использовать
|
823
|
+
один шаблонизатор для отображения шаблона, а другой для лэйаута при помощи
|
762
824
|
опции `:layout_engine`.
|
763
825
|
|
764
826
|
#### RDoc шаблоны
|
@@ -779,23 +841,23 @@ erb :overview, :locals => { :text => textile(:introduction) }
|
|
779
841
|
</table>
|
780
842
|
|
781
843
|
В RDoc невозможно вызывать методы или передавать локальные переменные.
|
782
|
-
Следовательно, вам, скорее всего,
|
844
|
+
Следовательно, вам, скорее всего, придётся использовать этот шаблон совместно
|
783
845
|
с другим шаблонизатором:
|
784
846
|
|
785
847
|
```ruby
|
786
848
|
erb :overview, :locals => { :text => rdoc(:introduction) }
|
787
849
|
```
|
788
850
|
|
789
|
-
|
851
|
+
Обратите внимание на то, что вы можете вызывать метод `rdoc` из других шаблонов:
|
790
852
|
|
791
853
|
```ruby
|
792
854
|
%h1 Hello From Haml!
|
793
855
|
%p= rdoc(:greetings)
|
794
856
|
```
|
795
857
|
|
796
|
-
Вы не можете вызывать Ruby из RDoc,
|
797
|
-
лэйауты на RDoc. Тем не менее,
|
798
|
-
для отображения шаблона, а другой для лэйаута
|
858
|
+
Вы не можете вызывать Ruby код код из RDoc, соответственно вы не можете использовать
|
859
|
+
лэйауты на RDoc. Тем не менее, существует возможность использовать один шаблонизатор
|
860
|
+
для отображения шаблона, а другой для лэйаута при помощи опции
|
799
861
|
`:layout_engine`.
|
800
862
|
|
801
863
|
#### AsciiDoc шаблоны
|
@@ -843,7 +905,7 @@ erb :overview, :locals => { :text => rdoc(:introduction) }
|
|
843
905
|
<table>
|
844
906
|
<tr>
|
845
907
|
<td>Зависимости</td>
|
846
|
-
<td><a href="
|
908
|
+
<td><a href="https://markaby.github.io/" title="Markaby">Markaby</a></td>
|
847
909
|
</tr>
|
848
910
|
<tr>
|
849
911
|
<td>Расширения файлов</td>
|
@@ -855,7 +917,7 @@ erb :overview, :locals => { :text => rdoc(:introduction) }
|
|
855
917
|
</tr>
|
856
918
|
</table>
|
857
919
|
|
858
|
-
|
920
|
+
Шаблонизатор также принимает блоки для включённых шаблонов ([см. пример](#Включённые-шаблоны)).
|
859
921
|
|
860
922
|
#### RABL шаблоны
|
861
923
|
|
@@ -909,23 +971,23 @@ erb :overview, :locals => { :text => rdoc(:introduction) }
|
|
909
971
|
</table>
|
910
972
|
|
911
973
|
В Creole невозможно вызывать методы или передавать локальные переменные.
|
912
|
-
Следовательно, вам, скорее всего,
|
974
|
+
Следовательно, вам, скорее всего, придётся использовать данный шаблон совместно
|
913
975
|
с другим шаблонизатором:
|
914
976
|
|
915
977
|
```ruby
|
916
978
|
erb :overview, :locals => { :text => creole(:introduction) }
|
917
979
|
```
|
918
980
|
|
919
|
-
|
981
|
+
обратите внимание на то, что вы можете вызывать метод `creole` из других шаблонов:
|
920
982
|
|
921
983
|
```ruby
|
922
984
|
%h1 Hello From Haml!
|
923
985
|
%p= creole(:greetings)
|
924
986
|
```
|
925
987
|
|
926
|
-
Вы не можете вызывать Ruby из Creole,
|
927
|
-
использовать лэйауты на Creole. Тем не менее,
|
928
|
-
один шаблонизатор для отображения шаблона, а другой для лэйаута
|
988
|
+
Вы не можете вызывать Ruby код из Creole, соответственно вы не можете
|
989
|
+
использовать лэйауты на Creole. Тем не менее, существует возможность использовать
|
990
|
+
один шаблонизатор для отображения шаблона, а другой для лэйаута при помощи
|
929
991
|
опции `:layout_engine`.
|
930
992
|
|
931
993
|
#### MediaWiki шаблоны
|
@@ -946,23 +1008,23 @@ erb :overview, :locals => { :text => creole(:introduction) }
|
|
946
1008
|
</table>
|
947
1009
|
|
948
1010
|
В разметке MediaWiki невозможно вызывать методы или передавать локальные переменные.
|
949
|
-
Следовательно, вам, скорее всего,
|
1011
|
+
Следовательно, вам, скорее всего, придётся использовать этот шаблон совместно
|
950
1012
|
с другим шаблонизатором:
|
951
1013
|
|
952
1014
|
```ruby
|
953
1015
|
erb :overview, :locals => { :text => mediawiki(:introduction) }
|
954
1016
|
```
|
955
1017
|
|
956
|
-
|
1018
|
+
Обратите внимание на то, что вы можете вызывать метод `mediawiki` из других шаблонов:
|
957
1019
|
|
958
1020
|
```ruby
|
959
1021
|
%h1 Hello From Haml!
|
960
1022
|
%p= mediawiki(:greetings)
|
961
1023
|
```
|
962
1024
|
|
963
|
-
Вы не можете вызывать Ruby из MediaWiki,
|
964
|
-
использовать лэйауты на MediaWiki. Тем не менее,
|
965
|
-
один шаблонизатор для отображения шаблона, а другой для лэйаута
|
1025
|
+
Вы не можете вызывать Ruby код из MediaWiki, соответственно вы не можете
|
1026
|
+
использовать лэйауты на MediaWiki. Тем не менее, существует возможность использовать
|
1027
|
+
один шаблонизатор для отображения шаблона, а другой для лэйаута при помощи
|
966
1028
|
опции `:layout_engine`.
|
967
1029
|
|
968
1030
|
#### CoffeeScript шаблоны
|
@@ -974,7 +1036,7 @@ erb :overview, :locals => { :text => mediawiki(:introduction) }
|
|
974
1036
|
<a href="https://github.com/josh/ruby-coffee-script" title="Ruby CoffeeScript">
|
975
1037
|
CoffeeScript
|
976
1038
|
</a> и
|
977
|
-
<a href="https://github.com/sstephenson/execjs
|
1039
|
+
<a href="https://github.com/sstephenson/execjs" title="ExecJS">
|
978
1040
|
способ запускать JavaScript
|
979
1041
|
</a>
|
980
1042
|
</td>
|
@@ -998,7 +1060,7 @@ erb :overview, :locals => { :text => mediawiki(:introduction) }
|
|
998
1060
|
<a href="https://github.com/forgecrafted/ruby-stylus" title="Ruby Stylus">
|
999
1061
|
Stylus
|
1000
1062
|
</a> и
|
1001
|
-
<a href="https://github.com/sstephenson/execjs
|
1063
|
+
<a href="https://github.com/sstephenson/execjs" title="ExecJS">
|
1002
1064
|
способ запускать JavaScript
|
1003
1065
|
</a>
|
1004
1066
|
</td>
|
@@ -1013,8 +1075,8 @@ erb :overview, :locals => { :text => mediawiki(:introduction) }
|
|
1013
1075
|
</tr>
|
1014
1076
|
</table>
|
1015
1077
|
|
1016
|
-
Перед тем, как использовать шаблоны
|
1017
|
-
`stylus/tilt`:
|
1078
|
+
Перед тем, как использовать шаблоны Stylus, необходимо сперва подключить
|
1079
|
+
`stylus` и `stylus/tilt`:
|
1018
1080
|
|
1019
1081
|
```ruby
|
1020
1082
|
require 'sinatra'
|
@@ -1051,7 +1113,7 @@ end
|
|
1051
1113
|
</table>
|
1052
1114
|
|
1053
1115
|
Содержимое шаблона интерпретируется как код на Ruby, а результирующая
|
1054
|
-
переменная json затем конвертируется
|
1116
|
+
переменная json затем конвертируется при помощи `#to_json`.
|
1055
1117
|
|
1056
1118
|
```ruby
|
1057
1119
|
json = { :foo => 'bar' }
|
@@ -1059,10 +1121,11 @@ json[:baz] = key
|
|
1059
1121
|
```
|
1060
1122
|
|
1061
1123
|
Опции `:callback` и `:variable` используются для "декорирования" итогового
|
1062
|
-
|
1124
|
+
объекта:
|
1063
1125
|
|
1064
1126
|
```ruby
|
1065
|
-
var resource = {"foo":"bar","baz":"qux"};
|
1127
|
+
var resource = {"foo":"bar","baz":"qux"};
|
1128
|
+
present(resource);
|
1066
1129
|
```
|
1067
1130
|
|
1068
1131
|
#### WLang шаблоны
|
@@ -1070,7 +1133,7 @@ var resource = {"foo":"bar","baz":"qux"}; present(resource);
|
|
1070
1133
|
<table>
|
1071
1134
|
<tr>
|
1072
1135
|
<td>Зависимости</td>
|
1073
|
-
<td><a href="https://github.com/blambeau/wlang
|
1136
|
+
<td><a href="https://github.com/blambeau/wlang" title="WLang">WLang</a></td>
|
1074
1137
|
</tr>
|
1075
1138
|
<tr>
|
1076
1139
|
<td>Расширения файлов</td>
|
@@ -1084,7 +1147,7 @@ var resource = {"foo":"bar","baz":"qux"}; present(resource);
|
|
1084
1147
|
|
1085
1148
|
Так как в WLang шаблонах невозможно вызывать методы из Ruby напрямую (за
|
1086
1149
|
исключением `yield`), то вы почти всегда будете передавать в шаблон локальные
|
1087
|
-
переменные.
|
1150
|
+
переменные. Лэйауты также могут быть описаны при помощи WLang.
|
1088
1151
|
|
1089
1152
|
### Доступ к переменным в шаблонах
|
1090
1153
|
|
@@ -1099,7 +1162,7 @@ get '/:id' do
|
|
1099
1162
|
end
|
1100
1163
|
```
|
1101
1164
|
|
1102
|
-
|
1165
|
+
Вы также можете установить их при помощи хэша локальных переменных:
|
1103
1166
|
|
1104
1167
|
```ruby
|
1105
1168
|
get '/:id' do
|
@@ -1108,46 +1171,44 @@ get '/:id' do
|
|
1108
1171
|
end
|
1109
1172
|
```
|
1110
1173
|
|
1111
|
-
Это обычный подход, когда шаблоны рендерятся как части других шаблонов.
|
1174
|
+
Это обычный подход, применяемый тогда, когда шаблоны рендерятся как части других шаблонов.
|
1112
1175
|
|
1113
|
-
### Шаблоны с `yield` и вложенные
|
1176
|
+
### Шаблоны с `yield` и вложенные лэйауты
|
1114
1177
|
|
1115
|
-
|
1116
|
-
`yield`.
|
1117
|
-
|
1118
|
-
как описано выше, либо он может быть дополнен блоком:
|
1178
|
+
Лэйаут (layout) обычно представляет собой шаблон, который исполняет
|
1179
|
+
`yield`. Такой шаблон может быть использован либо при помощи опции `:template`,
|
1180
|
+
как описано выше, либо при помощи блока:
|
1119
1181
|
|
1120
1182
|
```ruby
|
1121
|
-
|
1122
|
-
|
1123
|
-
|
1183
|
+
erb :post, :layout => false do
|
1184
|
+
erb :index
|
1185
|
+
end
|
1124
1186
|
```
|
1125
1187
|
|
1126
|
-
Эти инструкции
|
1188
|
+
Эти инструкции по сути эквивалентны `erb :index, :layout => :post`.
|
1127
1189
|
|
1128
1190
|
Передача блоков интерпретирующим шаблоны методам наиболее полезна для
|
1129
|
-
создания вложенных
|
1191
|
+
создания вложенных лэйаутов:
|
1130
1192
|
|
1131
1193
|
```ruby
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1194
|
+
erb :main_layout, :layout => false do
|
1195
|
+
erb :admin_layout do
|
1196
|
+
erb :user
|
1197
|
+
end
|
1198
|
+
end
|
1137
1199
|
```
|
1138
1200
|
|
1139
|
-
|
1201
|
+
То же самое может быть сделано в более короткой форме:
|
1140
1202
|
|
1141
1203
|
```ruby
|
1142
|
-
|
1143
|
-
|
1144
|
-
|
1204
|
+
erb :admin_layout, :layout => :main_layout do
|
1205
|
+
erb :user
|
1206
|
+
end
|
1145
1207
|
```
|
1146
1208
|
|
1147
|
-
В настоящее
|
1148
|
-
принимают блок:
|
1149
|
-
|
1150
|
-
Общий метод заполнения шаблонов `render` также принимает блок.
|
1209
|
+
В настоящее время следующие методы шаблонизаторов
|
1210
|
+
принимают блок: `erb`, `haml`, `liquid`, `slim `, `wlang`. Кроме того,
|
1211
|
+
общий метод построения шаблонов `render` также принимает блок.
|
1151
1212
|
|
1152
1213
|
### Включённые шаблоны
|
1153
1214
|
|
@@ -1170,13 +1231,13 @@ __END__
|
|
1170
1231
|
%div.title Hello world.
|
1171
1232
|
```
|
1172
1233
|
|
1173
|
-
|
1234
|
+
Обратите внимание: включённые шаблоны, определённые в исходном файле, который подключил
|
1174
1235
|
Sinatra, будут загружены автоматически. Вызовите `enable :inline_templates`
|
1175
|
-
|
1236
|
+
напрямую в том случае, если используете включённые шаблоны в других файлах.
|
1176
1237
|
|
1177
1238
|
### Именованные шаблоны
|
1178
1239
|
|
1179
|
-
Шаблоны также могут быть определены при помощи `template
|
1240
|
+
Шаблоны также могут быть определены при помощи метода `template`:
|
1180
1241
|
|
1181
1242
|
```ruby
|
1182
1243
|
template :layout do
|
@@ -1193,8 +1254,8 @@ end
|
|
1193
1254
|
```
|
1194
1255
|
|
1195
1256
|
Если шаблон с именем "layout" существует, то он будет использоваться каждый
|
1196
|
-
раз при рендеринге. Вы можете отключать лэйаут в каждом конкретном случае
|
1197
|
-
|
1257
|
+
раз при рендеринге. Вы можете отключать лэйаут в каждом конкретном случае при
|
1258
|
+
помощи опции `:layout => false` или отключить его для всего приложения: `set :haml,
|
1198
1259
|
:layout => false`:
|
1199
1260
|
|
1200
1261
|
```ruby
|
@@ -1205,9 +1266,9 @@ end
|
|
1205
1266
|
|
1206
1267
|
### Привязка файловых расширений
|
1207
1268
|
|
1208
|
-
|
1209
|
-
`Tilt.register`.
|
1210
|
-
шаблонов Textile:
|
1269
|
+
Для того, чтобы связать расширение файла с движком рендеринга, используйте
|
1270
|
+
`Tilt.register`. Так, например, вызовите следующий код в том случае, если вы
|
1271
|
+
хотите использовать расширение `tt` для шаблонов Textile:
|
1211
1272
|
|
1212
1273
|
```ruby
|
1213
1274
|
Tilt.register :tt, Tilt[:textile]
|
@@ -1215,7 +1276,7 @@ Tilt.register :tt, Tilt[:textile]
|
|
1215
1276
|
|
1216
1277
|
### Добавление собственного движка рендеринга
|
1217
1278
|
|
1218
|
-
Сначала зарегистрируйте
|
1279
|
+
Сначала зарегистрируйте собственный движок в Tilt, а затем создайте метод, отвечающий
|
1219
1280
|
за рендеринг:
|
1220
1281
|
|
1221
1282
|
```ruby
|
@@ -1230,8 +1291,25 @@ get '/' do
|
|
1230
1291
|
end
|
1231
1292
|
```
|
1232
1293
|
|
1233
|
-
|
1234
|
-
https://github.com/rtomayko/tilt
|
1294
|
+
Данный код отрендерит `./views/index.myat`.
|
1295
|
+
Подробнее о [Tilt](https://github.com/rtomayko/tilt#readme).
|
1296
|
+
|
1297
|
+
### Использование пользовательской логики для поиска шаблона
|
1298
|
+
|
1299
|
+
Для того, чтобы реализовать собственный механизм поиска шаблона,
|
1300
|
+
необходимо написать метод `#find_template`:
|
1301
|
+
|
1302
|
+
```ruby
|
1303
|
+
configure do
|
1304
|
+
set :views [ './views/a', './views/b' ]
|
1305
|
+
end
|
1306
|
+
|
1307
|
+
def find_template(views, name, engine, &block)
|
1308
|
+
Array(views).each do |v|
|
1309
|
+
super(v, name, engine, &block)
|
1310
|
+
end
|
1311
|
+
end
|
1312
|
+
```
|
1235
1313
|
|
1236
1314
|
## Фильтры
|
1237
1315
|
|
@@ -1262,12 +1340,12 @@ after do
|
|
1262
1340
|
end
|
1263
1341
|
```
|
1264
1342
|
|
1265
|
-
|
1343
|
+
Обратите внимание: если вы используете метод `body`, а не просто возвращаете строку из
|
1266
1344
|
маршрута, то тело ответа не будет доступно в `after`-фильтрах, так как оно
|
1267
1345
|
будет сгенерировано позднее.
|
1268
1346
|
|
1269
|
-
Фильтры могут использовать шаблоны URL и будут
|
1270
|
-
путь запроса совпадет с
|
1347
|
+
Фильтры также могут использовать шаблоны URL и будут выполнены только в том случае,
|
1348
|
+
если путь запроса совпадет с указанным шаблоном:
|
1271
1349
|
|
1272
1350
|
```ruby
|
1273
1351
|
before '/protected/*' do
|
@@ -1275,7 +1353,7 @@ before '/protected/*' do
|
|
1275
1353
|
end
|
1276
1354
|
|
1277
1355
|
after '/create/:slug' do |slug|
|
1278
|
-
session[
|
1356
|
+
session[:last_slug] = slug
|
1279
1357
|
end
|
1280
1358
|
```
|
1281
1359
|
|
@@ -1293,8 +1371,9 @@ end
|
|
1293
1371
|
|
1294
1372
|
## Методы-помощники
|
1295
1373
|
|
1296
|
-
Используйте метод `helpers
|
1297
|
-
|
1374
|
+
Используйте высокоуровневый метод `helpers` для того, чтобы определить
|
1375
|
+
методы-помощники, которые могут быть использованы в обработчиках маршрутов
|
1376
|
+
и шаблонах:
|
1298
1377
|
|
1299
1378
|
```ruby
|
1300
1379
|
helpers do
|
@@ -1326,14 +1405,14 @@ helpers FooUtils, BarUtils
|
|
1326
1405
|
|
1327
1406
|
### Использование сессий
|
1328
1407
|
|
1329
|
-
Сессия
|
1330
|
-
включена, то у вас будет один
|
1408
|
+
Сессия используется для того, чтобы сохранять состояние между запросами. Если
|
1409
|
+
эта опция включена, то у вас будет один хэш сессии на один пользовательский сеанс:
|
1331
1410
|
|
1332
1411
|
```ruby
|
1333
1412
|
enable :sessions
|
1334
1413
|
|
1335
1414
|
get '/' do
|
1336
|
-
"value = " << session[
|
1415
|
+
"value = " << session[:value].inspect
|
1337
1416
|
end
|
1338
1417
|
|
1339
1418
|
get '/:value' do
|
@@ -1341,36 +1420,86 @@ get '/:value' do
|
|
1341
1420
|
end
|
1342
1421
|
```
|
1343
1422
|
|
1344
|
-
|
1345
|
-
куках (cookies). Это может быть не совсем то, что вы хотите (например,
|
1346
|
-
сохранение больших объемов данных увеличит ваш трафик). В таком случае вы
|
1347
|
-
можете использовать альтернативную Rack "прослойку" (middleware), реализующую
|
1348
|
-
механизм сессий. Для этого *не надо* вызывать `enable :sessions`, вместо этого
|
1349
|
-
следует подключить ее так же, как и любую другую "прослойку":
|
1423
|
+
### Безопасность сессии
|
1350
1424
|
|
1351
|
-
|
1352
|
-
|
1425
|
+
Для того, чтобы повысить безопасность, данные сессии в файле 'cookie'
|
1426
|
+
подписываются ключом сессии с использованием `HMAC-SHA1`. Этот ключ сессии
|
1427
|
+
должен быть оптимальным криптографическим 'secure random' значением соответствующей
|
1428
|
+
длины, которая для `HMAC-SHA1` больше или равна 64 байтам (512 бит, 128
|
1429
|
+
шестнадцатеричных символов). Не рекомендуется использовать ключ, длина
|
1430
|
+
которого менее 32 байт (256 бит, 64 шестнадцатеричных символа). Поэтому
|
1431
|
+
**очень важно**, чтобы вы не просто составили значение ключа, а использовали
|
1432
|
+
безопасный генератор случайных чисел для его создания. Люди очень плохо
|
1433
|
+
придумывают случайные значения.
|
1353
1434
|
|
1354
|
-
|
1355
|
-
|
1356
|
-
|
1435
|
+
По умолчанию, Sinatra создаёт для вас безопасный случайный ключ сессии из
|
1436
|
+
32 байт, однако он будет меняться при каждом перезапуске приложения. Если у
|
1437
|
+
вас есть несколько экземпляров вашего приложения, и вы доверили Sinatra
|
1438
|
+
генерацию ключа, то каждый экземпляр будет иметь отличный ключ сессии,
|
1439
|
+
что, вероятно, не совсем то, что вам необходимо.
|
1440
|
+
|
1441
|
+
Для лучшей безопасности и удобства использования
|
1442
|
+
[рекомендуется](https://12factor.net/config) генерировать случайный безопасный
|
1443
|
+
ключ и хранить его в переменной среды на каждом хосте, на котором запущено
|
1444
|
+
приложение, чтобы все экземпляры вашего приложения использовали один и тот
|
1445
|
+
же ключ. Вы должны периодически менять значение ключа сессии на новое.
|
1446
|
+
Вот несколько примеров того, как вы можете создать 64-байтный ключ
|
1447
|
+
и установить его:
|
1357
1448
|
|
1358
|
-
|
1359
|
-
|
1360
|
-
|
1449
|
+
**Генерация ключа сессии**
|
1450
|
+
|
1451
|
+
```text
|
1452
|
+
$ ruby -e "require 'securerandom'; puts SecureRandom.hex(64)"
|
1453
|
+
99ae8af...snip...ec0f262ac
|
1361
1454
|
```
|
1362
1455
|
|
1363
|
-
|
1364
|
-
|
1365
|
-
|
1366
|
-
|
1367
|
-
|
1456
|
+
**Генерация ключа сессии (бонусные пункты)**
|
1457
|
+
|
1458
|
+
Используйте [гем 'sysrandom'](https://github.com/cryptosphere/sysrandom#readme).
|
1459
|
+
Предпочтительнее использовать системные средства RNG для генерации случайных
|
1460
|
+
значений вместо пространства пользователя `OpenSSL`, который в настоящее время
|
1461
|
+
по умолчанию используется в MRI Ruby:
|
1462
|
+
|
1463
|
+
```text
|
1464
|
+
$ gem install sysrandom
|
1465
|
+
Создание собственных расширений. Это может занять некоторое время...
|
1466
|
+
Успешно установлен sysrandom-1.x
|
1467
|
+
1 gem установлен
|
1468
|
+
|
1469
|
+
$ ruby -e "require 'sysrandom/securerandom'; puts SecureRandom.hex(64)"
|
1470
|
+
99ae8af...snip...ec0f262ac
|
1471
|
+
```
|
1472
|
+
|
1473
|
+
**Переменная среды для ключа сессии**
|
1474
|
+
|
1475
|
+
Задайте переменной среды `SESSION_SECRET` значение, которое вы
|
1476
|
+
сгенерировали. Данная переменная автоматически будет использована Sinatra.
|
1477
|
+
Сделайте это значение постоянным при перезагрузке вашего
|
1478
|
+
сервера. Поскольку метод для генерации будет различным в разных системах,
|
1479
|
+
то код ниже приведён только в качестве примера:
|
1480
|
+
|
1481
|
+
```bash
|
1482
|
+
# echo "export SESSION_SECRET=99ae8af...snip...ec0f262ac" >> ~/.bashrc
|
1483
|
+
```
|
1484
|
+
|
1485
|
+
**Конфигурация приложения**
|
1486
|
+
|
1487
|
+
В целях безопасности настройте конфигурацию вашего приложения таким образом,
|
1488
|
+
чтобы оно генерировало случайный безопасный ключ тогда, когда переменная
|
1489
|
+
среды `SESSION_SECRET` не доступна.
|
1490
|
+
|
1491
|
+
В качестве бонусных пунктов здесь тоже используйте
|
1492
|
+
[гем 'sysrandom'gem](https://github.com/cryptosphere/sysrandom):
|
1368
1493
|
|
1369
1494
|
```ruby
|
1370
|
-
|
1495
|
+
require 'securerandom'
|
1496
|
+
# -или- require 'sysrandom/securerandom'
|
1497
|
+
set :session_secret, ENV.fetch('SESSION_SECRET') { SecureRandom.hex(64) }
|
1371
1498
|
```
|
1372
1499
|
|
1373
|
-
|
1500
|
+
#### Конфигурация сессии
|
1501
|
+
|
1502
|
+
Если вы хотите больше настроек для сессий, вы можете задать их, передав хэш
|
1374
1503
|
опций в параметр `sessions`:
|
1375
1504
|
|
1376
1505
|
```ruby
|
@@ -1384,10 +1513,46 @@ foo.com, добавьте *.* перед доменом:
|
|
1384
1513
|
set :sessions, :domain => '.foo.com'
|
1385
1514
|
```
|
1386
1515
|
|
1516
|
+
#### Выбор вашей собственной "прослойки" сессии
|
1517
|
+
|
1518
|
+
Обратите внимание на то, что при использовании `enable :sessions` все данные
|
1519
|
+
сохраняются в куках (cookies). Это может быть не совсем то, что вы хотите (например,
|
1520
|
+
сохранение больших объёмов данных увеличит ваш трафик). В таком случае вы
|
1521
|
+
можете использовать альтернативную Rack "прослойку" (middleware), реализующую
|
1522
|
+
механизм сессий. Для этого используете один из способов ниже:
|
1523
|
+
|
1524
|
+
```ruby
|
1525
|
+
enable :sessions
|
1526
|
+
set :session_store, Rack::Session::Pool
|
1527
|
+
```
|
1528
|
+
|
1529
|
+
Или установите параметры сессии при помощи хэша опций:
|
1530
|
+
|
1531
|
+
```ruby
|
1532
|
+
set :sessions, :expire_after => 2592000
|
1533
|
+
set :session_store, Rack::Session::Pool
|
1534
|
+
```
|
1535
|
+
|
1536
|
+
Вы также можете **не вызывать** `enable :sessions`, а вместо этого использовать
|
1537
|
+
необходимую вам Rack прослойку так же, как вы это обычно делаете.
|
1538
|
+
|
1539
|
+
Очень важно обратить внимание на то, что когда вы используете этот метод,
|
1540
|
+
основной способ защиты сессии **не будет включён по умолчанию**.
|
1541
|
+
|
1542
|
+
Вам также потребуется добавить следующие Rack middleware для этого:
|
1543
|
+
|
1544
|
+
```ruby
|
1545
|
+
use Rack::Session::Pool, :expire_after => 2592000
|
1546
|
+
use Rack::Protection::RemoteToken
|
1547
|
+
use Rack::Protection::SessionHijacking
|
1548
|
+
```
|
1549
|
+
|
1550
|
+
Смотрите раздел ["Настройка защиты от атак"](#Настройка-защиты-от-атак) для более подробной информации.
|
1551
|
+
|
1387
1552
|
### Прерывание
|
1388
1553
|
|
1389
1554
|
Чтобы незамедлительно прервать обработку запроса внутри фильтра или маршрута,
|
1390
|
-
|
1555
|
+
используйте следующую команду:
|
1391
1556
|
|
1392
1557
|
```ruby
|
1393
1558
|
halt
|
@@ -1425,8 +1590,8 @@ halt erb(:error)
|
|
1425
1590
|
|
1426
1591
|
### Передача
|
1427
1592
|
|
1428
|
-
Маршрут может передать обработку запроса следующему совпадающему
|
1429
|
-
используя `pass`:
|
1593
|
+
Маршрут может передать обработку запроса следующему совпадающему маршруту
|
1594
|
+
используя метод `pass`:
|
1430
1595
|
|
1431
1596
|
```ruby
|
1432
1597
|
get '/guess/:who' do
|
@@ -1439,7 +1604,7 @@ get '/guess/*' do
|
|
1439
1604
|
end
|
1440
1605
|
```
|
1441
1606
|
|
1442
|
-
Блок маршрута сразу же прерывается,
|
1607
|
+
Блок маршрута сразу же прерывается, а контроль переходит к следующему
|
1443
1608
|
совпадающему маршруту. Если соответствующий маршрут не найден, то ответом на
|
1444
1609
|
запрос будет 404.
|
1445
1610
|
|
@@ -1459,23 +1624,23 @@ get '/bar' do
|
|
1459
1624
|
end
|
1460
1625
|
```
|
1461
1626
|
|
1462
|
-
|
1463
|
-
производительность, перенеся `"bar"` в метод-помощник, используемый и в
|
1627
|
+
Обратите внимание на то, что в предыдущем примере можно облегчить тестирование и
|
1628
|
+
повысить производительность, перенеся `"bar"` в метод-помощник, используемый и в
|
1464
1629
|
`/foo`, и в `/bar`.
|
1465
1630
|
|
1466
|
-
Если вы хотите, чтобы запрос был отправлен в тот же экземпляр приложения,
|
1467
|
-
в его копию, используйте `call!` вместо `call`.
|
1631
|
+
Если вы хотите, чтобы запрос был отправлен в тот же экземпляр приложения,
|
1632
|
+
а не в его копию, используйте `call!` вместо `call`.
|
1468
1633
|
|
1469
1634
|
Если хотите узнать больше о `call`, смотрите спецификацию Rack.
|
1470
1635
|
|
1471
|
-
###
|
1636
|
+
### Установка тела, статус кода и заголовков ответа
|
1472
1637
|
|
1473
1638
|
Хорошим тоном является установка кода состояния HTTP и тела ответа в
|
1474
1639
|
возвращаемом значении обработчика маршрута. Тем не менее, в некоторых
|
1475
1640
|
ситуациях вам, возможно, понадобится задать тело ответа в произвольной точке
|
1476
|
-
потока исполнения. Вы можете сделать это
|
1641
|
+
потока исполнения. Вы можете сделать это при помощи метода-помощника `body`.
|
1477
1642
|
Если вы задействуете метод `body`, то вы можете использовать его и в
|
1478
|
-
дальнейшем, чтобы получить доступ к телу
|
1643
|
+
дальнейшем, чтобы получить доступ к телу ответа:
|
1479
1644
|
|
1480
1645
|
```ruby
|
1481
1646
|
get '/foo' do
|
@@ -1489,7 +1654,7 @@ end
|
|
1489
1654
|
|
1490
1655
|
Также можно передать блок в метод `body`, который затем будет вызван
|
1491
1656
|
обработчиком Rack (такой подход может быть использован для реализации
|
1492
|
-
|
1657
|
+
потокового ответа, см. ["Возвращаемые значения"](#Возвращаемые-значения)).
|
1493
1658
|
|
1494
1659
|
Аналогично вы можете установить код ответа и его заголовки:
|
1495
1660
|
|
@@ -1498,7 +1663,7 @@ get '/foo' do
|
|
1498
1663
|
status 418
|
1499
1664
|
headers \
|
1500
1665
|
"Allow" => "BREW, POST, GET, PROPFIND, WHEN",
|
1501
|
-
"Refresh" => "Refresh: 20;
|
1666
|
+
"Refresh" => "Refresh: 20; https://ietf.org/rfc/rfc2324.txt"
|
1502
1667
|
body "I'm a tea pot!"
|
1503
1668
|
end
|
1504
1669
|
```
|
@@ -1506,12 +1671,12 @@ end
|
|
1506
1671
|
Как и `body`, методы `headers` и `status`, вызванные без аргументов,
|
1507
1672
|
возвращают свои текущие значения.
|
1508
1673
|
|
1509
|
-
###
|
1674
|
+
### Потоковые ответы
|
1510
1675
|
|
1511
1676
|
Иногда требуется начать отправлять данные клиенту прямо в процессе
|
1512
1677
|
генерирования частей этих данных. В особых случаях требуется постоянно
|
1513
1678
|
отправлять данные до тех пор, пока клиент не закроет соединение. Вы можете
|
1514
|
-
использовать метод `stream` вместо
|
1679
|
+
использовать метод `stream` вместо разработки собственных "обёрток".
|
1515
1680
|
|
1516
1681
|
```ruby
|
1517
1682
|
get '/' do
|
@@ -1525,15 +1690,15 @@ get '/' do
|
|
1525
1690
|
end
|
1526
1691
|
```
|
1527
1692
|
|
1528
|
-
|
1693
|
+
Это позволяет вам реализовать стриминговые API,
|
1529
1694
|
[Server Sent Events](https://w3c.github.io/eventsource/),
|
1530
1695
|
и может служить основой для [WebSockets](https://en.wikipedia.org/wiki/WebSocket).
|
1531
|
-
Также такой подход можно использовать для увеличения производительности в случае,
|
1532
|
-
когда какая-то часть контента зависит от медленного ресурса.
|
1696
|
+
Также такой подход можно использовать для увеличения производительности в том случае,
|
1697
|
+
когда какая-то часть контента (а не весь) зависит от медленного ресурса.
|
1533
1698
|
|
1534
|
-
|
1699
|
+
Обратите внимание на то, что возможности стриминга, особенно количество одновременно
|
1535
1700
|
обслуживаемых запросов, очень сильно зависят от используемого веб-сервера.
|
1536
|
-
Некоторые серверы могут и вовсе не поддерживать стриминг.
|
1701
|
+
Некоторые серверы могут и вовсе не поддерживать стриминг. Если сервер не
|
1537
1702
|
поддерживает стриминг, то все данные будут отправлены за один раз сразу после
|
1538
1703
|
того, как блок, переданный в `stream`, завершится. Стриминг вообще не работает
|
1539
1704
|
при использовании Shotgun.
|
@@ -1541,7 +1706,7 @@ end
|
|
1541
1706
|
Если метод используется с параметром `keep_open`, то он не будет вызывать
|
1542
1707
|
`close` у объекта потока, что позволит вам закрыть его позже в любом другом
|
1543
1708
|
месте. Это работает только с событийными серверами, например, с Thin и
|
1544
|
-
Rainbows. Другие же серверы
|
1709
|
+
Rainbows. Другие же серверы всё равно будут закрывать поток:
|
1545
1710
|
|
1546
1711
|
```ruby
|
1547
1712
|
# long polling
|
@@ -1550,20 +1715,20 @@ set :server, :thin
|
|
1550
1715
|
connections = []
|
1551
1716
|
|
1552
1717
|
get '/subscribe' do
|
1553
|
-
# регистрация клиента
|
1718
|
+
# регистрация клиента в событиях сервера
|
1554
1719
|
stream(:keep_open) do |out|
|
1555
|
-
connections << out
|
1556
|
-
# удаление "
|
1720
|
+
connections << out
|
1721
|
+
# удаление "мёртвых клиентов"
|
1557
1722
|
connections.reject!(&:closed?)
|
1558
1723
|
end
|
1559
1724
|
end
|
1560
1725
|
|
1561
|
-
post '
|
1726
|
+
post '/:message' do
|
1562
1727
|
connections.each do |out|
|
1563
1728
|
# уведомить клиента о новом сообщении
|
1564
1729
|
out << params['message'] << "\n"
|
1565
1730
|
|
1566
|
-
#
|
1731
|
+
# указать клиенту на необходимость снова соединиться
|
1567
1732
|
out.close
|
1568
1733
|
end
|
1569
1734
|
|
@@ -1572,6 +1737,9 @@ post '/message' do
|
|
1572
1737
|
end
|
1573
1738
|
```
|
1574
1739
|
|
1740
|
+
Также клиент может закрыть соединение при попытке записи в сокет. В связи с
|
1741
|
+
этим рекомендуется выполнить проверку `out.closed?` прежде, чем пытаться произвести запись.
|
1742
|
+
|
1575
1743
|
### Логирование
|
1576
1744
|
|
1577
1745
|
В области видимости запроса метод `logger` предоставляет доступ к экземпляру
|
@@ -1588,9 +1756,9 @@ end
|
|
1588
1756
|
логирование выключено, то этот метод вернет пустой (dummy) объект, поэтому вы
|
1589
1757
|
можете смело использовать его в маршрутах и фильтрах.
|
1590
1758
|
|
1591
|
-
|
1592
|
-
`Sinatra::Application
|
1593
|
-
вы,
|
1759
|
+
Обратите внимание на то, что логирование включено по умолчанию только для
|
1760
|
+
`Sinatra::Application`. Если ваше приложение является подклассом `Sinatra::Base`, то
|
1761
|
+
вы, скорее всего, захотите включить его вручную:
|
1594
1762
|
|
1595
1763
|
```ruby
|
1596
1764
|
class MyApp < Sinatra::Base
|
@@ -1601,8 +1769,8 @@ end
|
|
1601
1769
|
```
|
1602
1770
|
|
1603
1771
|
Чтобы избежать использования любой логирующей "прослойки", задайте опции
|
1604
|
-
`logging` значение `nil`.
|
1605
|
-
`logger`
|
1772
|
+
`logging` значение `nil`. При этом не забывайте, что в такой ситуации
|
1773
|
+
`logger` будет возвращать `nil`. Чаще всего так делают, когда задают свой собственный
|
1606
1774
|
логер. Sinatra будет использовать то, что находится в `env['rack.logger']`.
|
1607
1775
|
|
1608
1776
|
### Mime-типы
|
@@ -1617,7 +1785,7 @@ configure do
|
|
1617
1785
|
end
|
1618
1786
|
```
|
1619
1787
|
|
1620
|
-
Вы также можете использовать это в `content_type
|
1788
|
+
Вы также можете использовать это в методе-помощнике `content_type`:
|
1621
1789
|
|
1622
1790
|
```ruby
|
1623
1791
|
get '/' do
|
@@ -1641,7 +1809,7 @@ end
|
|
1641
1809
|
|
1642
1810
|
### Перенаправление (редирект)
|
1643
1811
|
|
1644
|
-
Вы можете перенаправить браузер пользователя
|
1812
|
+
Вы можете перенаправить браузер пользователя при помощи метода `redirect`:
|
1645
1813
|
|
1646
1814
|
```ruby
|
1647
1815
|
get '/foo' do
|
@@ -1657,8 +1825,8 @@ redirect to('/bar'), 303
|
|
1657
1825
|
redirect 'http://www.google.com/', 'wrong place, buddy'
|
1658
1826
|
```
|
1659
1827
|
|
1660
|
-
Вы также можете перенаправить пользователя
|
1661
|
-
|
1828
|
+
Вы также можете перенаправить пользователя обратно на страницу, с которой он
|
1829
|
+
пришёл, при помощи `redirect back`:
|
1662
1830
|
|
1663
1831
|
```ruby
|
1664
1832
|
get '/foo' do
|
@@ -1671,8 +1839,8 @@ get '/bar' do
|
|
1671
1839
|
end
|
1672
1840
|
```
|
1673
1841
|
|
1674
|
-
|
1675
|
-
их в строку запроса:
|
1842
|
+
Для того, чтобы передать какие-либо параметры вместе с перенаправлением,
|
1843
|
+
добавьте их в строку запроса:
|
1676
1844
|
|
1677
1845
|
```ruby
|
1678
1846
|
redirect to('/bar?sum=42')
|
@@ -1684,12 +1852,12 @@ redirect to('/bar?sum=42')
|
|
1684
1852
|
enable :sessions
|
1685
1853
|
|
1686
1854
|
get '/foo' do
|
1687
|
-
session[
|
1855
|
+
session[:secret] = 'foo'
|
1688
1856
|
redirect to('/bar')
|
1689
1857
|
end
|
1690
1858
|
|
1691
1859
|
get '/bar' do
|
1692
|
-
session[
|
1860
|
+
session[:secret]
|
1693
1861
|
end
|
1694
1862
|
```
|
1695
1863
|
|
@@ -1697,7 +1865,7 @@ end
|
|
1697
1865
|
|
1698
1866
|
Установка корректных заголовков — основа правильного HTTP кэширования.
|
1699
1867
|
|
1700
|
-
Вы можете легко выставить заголовок Cache-Control
|
1868
|
+
Вы можете легко выставить заголовок Cache-Control следующим образом:
|
1701
1869
|
|
1702
1870
|
```ruby
|
1703
1871
|
get '/' do
|
@@ -1723,13 +1891,14 @@ before do
|
|
1723
1891
|
end
|
1724
1892
|
```
|
1725
1893
|
|
1726
|
-
Чтобы
|
1727
|
-
|
1728
|
-
методы-помощники *до* выполнения
|
1729
|
-
немедленно отправят ответ
|
1894
|
+
Чтобы использовать кэширование правильно, вам стоит подумать о
|
1895
|
+
применении `etag` или `last_modified`. Рекомендуется использовать эти
|
1896
|
+
методы-помощники *до* выполнения ресурсоёмких вычислений, так как они
|
1897
|
+
немедленно отправят ответ клиенту в том случае, если текущая версия
|
1898
|
+
уже присутствует в их кэше:
|
1730
1899
|
|
1731
1900
|
```ruby
|
1732
|
-
get
|
1901
|
+
get "/article/:id" do
|
1733
1902
|
@article = Article.find params['id']
|
1734
1903
|
last_modified @article.updated_at
|
1735
1904
|
etag @article.sha1
|
@@ -1744,13 +1913,13 @@ end
|
|
1744
1913
|
etag @article.sha1, :weak
|
1745
1914
|
```
|
1746
1915
|
|
1747
|
-
Эти методы-помощники не станут ничего
|
1748
|
-
необходимую информацию для вашего кэша. Если вы ищете
|
1749
|
-
кэширования, попробуйте [rack-cache](https://github.com/rtomayko/rack-cache):
|
1916
|
+
Эти методы-помощники не станут ничего кэшировать, однако они дадут
|
1917
|
+
необходимую информацию для вашего кэша. Если вы ищете лёгкое решение для
|
1918
|
+
кэширования, попробуйте [rack-cache](https://github.com/rtomayko/rack-cache#readme):
|
1750
1919
|
|
1751
1920
|
```ruby
|
1752
|
-
require
|
1753
|
-
require
|
1921
|
+
require "rack/cache"
|
1922
|
+
require "sinatra"
|
1754
1923
|
|
1755
1924
|
use Rack::Cache
|
1756
1925
|
|
@@ -1767,9 +1936,9 @@ end
|
|
1767
1936
|
В соответствии с RFC 2616 ваше приложение должно вести себя по-разному, когда
|
1768
1937
|
заголовки If-Match или If-None-Match имеют значение `*`, в зависимости от
|
1769
1938
|
того, существует или нет запрашиваемый ресурс. Sinatra предполагает, что
|
1770
|
-
ресурсы, к которым обращаются
|
1939
|
+
ресурсы, к которым обращаются при помощи безопасных (GET) и идемпотентных (PUT)
|
1771
1940
|
методов, уже существуют, а остальные ресурсы (к которым обращаются, например,
|
1772
|
-
|
1941
|
+
при помощи POST) считает новыми. Вы можете изменить данное поведение при помощи
|
1773
1942
|
опции `:new_resource`:
|
1774
1943
|
|
1775
1944
|
```ruby
|
@@ -1806,36 +1975,37 @@ send_file 'foo.png', :type => :jpg
|
|
1806
1975
|
|
1807
1976
|
<dl>
|
1808
1977
|
<dt>filename</dt>
|
1809
|
-
|
1978
|
+
<dd>имя файла, по умолчанию: реальное имя файла.</dd>
|
1810
1979
|
|
1811
1980
|
<dt>last_modified</dt>
|
1812
|
-
|
1813
|
-
|
1981
|
+
<dd>значение для заголовка Last-Modified, по умолчанию: mtime (время
|
1982
|
+
изменения) файла.</dd>
|
1814
1983
|
|
1815
1984
|
<dt>type</dt>
|
1816
|
-
|
1985
|
+
<dd>тип файла, по умолчанию: определяется по расширению файла.</dd>
|
1817
1986
|
|
1818
1987
|
<dt>disposition</dt>
|
1819
|
-
|
1820
|
-
|
1988
|
+
<dd>
|
1989
|
+
используется для заголовка Content-Disposition, возможные значения: <tt>nil</tt>
|
1990
|
+
(по умолчанию), <tt>:attachment</tt> и <tt>:inline</tt>
|
1991
|
+
</dd>
|
1821
1992
|
|
1822
1993
|
<dt>length</dt>
|
1823
|
-
|
1994
|
+
<dd>значения для заголовка Content-Length, по умолчанию: размер файла.</dd>
|
1824
1995
|
|
1825
1996
|
<dt>status</dt>
|
1826
|
-
|
1827
|
-
|
1997
|
+
<dd>
|
1998
|
+
Код ответа. Полезно в том случае, когда отсылается статический файл в качестве
|
1999
|
+
страницы с сообщением об ошибке. Если поддерживается обработчик Rack, будут использоваться
|
2000
|
+
другие средства, кроме потоковой передачи из процесса Ruby. Если вы используете
|
2001
|
+
этот вспомогательный метод, Sinatra автоматически обрабатывает запросы диапазона.
|
2002
|
+
</dd>
|
1828
2003
|
</dl>
|
1829
2004
|
|
1830
|
-
Этот метод будет использовать возможности Rack сервера для отправки файлов,
|
1831
|
-
если они доступны, в противном случае будет напрямую отдавать файл из Ruby
|
1832
|
-
процесса. Метод `send_file` также обеспечивает автоматическую обработку
|
1833
|
-
частичных (range) запросов с помощью Sinatra.
|
1834
|
-
|
1835
2005
|
### Доступ к объекту запроса
|
1836
2006
|
|
1837
2007
|
Объект входящего запроса доступен на уровне обработки запроса (в фильтрах,
|
1838
|
-
маршрутах, обработчиках ошибок)
|
2008
|
+
маршрутах, обработчиках ошибок) при помощи `request` метода:
|
1839
2009
|
|
1840
2010
|
```ruby
|
1841
2011
|
# приложение запущено на http://example.com/example
|
@@ -1856,22 +2026,22 @@ get '/foo' do
|
|
1856
2026
|
request.host # "example.com"
|
1857
2027
|
request.get? # true (есть аналоги для других методов HTTP)
|
1858
2028
|
request.form_data? # false
|
1859
|
-
request["some_param"] # значение параметра some_param. Шорткат для
|
2029
|
+
request["some_param"] # значение параметра some_param. Шорткат для хэша params
|
1860
2030
|
request.referrer # источник запроса клиента либо '/'
|
1861
2031
|
request.user_agent # user agent (используется для :agent условия)
|
1862
|
-
request.cookies #
|
2032
|
+
request.cookies # хэш, содержащий cookies браузера
|
1863
2033
|
request.xhr? # является ли запрос ajax запросом?
|
1864
2034
|
request.url # "http://example.com/example/foo"
|
1865
2035
|
request.path # "/example/foo"
|
1866
2036
|
request.ip # IP-адрес клиента
|
1867
2037
|
request.secure? # false (true, если запрос сделан через SSL)
|
1868
2038
|
request.forwarded? # true (если сервер работает за обратным прокси)
|
1869
|
-
request.env # "сырой" env
|
2039
|
+
request.env # "сырой" env хэш, полученный Rack
|
1870
2040
|
end
|
1871
2041
|
```
|
1872
2042
|
|
1873
2043
|
Некоторые опции, такие как `script_name` или `path_info`, доступны для
|
1874
|
-
|
2044
|
+
модификации:
|
1875
2045
|
|
1876
2046
|
```ruby
|
1877
2047
|
before { request.path_info = "/" }
|
@@ -1893,8 +2063,8 @@ end
|
|
1893
2063
|
|
1894
2064
|
### Вложения
|
1895
2065
|
|
1896
|
-
Вы можете использовать метод `attachment`, чтобы
|
1897
|
-
сервера должен быть
|
2066
|
+
Вы можете использовать метод `attachment`, чтобы сообщить браузеру о том,
|
2067
|
+
что ответ сервера должен быть сохранён на диск, а не отображён:
|
1898
2068
|
|
1899
2069
|
```ruby
|
1900
2070
|
get '/' do
|
@@ -1916,18 +2086,18 @@ end
|
|
1916
2086
|
|
1917
2087
|
Sinatra предлагает метод-помощник `time_for`, который из заданного значения
|
1918
2088
|
создает объект Time. Он также может конвертировать `DateTime`, `Date` и
|
1919
|
-
|
2089
|
+
схожие классы:
|
1920
2090
|
|
1921
2091
|
```ruby
|
1922
2092
|
get '/' do
|
1923
|
-
pass if Time.now > time_for('Dec 23,
|
2093
|
+
pass if Time.now > time_for('Dec 23, 2016')
|
1924
2094
|
"still time"
|
1925
2095
|
end
|
1926
2096
|
```
|
1927
2097
|
|
1928
2098
|
Этот метод используется внутри Sinatra методами `expires`, `last_modified` и
|
1929
2099
|
им подобными. Поэтому вы легко можете изменить и дополнить поведение этих методов,
|
1930
|
-
переопределив `time_for` в
|
2100
|
+
переопределив `time_for` в своём приложении:
|
1931
2101
|
|
1932
2102
|
```ruby
|
1933
2103
|
helpers do
|
@@ -1947,7 +2117,7 @@ get '/' do
|
|
1947
2117
|
end
|
1948
2118
|
```
|
1949
2119
|
|
1950
|
-
### Поиск шаблонов
|
2120
|
+
### Поиск файлов шаблонов
|
1951
2121
|
|
1952
2122
|
Для поиска шаблонов и их последующего рендеринга используется метод
|
1953
2123
|
`find_template`:
|
@@ -1990,18 +2160,17 @@ end
|
|
1990
2160
|
|
1991
2161
|
Вы можете легко вынести этот код в расширение и поделиться им с остальными!
|
1992
2162
|
|
1993
|
-
|
1994
|
-
а вызывает заданный блок для всех возможных путей. Дело тут не в
|
1995
|
-
производительности,
|
1996
|
-
|
1997
|
-
если приложение запущено не в режиме разработки (`set :environment,
|
1998
|
-
|
1999
|
-
|
2163
|
+
Обратите внимание на тот факт, что `find_template` не проверяет, существует ли
|
2164
|
+
файл на самом деле, а вызывает заданный блок для всех возможных путей. Дело тут не в
|
2165
|
+
производительности, а в том, что `render` вызовет `break` как только файл
|
2166
|
+
будет найден. Содержимое и местонахождение шаблонов будет закэшировано в том случае,
|
2167
|
+
если приложение запущено не в режиме разработки (`set :environment, :development`).
|
2168
|
+
Вы должны помнить об этих нюансах, если пишите по-настоящему "сумасшедший"
|
2169
|
+
метод.
|
2000
2170
|
|
2001
2171
|
## Конфигурация
|
2002
2172
|
|
2003
|
-
Этот блок исполняется один раз при старте в любом
|
2004
|
-
(environment):
|
2173
|
+
Этот блок исполняется один раз при старте в любом окружении (environment):
|
2005
2174
|
|
2006
2175
|
```ruby
|
2007
2176
|
configure do
|
@@ -2022,7 +2191,8 @@ configure do
|
|
2022
2191
|
end
|
2023
2192
|
```
|
2024
2193
|
|
2025
|
-
|
2194
|
+
Следующий пример будет выполнен только тогда, когда окружение
|
2195
|
+
(переменная `APP_ENV`) будет задана как `:production`:
|
2026
2196
|
|
2027
2197
|
```ruby
|
2028
2198
|
configure :production do
|
@@ -2030,7 +2200,8 @@ configure :production do
|
|
2030
2200
|
end
|
2031
2201
|
```
|
2032
2202
|
|
2033
|
-
|
2203
|
+
Следующий код будет выполнен в том случае, когда окружение
|
2204
|
+
будет задано как `:production` или `:test`:
|
2034
2205
|
|
2035
2206
|
```ruby
|
2036
2207
|
configure :production, :test do
|
@@ -2038,7 +2209,7 @@ configure :production, :test do
|
|
2038
2209
|
end
|
2039
2210
|
```
|
2040
2211
|
|
2041
|
-
Вы можете получить доступ к этим опциям
|
2212
|
+
Вы можете получить доступ к этим опциям при помощи метода `settings`:
|
2042
2213
|
|
2043
2214
|
```ruby
|
2044
2215
|
configure do
|
@@ -2055,16 +2226,16 @@ end
|
|
2055
2226
|
### Настройка защиты от атак
|
2056
2227
|
|
2057
2228
|
Sinatra использует
|
2058
|
-
[Rack::Protection](https://github.com/sinatra/rack-protection#readme) для защиты
|
2229
|
+
[Rack::Protection](https://github.com/sinatra/sinatra/tree/master/rack-protection#readme) для защиты
|
2059
2230
|
приложения от простых атак. Вы можете легко выключить эту защиту (что сделает
|
2060
|
-
ваше приложение чрезвычайно уязвимым):
|
2231
|
+
ваше приложение чрезвычайно уязвимым к большому числу различных уязвимостей):
|
2061
2232
|
|
2062
2233
|
```ruby
|
2063
2234
|
disable :protection
|
2064
2235
|
```
|
2065
2236
|
|
2066
|
-
Чтобы
|
2067
|
-
`protection`:
|
2237
|
+
Чтобы отключить какой-либо конкретный уровень защиты, передайте хэш опций
|
2238
|
+
в параметр `protection`:
|
2068
2239
|
|
2069
2240
|
```ruby
|
2070
2241
|
set :protection, :except => :path_traversal
|
@@ -2076,204 +2247,268 @@ set :protection, :except => :path_traversal
|
|
2076
2247
|
set :protection, :except => [:path_traversal, :session_hijacking]
|
2077
2248
|
```
|
2078
2249
|
|
2250
|
+
По умолчанию Sinatra будет устанавливать `session based` защиту только если
|
2251
|
+
включена опция `:sessions`. См. ["Использование сессий""](#Использование-сессий).
|
2252
|
+
Иногда вы захотите настроить сессии "вне" приложения Sinatra, например, в
|
2253
|
+
config.ru или при помощи отдельного экземпляра `Rack::Builder`. В таком случае
|
2254
|
+
вы также можете настроить `session based` защиту, передав опцию `:session`:
|
2255
|
+
|
2256
|
+
```ruby
|
2257
|
+
set :protection, :session => true
|
2258
|
+
```
|
2259
|
+
|
2079
2260
|
### Доступные настройки
|
2080
2261
|
|
2081
2262
|
<dl>
|
2082
2263
|
<dt>absolute_redirects</dt>
|
2083
|
-
|
2084
|
-
|
2085
|
-
|
2086
|
-
|
2087
|
-
|
2088
|
-
|
2089
|
-
|
2090
|
-
|
2091
|
-
|
2092
|
-
|
2093
|
-
|
2094
|
-
|
2264
|
+
<dd>
|
2265
|
+
если отключено, то Sinatra будет позволять использование относительных
|
2266
|
+
перенаправлений, но при этом перестанет соответствовать RFC 2616 (HTTP
|
2267
|
+
1.1), который разрешает только абсолютные перенаправления.
|
2268
|
+
</dd>
|
2269
|
+
<dd>
|
2270
|
+
включайте эту опцию, если ваше приложение работает за обратным прокси,
|
2271
|
+
который настроен не совсем корректно. Обратите внимание на тот факт, что
|
2272
|
+
метод <tt>url</tt> всё равно будет генерировать абсолютные URL в том случае,
|
2273
|
+
если вы не передадите <tt>false</tt> вторым аргументом.
|
2274
|
+
</dd>
|
2275
|
+
<dd>отключено по умолчанию.</dd>
|
2095
2276
|
|
2096
2277
|
<dt>add_charset</dt>
|
2097
|
-
|
2098
|
-
|
2099
|
-
|
2100
|
-
|
2101
|
-
|
2278
|
+
<dd>
|
2279
|
+
mime-типы, к которым метод <tt>content_type</tt> будет автоматически добавлять
|
2280
|
+
информацию о кодировке. Вам следует добавлять значения к этой опции
|
2281
|
+
вместо её переопределения: <tt>settings.add_charset << "application/foobar"</tt>
|
2282
|
+
</dd>
|
2102
2283
|
|
2103
2284
|
<dt>app_file</dt>
|
2104
|
-
|
2105
|
-
|
2106
|
-
|
2107
|
-
|
2108
|
-
|
2285
|
+
<dd>
|
2286
|
+
путь к главному файлу приложения, используется для нахождения корневой
|
2287
|
+
директории проекта, директорий с шаблонами и статическими файлами,
|
2288
|
+
вложенных шаблонов.
|
2289
|
+
</dd>
|
2109
2290
|
|
2110
2291
|
<dt>bind</dt>
|
2111
|
-
|
2112
|
-
|
2113
|
-
|
2114
|
-
|
2292
|
+
<dd>
|
2293
|
+
используемый IP-адрес (по умолчанию: <tt>0.0.0.0</tt> <em>или</em>
|
2294
|
+
<tt>localhost</tt> если опция `environment` настроена на "development").
|
2295
|
+
Используется только встроенным сервером.
|
2296
|
+
</dd>
|
2115
2297
|
|
2116
2298
|
<dt>default_encoding</dt>
|
2117
|
-
|
2299
|
+
<dd>кодировка, если неизвестна (по умолчанию: <tt>"utf-8"</tt>).</dd>
|
2118
2300
|
|
2119
2301
|
<dt>dump_errors</dt>
|
2120
|
-
|
2302
|
+
<dd>отображать ошибки в логе.</dd>
|
2121
2303
|
|
2122
2304
|
<dt>environment</dt>
|
2123
|
-
|
2124
|
-
|
2125
|
-
|
2126
|
-
|
2305
|
+
<dd>
|
2306
|
+
текущее окружение, по умолчанию, значение <tt>ENV['APP_ENV']</tt> или
|
2307
|
+
<tt>"development"</tt>, если <tt>ENV['APP_ENV']</tt> недоступна.
|
2308
|
+
</dd>
|
2127
2309
|
|
2128
2310
|
<dt>logging</dt>
|
2129
|
-
|
2311
|
+
<dd>использовать логер.</dd>
|
2130
2312
|
|
2131
2313
|
<dt>lock</dt>
|
2132
|
-
|
2133
|
-
|
2134
|
-
|
2314
|
+
<dd>
|
2315
|
+
создаёт блокировку для каждого запроса, которая гарантирует обработку
|
2316
|
+
только одного запроса в текущий момент времени в Ruby процессе.
|
2317
|
+
</dd>
|
2318
|
+
<dd>
|
2319
|
+
включайте в том случае, если ваше приложение не потокобезопасно (thread-safe).
|
2320
|
+
Отключено по умолчанию.
|
2135
2321
|
</dd>
|
2136
|
-
<dd>
|
2137
|
-
Включайте, если ваше приложение не потоко-безопасно (thread-safe).
|
2138
|
-
Отключено по умолчанию.</dd>
|
2139
2322
|
|
2140
2323
|
<dt>method_override</dt>
|
2141
|
-
|
2142
|
-
|
2143
|
-
|
2144
|
-
|
2324
|
+
<dd>
|
2325
|
+
использовать "магический" параметр <tt>_method</tt> для поддержки
|
2326
|
+
PUT/DELETE форм в браузерах, которые не поддерживают данные методы.
|
2327
|
+
</dd>
|
2328
|
+
|
2329
|
+
<dt>mustermann_opts</dt>
|
2330
|
+
<dd>
|
2331
|
+
хэш настроек по умолчанию для перехода к Mustermann.new при компиляции
|
2332
|
+
маршрутов маршрутизации.
|
2333
|
+
</dd>
|
2145
2334
|
|
2146
2335
|
<dt>port</dt>
|
2147
|
-
|
2148
|
-
|
2149
|
-
|
2150
|
-
|
2336
|
+
<dd>
|
2337
|
+
порт, на котором будет работать сервер.
|
2338
|
+
Используется только встроенным сервером.
|
2339
|
+
</dd>
|
2151
2340
|
|
2152
2341
|
<dt>prefixed_redirects</dt>
|
2153
|
-
|
2154
|
-
|
2155
|
-
|
2156
|
-
|
2157
|
-
|
2342
|
+
<dd>
|
2343
|
+
добавлять или нет параметр <tt>request.script_name</tt> к редиректам, если не
|
2344
|
+
задан абсолютный путь. Таким образом, <tt>redirect '/foo'</tt> будет вести себя
|
2345
|
+
как <tt>redirect to('/foo')</tt>. Отключено по умолчанию.
|
2346
|
+
</dd>
|
2158
2347
|
|
2159
2348
|
<dt>protection</dt>
|
2160
|
-
|
2349
|
+
<dd>включена или нет защита от атак. Смотрите секцию защиты от атак выше.</dd>
|
2161
2350
|
|
2162
2351
|
<dt>public_dir</dt>
|
2163
|
-
|
2352
|
+
<dd>алиас для <tt>public_folder</tt>.</dd>
|
2164
2353
|
|
2165
2354
|
<dt>public_folder</dt>
|
2166
|
-
|
2167
|
-
|
2168
|
-
|
2169
|
-
|
2170
|
-
|
2355
|
+
<dd>
|
2356
|
+
путь к общедоступной директории, откуда будут раздаваться файлы.
|
2357
|
+
Используется, только если включена раздача статических файлов
|
2358
|
+
(см. опцию <tt>static</tt> ниже). Берётся из настройки <tt>app_file</tt>,
|
2359
|
+
если не установлена.
|
2360
|
+
</dd>
|
2361
|
+
|
2362
|
+
<dt>quiet</dt>
|
2363
|
+
<dd>
|
2364
|
+
отключает журналы, созданные командами запуска и остановки Sinatra.
|
2365
|
+
<tt>false</tt> по умолчанию.
|
2366
|
+
</dd>
|
2171
2367
|
|
2172
2368
|
<dt>reload_templates</dt>
|
2173
|
-
|
2174
|
-
|
2175
|
-
|
2176
|
-
|
2369
|
+
<dd>
|
2370
|
+
перезагружать или нет шаблоны на каждый запрос. Включено в режиме
|
2371
|
+
разработки.
|
2372
|
+
</dd>
|
2177
2373
|
|
2178
2374
|
<dt>root</dt>
|
2179
|
-
|
2375
|
+
<dd>
|
2376
|
+
путь к корневой директории проекта. Берётся из настройки <tt>app_file</tt>,
|
2377
|
+
если не установлен.
|
2378
|
+
</dd>
|
2180
2379
|
|
2181
2380
|
<dt>raise_errors</dt>
|
2182
|
-
|
2183
|
-
|
2184
|
-
|
2185
|
-
|
2381
|
+
<dd>
|
2382
|
+
выбрасывать исключения (будет останавливать приложение).
|
2383
|
+
По умолчанию включено только в окружении <tt>"test"</tt>.
|
2384
|
+
</dd>
|
2186
2385
|
|
2187
2386
|
<dt>run</dt>
|
2188
|
-
|
2189
|
-
|
2190
|
-
|
2191
|
-
|
2387
|
+
<dd>
|
2388
|
+
если включено, Sinatra будет самостоятельно запускать веб-сервер. Не
|
2389
|
+
включайте, если используете rackup или аналогичные средства.
|
2390
|
+
</dd>
|
2192
2391
|
|
2193
2392
|
<dt>running</dt>
|
2194
|
-
|
2393
|
+
<dd>работает ли сейчас встроенный сервер? Не меняйте эту опцию!</dd>
|
2195
2394
|
|
2196
2395
|
<dt>server</dt>
|
2197
|
-
|
2198
|
-
|
2199
|
-
|
2200
|
-
|
2396
|
+
<dd>
|
2397
|
+
сервер или список серверов, которые следует использовать в качестве
|
2398
|
+
встроенного сервера. Порядок задаёт приоритет, по умолчанию зависит
|
2399
|
+
от реализации Ruby.
|
2400
|
+
</dd>
|
2401
|
+
|
2402
|
+
<dt>server_settings</dt>
|
2403
|
+
<dd>
|
2404
|
+
Если вы используете в качестве сервера WEBrick, например для работы в
|
2405
|
+
режиме разработки, то вы можете передать набор опций для <tt>server_settings</tt>,
|
2406
|
+
таких как <tt>SSLEnable</tt> или <tt>SSLVerifyClient</tt>. Тем не менее, такие
|
2407
|
+
серверы как Puma или Thin не поддерживают эти параметры, поэтому вы можете
|
2408
|
+
устанавливать <tt>server_settings</tt> указав его как метод при вызове
|
2409
|
+
<tt>configure</tt>.
|
2410
|
+
</dd>
|
2201
2411
|
|
2202
2412
|
<dt>sessions</dt>
|
2203
|
-
|
2204
|
-
|
2205
|
-
|
2206
|
-
|
2413
|
+
<dd>
|
2414
|
+
включить сессии на основе кук (cookie) на базе <tt>Rack::Session::Cookie</tt>.
|
2415
|
+
Смотрите раздел "Использование сессий" выше.
|
2416
|
+
</dd>
|
2417
|
+
|
2418
|
+
<dt>session_store</dt>
|
2419
|
+
<dd>
|
2420
|
+
используемая Rack "прослойка" для сессии. По умолчанию <tt>Rack::Session::Cookie</tt>.
|
2421
|
+
Смотрите раздел "Использование сессий" выше.
|
2422
|
+
</dd>
|
2207
2423
|
|
2208
2424
|
<dt>show_exceptions</dt>
|
2209
|
-
|
2210
|
-
|
2211
|
-
|
2212
|
-
|
2213
|
-
|
2214
|
-
|
2215
|
-
|
2216
|
-
|
2217
|
-
</dd>
|
2425
|
+
<dd>
|
2426
|
+
показывать исключения/стек вызовов (stack trace) в браузере. По умолчанию
|
2427
|
+
включено только в окружении <tt>"development"</tt>.
|
2428
|
+
</dd>
|
2429
|
+
<dd>
|
2430
|
+
может также быть установлено в <tt>:after_handler</tt> для запуска специфичной
|
2431
|
+
для приложения обработки ошибок, перед показом трассировки стека в браузере.
|
2432
|
+
</dd>
|
2218
2433
|
|
2219
2434
|
<dt>static</dt>
|
2220
|
-
|
2221
|
-
|
2222
|
-
|
2223
|
-
|
2435
|
+
<dd>указывает, должна ли Sinatra осуществлять раздачу статических файлов.</dd>
|
2436
|
+
<dd>Отключите, если используете какой-либо веб-сервер для этой цели.</dd>
|
2437
|
+
<dd>Отключение значительно улучшит производительность приложения.</dd>
|
2438
|
+
<dd>По умолчанию включено в классических и отключено в модульных приложениях.</dd>
|
2224
2439
|
|
2225
2440
|
<dt>static_cache_control</dt>
|
2226
|
-
|
2227
|
-
|
2228
|
-
|
2229
|
-
|
2230
|
-
|
2231
|
-
|
2232
|
-
|
2233
|
-
|
2234
|
-
|
2441
|
+
<dd>
|
2442
|
+
когда Sinatra раздаёт статические файлы, используйте эту опцию для того,
|
2443
|
+
чтобы добавить им заголовок <tt>Cache-Control</tt>. Для этого используется
|
2444
|
+
метод-помощник <tt>cache_control</tt>. По умолчанию отключено.
|
2445
|
+
</dd>
|
2446
|
+
<dd>
|
2447
|
+
используйте массив, когда надо задать несколько значений:
|
2448
|
+
<tt>set :static_cache_control, [:public, :max_age => 300]</tt>
|
2449
|
+
</dd>
|
2235
2450
|
|
2236
2451
|
<dt>threaded</dt>
|
2237
|
-
|
2238
|
-
|
2239
|
-
|
2240
|
-
|
2452
|
+
<dd>
|
2453
|
+
если включено, то Thin будет использовать <tt>EventMachine.defer</tt> для
|
2454
|
+
обработки запросов.
|
2455
|
+
</dd>
|
2241
2456
|
|
2242
2457
|
<dt>traps</dt>
|
2243
|
-
|
2458
|
+
<dd>указывает, должна ли Sinatra обрабатывать системные сигналы.</tt></dd>
|
2244
2459
|
|
2245
2460
|
<dt>views</dt>
|
2246
|
-
|
2461
|
+
<dd>
|
2462
|
+
путь к директории с шаблонами. Берётся из настройки <tt>app_file</tt> в том
|
2463
|
+
случае, если не установлен.
|
2464
|
+
</dd>
|
2465
|
+
|
2466
|
+
<dt>x_cascade</dt>
|
2467
|
+
<dd>
|
2468
|
+
Указывает, необходимо ли устанавливать заголовок X-Cascade если никакие маршруты не совпадают.
|
2469
|
+
<tt>true</tt> по умолчанию.
|
2470
|
+
</dd>
|
2247
2471
|
</dl>
|
2248
2472
|
|
2249
2473
|
## Режим, окружение
|
2250
2474
|
|
2251
|
-
Есть 3
|
2252
|
-
`"test"`. Режим может быть задан через переменную окружения `
|
2475
|
+
Есть 3 предопределённых режима работы приложения (окружения): `"development"`,
|
2476
|
+
`"production"` и `"test"`. Режим может быть задан через переменную окружения `APP_ENV`.
|
2253
2477
|
Значение по умолчанию — `"development"`. В этом режиме работы все шаблоны
|
2254
|
-
перезагружаются между
|
2478
|
+
перезагружаются между запросами, а также задаются специальные обработчики
|
2255
2479
|
`not_found` и `error`, чтобы вы могли увидеть стек вызовов. В окружениях
|
2256
2480
|
`"production"` и `"test"` шаблоны по умолчанию кэшируются.
|
2257
2481
|
|
2258
|
-
Для запуска приложения в
|
2482
|
+
Для запуска приложения в определённом окружении установите переменную
|
2483
|
+
окружения `APP_ENV`:
|
2259
2484
|
|
2260
|
-
```
|
2261
|
-
ruby my_app.rb
|
2485
|
+
```shell
|
2486
|
+
APP_ENV=production ruby my_app.rb
|
2262
2487
|
```
|
2263
2488
|
|
2264
|
-
Вы можете использовать
|
2265
|
-
|
2489
|
+
Вы можете использовать предопределённые методы `development?`, `test?` и
|
2490
|
+
`production?`, чтобы определить текущее окружение.
|
2491
|
+
|
2492
|
+
```ruby
|
2493
|
+
get '/' do
|
2494
|
+
if settings.development?
|
2495
|
+
"development!"
|
2496
|
+
else
|
2497
|
+
"not development!"
|
2498
|
+
end
|
2499
|
+
end
|
2500
|
+
```
|
2266
2501
|
|
2267
2502
|
## Обработка ошибок
|
2268
2503
|
|
2269
|
-
Обработчики ошибок исполняются в том же контексте, что и
|
2504
|
+
Обработчики ошибок исполняются в том же контексте, что и маршруты и
|
2270
2505
|
`before`-фильтры, а это означает, что всякие прелести вроде `haml`, `erb`,
|
2271
2506
|
`halt` и т.д. доступны и им.
|
2272
2507
|
|
2273
2508
|
### Not Found
|
2274
2509
|
|
2275
|
-
|
2276
|
-
|
2510
|
+
В случае возникновения исключения `Sinatra::NotFound` или возврата кода ответа 404
|
2511
|
+
будет вызван обработчик `not_found`:
|
2277
2512
|
|
2278
2513
|
```ruby
|
2279
2514
|
not_found do
|
@@ -2283,9 +2518,16 @@ end
|
|
2283
2518
|
|
2284
2519
|
### Error
|
2285
2520
|
|
2286
|
-
Обработчик ошибок `error` будет
|
2287
|
-
|
2288
|
-
|
2521
|
+
Обработчик ошибок `error` будет вызван тогда, когда исключение выброшено из блока
|
2522
|
+
маршрута либо из фильтра. Тем не менее, обратите внимание на то, что в режиме разработки
|
2523
|
+
он будет запускаться только в том случае, если вы установите опцию "show exceptions"
|
2524
|
+
на `: after_handler`:
|
2525
|
+
|
2526
|
+
```ruby
|
2527
|
+
set :show_exceptions, :after_handler
|
2528
|
+
```
|
2529
|
+
|
2530
|
+
Объект-исключение доступен как переменная `sinatra.error` в Rack:
|
2289
2531
|
|
2290
2532
|
```ruby
|
2291
2533
|
error do
|
@@ -2293,7 +2535,7 @@ error do
|
|
2293
2535
|
end
|
2294
2536
|
```
|
2295
2537
|
|
2296
|
-
|
2538
|
+
Пользовательские ошибки:
|
2297
2539
|
|
2298
2540
|
```ruby
|
2299
2541
|
error MyCustomError do
|
@@ -2301,7 +2543,7 @@ error MyCustomError do
|
|
2301
2543
|
end
|
2302
2544
|
```
|
2303
2545
|
|
2304
|
-
Тогда, если это
|
2546
|
+
Тогда, если это возникнет:
|
2305
2547
|
|
2306
2548
|
```ruby
|
2307
2549
|
get '/' do
|
@@ -2335,19 +2577,22 @@ error 400..510 do
|
|
2335
2577
|
end
|
2336
2578
|
```
|
2337
2579
|
|
2338
|
-
Sinatra устанавливает специальные `not_found` и `error
|
2339
|
-
приложение запущено в режиме разработки (окружение `:development`)
|
2580
|
+
Sinatra устанавливает специальные обработчики `not_found` и `error`, когда
|
2581
|
+
приложение запущено в режиме разработки (окружение `:development`) чтобы
|
2582
|
+
отображать информативные трассировки стека и дополнительную информацию об отладке
|
2583
|
+
в вашем браузере.
|
2340
2584
|
|
2341
2585
|
## Rack "прослойки"
|
2342
2586
|
|
2343
|
-
Sinatra использует [Rack](
|
2587
|
+
Sinatra использует [Rack](https://rack.github.io/) - минимальный стандартный
|
2344
2588
|
интерфейс для веб-фреймворков на Ruby. Одной из самых интересных для
|
2345
2589
|
разработчиков возможностей Rack является поддержка "прослоек" ("middleware") —
|
2346
2590
|
компонентов, находящихся "между" сервером и вашим приложением, которые
|
2347
2591
|
отслеживают и/или манипулируют HTTP запросами/ответами для предоставления
|
2348
2592
|
различной функциональности.
|
2349
2593
|
|
2350
|
-
|
2594
|
+
Sinatra позволяет очень просто создавать пайплайны из подобных Rack "прослоек"
|
2595
|
+
при помощи метода `use`:
|
2351
2596
|
|
2352
2597
|
```ruby
|
2353
2598
|
require 'sinatra'
|
@@ -2363,7 +2608,7 @@ end
|
|
2363
2608
|
|
2364
2609
|
Семантика `use` идентична той, что определена для
|
2365
2610
|
[Rack::Builder](http://www.rubydoc.info/github/rack/rack/master/Rack/Builder) DSL
|
2366
|
-
(чаще всего используется в rackup файлах).
|
2611
|
+
(чаще всего используется в rackup файлах). Так, например, метод `use` принимает как
|
2367
2612
|
множественные переменные, так и блоки:
|
2368
2613
|
|
2369
2614
|
```ruby
|
@@ -2375,20 +2620,18 @@ end
|
|
2375
2620
|
Rack распространяется с различными стандартными "прослойками" для логирования,
|
2376
2621
|
отладки, маршрутизации URL, аутентификации, обработки сессий. Sinatra
|
2377
2622
|
использует многие из этих компонентов автоматически, основываясь на
|
2378
|
-
конфигурации, чтобы вам не приходилось подключать
|
2623
|
+
конфигурации, чтобы вам не приходилось подключать их при помощи `use` вручную.
|
2379
2624
|
|
2380
2625
|
Вы можете найти полезные прослойки в
|
2381
2626
|
[rack](https://github.com/rack/rack/tree/master/lib/rack),
|
2382
2627
|
[rack-contrib](https://github.com/rack/rack-contrib#readme),
|
2383
|
-
или в
|
2384
|
-
[Rack wiki](https://github.com/rack/rack/wiki/List-of-Middleware).
|
2628
|
+
или в [Rack wiki](https://github.com/rack/rack/wiki/List-of-Middleware).
|
2385
2629
|
|
2386
2630
|
## Тестирование
|
2387
2631
|
|
2388
|
-
Тесты для Sinatra приложений могут быть написаны
|
2389
|
-
фреймворков, поддерживающих тестирование Rack.
|
2390
|
-
[Rack::Test](http://www.rubydoc.info/github/brynary/rack-test/master/frames)
|
2391
|
-
рекомендован:
|
2632
|
+
Тесты для Sinatra приложений могут быть написаны при помощи любых библиотек или
|
2633
|
+
фреймворков, поддерживающих тестирование Rack. Разработчики гема Sinatra рекомендуют
|
2634
|
+
использовать [Rack::Test](http://www.rubydoc.info/github/brynary/rack-test/master/frames):
|
2392
2635
|
|
2393
2636
|
```ruby
|
2394
2637
|
require 'my_sinatra_app'
|
@@ -2412,23 +2655,25 @@ class MyAppTest < Minitest::Test
|
|
2412
2655
|
assert_equal 'Hello Frank!', last_response.body
|
2413
2656
|
end
|
2414
2657
|
|
2415
|
-
def
|
2658
|
+
def test_with_user_agent
|
2416
2659
|
get '/', {}, 'HTTP_USER_AGENT' => 'Songbird'
|
2417
2660
|
assert_equal "You're using Songbird!", last_response.body
|
2418
2661
|
end
|
2419
2662
|
end
|
2420
2663
|
```
|
2421
2664
|
|
2665
|
+
Примечание: если вы используете Sinatra в модульном стиле, замените
|
2666
|
+
`Sinatra::Application` в примере выше на имя класса вашего приложения.
|
2667
|
+
|
2422
2668
|
## Sinatra::Base — "прослойки", библиотеки и модульные приложения
|
2423
2669
|
|
2424
|
-
Описание
|
2425
|
-
|
2426
|
-
|
2427
|
-
|
2428
|
-
|
2429
|
-
|
2430
|
-
|
2431
|
-
расширений Sinatra. И тут на помощь приходит `Sinatra::Base`:
|
2670
|
+
Описание вашего приложения на верхнем уровне хорошо работает для микроприложений,
|
2671
|
+
но имеет значительные недостатки при создании многоразовых компонентов, таких как
|
2672
|
+
Rack "прослойка", Rails metal, простые библиотеки с серверным компонентом или
|
2673
|
+
даже расширения Sinatra. Верхний уровень предполагает конфигурацию стиля
|
2674
|
+
микроприложений (например, одиночный файл приложения, `./public` и `./views`,
|
2675
|
+
каталоги, логирование, страницу подробных сведений об исключениях и т.д.).
|
2676
|
+
И тут на помощь приходит `Sinatra::Base`:
|
2432
2677
|
|
2433
2678
|
```ruby
|
2434
2679
|
require 'sinatra/base'
|
@@ -2443,20 +2688,33 @@ class MyApp < Sinatra::Base
|
|
2443
2688
|
end
|
2444
2689
|
```
|
2445
2690
|
|
2446
|
-
Методы, доступные `Sinatra::Base`
|
2447
|
-
приложениям
|
2448
|
-
конвертированы в `Sinatra::Base` компоненты
|
2691
|
+
Методы, доступные подклассам `Sinatra::Base` идентичны тем, что доступны
|
2692
|
+
приложениям при помощи DSL верхнего уровня. Большинство таких приложений могут быть
|
2693
|
+
конвертированы в `Sinatra::Base` компоненты при помощи двух модификаций:
|
2449
2694
|
|
2450
|
-
* Вы должны подключать `sinatra/base` вместо `sinatra`, иначе все методы,
|
2695
|
+
* Вы должны подключать `sinatra/base` вместо `sinatra`, иначе все DSL методы,
|
2451
2696
|
предоставляемые Sinatra, будут импортированы в глобальное пространство
|
2452
|
-
|
2697
|
+
имён.
|
2453
2698
|
* Поместите все маршруты, обработчики ошибок, фильтры и опции в подкласс
|
2454
2699
|
`Sinatra::Base`.
|
2455
2700
|
|
2456
2701
|
`Sinatra::Base` — это чистый лист. Большинство опций, включая встроенный
|
2457
|
-
сервер, по умолчанию отключены. Смотрите
|
2458
|
-
[Опции и конфигурация](http://www.sinatrarb.com/configuration.html)
|
2459
|
-
для детальной информации об опциях и их поведении.
|
2702
|
+
сервер, по умолчанию отключены. Смотрите
|
2703
|
+
[Опции и конфигурация](http://www.sinatrarb.com/configuration.html)
|
2704
|
+
для детальной информации об опциях и их поведении. Если вы хотите, чтобы
|
2705
|
+
поведение было более похоже на то, когда вы определяете своё приложение
|
2706
|
+
на верхнем уровне (также известно как классический стиль), вы можете
|
2707
|
+
унаследоваться от `Sinatra::Application`:
|
2708
|
+
|
2709
|
+
```ruby
|
2710
|
+
require 'sinatra/base'
|
2711
|
+
|
2712
|
+
class MyApp < Sinatra::Application
|
2713
|
+
get '/' do
|
2714
|
+
'Hello world!'
|
2715
|
+
end
|
2716
|
+
end
|
2717
|
+
```
|
2460
2718
|
|
2461
2719
|
### Модульные приложения против классических
|
2462
2720
|
|
@@ -2472,19 +2730,61 @@ end
|
|
2472
2730
|
Переходя с одного стиля на другой, примите во внимание следующие изменения в
|
2473
2731
|
настройках:
|
2474
2732
|
|
2475
|
-
|
2733
|
+
<table>
|
2734
|
+
<tr>
|
2735
|
+
<th>Опция</th>
|
2736
|
+
<th>Классический</th>
|
2737
|
+
<th>Модульный</th>
|
2738
|
+
<th>Модульный</th>
|
2739
|
+
</tr>
|
2740
|
+
|
2741
|
+
<tr>
|
2742
|
+
<td>app_file</td>
|
2743
|
+
<td>файл с приложением</td>
|
2744
|
+
<td>файл с подклассом Sinatra::Base</td>
|
2745
|
+
<td>файл с подклассом Sinatra::Application</td>
|
2746
|
+
</tr>
|
2747
|
+
|
2748
|
+
<tr>
|
2749
|
+
<td>run</td>
|
2750
|
+
<td>$0 == app_file</td>
|
2751
|
+
<td>false</td>
|
2752
|
+
<td>false</td>
|
2753
|
+
</tr>
|
2754
|
+
|
2755
|
+
<tr>
|
2756
|
+
<td>logging</td>
|
2757
|
+
<td>true</td>
|
2758
|
+
<td>false</td>
|
2759
|
+
<td>true</td>
|
2760
|
+
</tr>
|
2761
|
+
|
2762
|
+
<tr>
|
2763
|
+
<td>method_override</td>
|
2764
|
+
<td>true</td>
|
2765
|
+
<td>false</td>
|
2766
|
+
<td>true</td>
|
2767
|
+
</tr>
|
2768
|
+
|
2769
|
+
<tr>
|
2770
|
+
<td>inline_templates</td>
|
2771
|
+
<td>true</td>
|
2772
|
+
<td>false</td>
|
2773
|
+
<td>true</td>
|
2774
|
+
</tr>
|
2476
2775
|
|
2477
|
-
|
2478
|
-
|
2479
|
-
|
2480
|
-
|
2481
|
-
|
2482
|
-
|
2776
|
+
<tr>
|
2777
|
+
<td>static</td>
|
2778
|
+
<td>true</td>
|
2779
|
+
<td>File.exist?(public_folder)</td>
|
2780
|
+
<td>true</td>
|
2781
|
+
</tr>
|
2782
|
+
</table>
|
2483
2783
|
|
2484
2784
|
### Запуск модульных приложений
|
2485
2785
|
|
2486
2786
|
Есть два общепринятых способа запускать модульные приложения: запуск напрямую
|
2487
|
-
|
2787
|
+
при помощи `run!`:
|
2488
2788
|
|
2489
2789
|
```ruby
|
2490
2790
|
# my_app.rb
|
@@ -2500,22 +2800,22 @@ end
|
|
2500
2800
|
|
2501
2801
|
Затем:
|
2502
2802
|
|
2503
|
-
```
|
2803
|
+
```shell
|
2504
2804
|
ruby my_app.rb
|
2505
2805
|
```
|
2506
2806
|
|
2507
|
-
Или
|
2508
|
-
использовать любой Rack-совместимый сервер
|
2807
|
+
Или при помощи конфигурационного файла `config.ru`, который позволяет
|
2808
|
+
использовать любой Rack-совместимый сервер приложений:
|
2509
2809
|
|
2510
2810
|
```ruby
|
2511
|
-
# config.ru
|
2811
|
+
# config.ru (запускается при помощи Rackup)
|
2512
2812
|
require './my_app'
|
2513
2813
|
run MyApp
|
2514
2814
|
```
|
2515
2815
|
|
2516
2816
|
Запускаем:
|
2517
2817
|
|
2518
|
-
```
|
2818
|
+
```shell
|
2519
2819
|
rackup -p 4567
|
2520
2820
|
```
|
2521
2821
|
|
@@ -2541,17 +2841,16 @@ run Sinatra::Application
|
|
2541
2841
|
|
2542
2842
|
### Когда использовать config.ru?
|
2543
2843
|
|
2544
|
-
|
2545
|
-
`config.ru`:
|
2844
|
+
Использование файла `config.ru` рекомендовано если:
|
2546
2845
|
|
2547
|
-
* вы хотите разворачивать
|
2846
|
+
* вы хотите разворачивать своё приложение на различных Rack-совместимых
|
2548
2847
|
серверах (Passenger, Unicorn, Heroku, ...);
|
2549
2848
|
* вы хотите использовать более одного подкласса `Sinatra::Base`;
|
2550
2849
|
* вы хотите использовать Sinatra только в качестве "прослойки" Rack.
|
2551
2850
|
|
2552
2851
|
**Совсем необязательно переходить на использование `config.ru` лишь потому,
|
2553
2852
|
что вы стали использовать модульный стиль приложения. И необязательно
|
2554
|
-
использовать модульный стиль, чтобы запускать приложение
|
2853
|
+
использовать модульный стиль, чтобы запускать приложение при помощи
|
2555
2854
|
`config.ru`.**
|
2556
2855
|
|
2557
2856
|
### Использование Sinatra в качестве "прослойки"
|
@@ -2559,7 +2858,7 @@ run Sinatra::Application
|
|
2559
2858
|
Не только сама Sinatra может использовать "прослойки" Rack, но и любое Sinatra
|
2560
2859
|
приложение само может быть добавлено к любому Rack endpoint в качестве
|
2561
2860
|
"прослойки". Этим endpoint (конечной точкой) может быть другое Sinatra
|
2562
|
-
|
2861
|
+
приложение или любое другое приложение, основанное на Rack (Rails/Hamami/Roda/...):
|
2563
2862
|
|
2564
2863
|
```ruby
|
2565
2864
|
require 'sinatra/base'
|
@@ -2595,7 +2894,7 @@ end
|
|
2595
2894
|
### Создание приложений "на лету"
|
2596
2895
|
|
2597
2896
|
Иногда требуется создавать Sinatra приложения "на лету" (например, из другого
|
2598
|
-
приложения)
|
2897
|
+
приложения), не сохраняя их в константу. Это возможно при помощи `Sinatra.new`:
|
2599
2898
|
|
2600
2899
|
```ruby
|
2601
2900
|
require 'sinatra/base'
|
@@ -2607,7 +2906,7 @@ my_app.run!
|
|
2607
2906
|
наследоваться:
|
2608
2907
|
|
2609
2908
|
```ruby
|
2610
|
-
# config.ru
|
2909
|
+
# config.ru (запускается при помощи Rackup)
|
2611
2910
|
require 'sinatra/base'
|
2612
2911
|
|
2613
2912
|
controller = Sinatra.new do
|
@@ -2627,7 +2926,7 @@ end
|
|
2627
2926
|
Это особенно полезно для тестирования расширений Sinatra и при использовании
|
2628
2927
|
Sinatra внутри вашей библиотеки.
|
2629
2928
|
|
2630
|
-
|
2929
|
+
Это также значительно упрощает использование Sinatra в качестве прослойки:
|
2631
2930
|
|
2632
2931
|
```ruby
|
2633
2932
|
require 'sinatra/base'
|
@@ -2653,7 +2952,7 @@ run RailsProject::Application
|
|
2653
2952
|
вы не сможете получить доступ к объектам `request` или `session`, так как
|
2654
2953
|
существует только один класс приложения для всех запросов.
|
2655
2954
|
|
2656
|
-
Опции, созданные
|
2955
|
+
Опции, созданные при помощи `set`, являются методами уровня класса:
|
2657
2956
|
|
2658
2957
|
```ruby
|
2659
2958
|
class MyApp < Sinatra::Base
|
@@ -2667,10 +2966,10 @@ class MyApp < Sinatra::Base
|
|
2667
2966
|
end
|
2668
2967
|
```
|
2669
2968
|
|
2670
|
-
У вас будет
|
2969
|
+
У вас будет привязка к области видимости приложения внутри:
|
2671
2970
|
|
2672
2971
|
* тела вашего класса приложения;
|
2673
|
-
* методов,
|
2972
|
+
* методов, определённых расширениями;
|
2674
2973
|
* блока, переданного в `helpers`;
|
2675
2974
|
* блоков, использованных как значения для `set`;
|
2676
2975
|
* блока, переданного в `Sinatra.new`.
|
@@ -2685,9 +2984,9 @@ end
|
|
2685
2984
|
|
2686
2985
|
Для каждого входящего запроса будет создан новый экземпляр вашего приложения,
|
2687
2986
|
и все блоки обработчика будут запущены в этом контексте. В этой области
|
2688
|
-
видимости вам доступны `request` и `session` объекты, вызовы методов
|
2987
|
+
видимости вам доступны `request` и `session` объекты, а также вызовы методов
|
2689
2988
|
рендеринга, такие как `erb` или `haml`. Вы можете получить доступ к области
|
2690
|
-
видимости приложения из контекста
|
2989
|
+
видимости приложения из контекста запроса используя метод-помощник
|
2691
2990
|
`settings`:
|
2692
2991
|
|
2693
2992
|
```ruby
|
@@ -2707,10 +3006,10 @@ class MyApp < Sinatra::Base
|
|
2707
3006
|
end
|
2708
3007
|
```
|
2709
3008
|
|
2710
|
-
У вас будет
|
3009
|
+
У вас будет привязка к области видимости запроса в:
|
2711
3010
|
|
2712
|
-
* get
|
2713
|
-
* before
|
3011
|
+
* get, head, post, put, delete, options, patch, link и unlink блоках;
|
3012
|
+
* before и after фильтрах;
|
2714
3013
|
* методах-помощниках;
|
2715
3014
|
* шаблонах/отображениях.
|
2716
3015
|
|
@@ -2726,8 +3025,8 @@ end
|
|
2726
3025
|
|
2727
3026
|
У вас будет контекст делегирования внутри:
|
2728
3027
|
|
2729
|
-
* привязки верхнего уровня, если вы сделали `require
|
2730
|
-
* объекта, расширенного
|
3028
|
+
* привязки верхнего уровня, если вы сделали `require "sinatra"`;
|
3029
|
+
* объекта, расширенного при помощи `Sinatra::Delegator`.
|
2731
3030
|
|
2732
3031
|
Посмотрите сами в код: вот
|
2733
3032
|
[примесь Sinatra::Delegator](https://github.com/sinatra/sinatra/blob/ca06364/lib/sinatra/base.rb#L1609-1633)
|
@@ -2737,11 +3036,11 @@ end
|
|
2737
3036
|
|
2738
3037
|
Sinatra приложения могут быть запущены напрямую:
|
2739
3038
|
|
2740
|
-
```
|
2741
|
-
ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-o HOST] [-s HANDLER]
|
3039
|
+
```shell
|
3040
|
+
ruby myapp.rb [-h] [-x] [-q] [-e ENVIRONMENT] [-p PORT] [-o HOST] [-s HANDLER]
|
2742
3041
|
```
|
2743
3042
|
|
2744
|
-
|
3043
|
+
Поддерживаемые опции:
|
2745
3044
|
|
2746
3045
|
```
|
2747
3046
|
-h # раздел помощи
|
@@ -2749,19 +3048,20 @@ ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-o HOST] [-s HANDLER]
|
|
2749
3048
|
-o # указание хоста (по умолчанию 0.0.0.0)
|
2750
3049
|
-e # указание окружения, режима (по умолчанию development)
|
2751
3050
|
-s # указание rack сервера/обработчика (по умолчанию thin)
|
3051
|
+
-q # включить тихий режим для сервера (по умолчанию выключен)
|
2752
3052
|
-x # включить мьютекс-блокировку (по умолчанию выключена)
|
2753
3053
|
```
|
2754
3054
|
|
2755
|
-
###
|
3055
|
+
### Многопоточность
|
2756
3056
|
|
2757
|
-
_Данный раздел является перефразированным [ответом пользователя Konstantin]
|
3057
|
+
_Данный раздел является перефразированным [ответом пользователя Konstantin](https://stackoverflow.com/a/6282999/5245129) на StackOverflow_
|
2758
3058
|
|
2759
3059
|
Sinatra не навязывает каких-либо моделей параллелизма, но для этих целей можно
|
2760
|
-
использовать любой Rack
|
3060
|
+
использовать любой Rack обработчик (сервер), например Thin, Puma или WEBrick. Сама
|
2761
3061
|
по себе Sinatra потокобезопасна, поэтому нет никаких проблем в использовании
|
2762
3062
|
поточной модели параллелизма в Rack обработчике. Это означает, что когда
|
2763
3063
|
запускается сервер, вы должны указать правильный метод вызова для конкретного
|
2764
|
-
Rack обработчика. Пример ниже показывает, как можно запустить
|
3064
|
+
Rack обработчика. Пример ниже показывает, как можно запустить мультипоточный
|
2765
3065
|
Thin сервер:
|
2766
3066
|
|
2767
3067
|
```ruby
|
@@ -2776,60 +3076,45 @@ class App < Sinatra::Base
|
|
2776
3076
|
end
|
2777
3077
|
|
2778
3078
|
App.run!
|
3079
|
+
|
2779
3080
|
```
|
2780
3081
|
|
2781
|
-
|
3082
|
+
Для запуска сервере выполните следующую команду:
|
2782
3083
|
|
2783
3084
|
```shell
|
2784
3085
|
thin --threaded start
|
2785
3086
|
```
|
2786
3087
|
|
2787
|
-
[so-answer]: http://stackoverflow.com/questions/6278817/is-sinatra-multi-threaded/6282999#6282999)
|
2788
|
-
|
2789
3088
|
## Системные требования
|
2790
3089
|
|
2791
3090
|
Следующие версии Ruby официально поддерживаются:
|
2792
|
-
|
2793
3091
|
<dl>
|
2794
|
-
<dt>Ruby
|
2795
|
-
<dd>
|
2796
|
-
|
2797
|
-
|
2798
|
-
|
2799
|
-
возможно, поддержка не будет прекращена. <b>Ruby 1.8.6 больше не
|
2800
|
-
поддерживается.</b> Если вы хотите использовать 1.8.6, откатитесь до Sinatra
|
2801
|
-
1.2, которая будет получать все исправления ошибок до тех пор, пока не
|
2802
|
-
будет выпущена Sinatra 1.4.0.</dd>
|
2803
|
-
|
2804
|
-
<dt>Ruby 1.9.2</dt>
|
2805
|
-
<dd>1.9.2 полностью поддерживается и рекомендована к использованию.
|
2806
|
-
Не используйте 1.9.2p0,
|
2807
|
-
известно, что эта версия очень нестабильна при использовании Sinatra. Эта
|
2808
|
-
версия будет поддерживаться по крайней мере до выхода Ruby 1.9.4/2.0, а
|
2809
|
-
поддержка последней версии 1.9 будет осуществляться до тех пор, пока она
|
2810
|
-
поддерживается командой разработчиков Ruby.</dd>
|
2811
|
-
|
2812
|
-
<dt>Ruby 1.9.3</dt>
|
2813
|
-
<dd>1.9.3 полностью поддерживается. Заметьте, что переход на 1.9.3 с
|
2814
|
-
ранних версий сделает недействительными все сессии.</dd>
|
3092
|
+
<dt>Ruby 2.3</dt>
|
3093
|
+
<dd>
|
3094
|
+
Версия 2.3 полностью поддерживается и рекомендуется. В настоящее время нет
|
3095
|
+
планов отказаться от официальной поддержки.
|
3096
|
+
</dd>
|
2815
3097
|
|
2816
3098
|
<dt>Rubinius</dt>
|
2817
|
-
<dd>
|
2818
|
-
|
3099
|
+
<dd>
|
3100
|
+
Rubinius официально поддерживается (Rubinius >= 2.x). Рекомендуется
|
3101
|
+
выполнить <tt>gem install puma</tt>.
|
3102
|
+
</dd>
|
2819
3103
|
|
2820
3104
|
<dt>JRuby</dt>
|
2821
|
-
<dd>
|
2822
|
-
|
2823
|
-
|
2824
|
-
|
2825
|
-
|
2826
|
-
Redcarpet и RedCloth.</dd>
|
3105
|
+
<dd>
|
3106
|
+
Официально поддерживается последний стабильный релиз JRuby. Не
|
3107
|
+
рекомендуется использовать расширений на C в JRuby. Рекомендуется
|
3108
|
+
выполнить <tt>gem install trinidad</tt>.
|
3109
|
+
</dd>
|
2827
3110
|
</dl>
|
2828
3111
|
|
3112
|
+
Версии Ruby ниже 2.2.2 более не поддерживаются в Sinatra 2.0.
|
3113
|
+
|
2829
3114
|
Мы также следим за предстоящими к выходу версиями Ruby.
|
2830
3115
|
|
2831
|
-
Следующие реализации Ruby не поддерживаются официально,
|
2832
|
-
них запускается Sinatra:
|
3116
|
+
Следующие реализации Ruby не поддерживаются официально, однако известно, что
|
3117
|
+
на них запускается Sinatra:
|
2833
3118
|
|
2834
3119
|
* старые версии JRuby и Rubinius;
|
2835
3120
|
* Ruby Enterprise Edition;
|
@@ -2840,102 +3125,66 @@ thin --threaded start
|
|
2840
3125
|
работает на этой версии, а на поддерживаемой работает — это не наша проблема,
|
2841
3126
|
а их.
|
2842
3127
|
|
2843
|
-
Мы также запускаем наши CI-тесты на версии
|
2844
|
-
|
2845
|
-
|
2846
|
-
поддерживаться.
|
3128
|
+
Мы также запускаем наши CI-тесты на ruby-head (будущие версии MRI), но мы не
|
3129
|
+
можем ничего гарантировать, так как ведётся постоянная разработка.
|
3130
|
+
Предполагается, что предстоящие релизы 2.x будут полностью поддерживаться.
|
2847
3131
|
|
2848
3132
|
Sinatra должна работать на любой операционной системе, в которой есть одна из
|
2849
3133
|
указанных выше версий Ruby.
|
2850
3134
|
|
3135
|
+
Если вы запускаете MacRuby, вы должны выполнить `gem install control_tower`.
|
3136
|
+
|
2851
3137
|
Пока невозможно запустить Sinatra на Cardinal, SmallRuby, BlueRuby и на любой
|
2852
|
-
версии Ruby
|
3138
|
+
версии Ruby ниже 2.2.
|
2853
3139
|
|
2854
|
-
##
|
3140
|
+
## Самая свежая версия
|
2855
3141
|
|
2856
|
-
Если вы хотите использовать самый последний
|
2857
|
-
|
3142
|
+
Если вы хотите использовать самый последний релиз Sinatra, не бойтесь запускать
|
3143
|
+
своё приложение вместе с кодом из master ветки Sinatra, так как она весьма стабильна.
|
2858
3144
|
|
2859
|
-
Мы также время от времени выпускаем предварительные версии,
|
2860
|
-
|
3145
|
+
Мы также время от времени выпускаем предварительные версии, которые вы можете
|
3146
|
+
установить следующим образом:
|
2861
3147
|
|
2862
|
-
```
|
3148
|
+
```shell
|
2863
3149
|
gem install sinatra --pre
|
2864
3150
|
```
|
2865
3151
|
|
2866
|
-
|
3152
|
+
таким образом вы сможете воспользоваться некоторыми самыми последними возможностями.
|
2867
3153
|
|
2868
|
-
###
|
3154
|
+
### При помощи Bundler
|
2869
3155
|
|
2870
|
-
Если вы хотите запускать
|
3156
|
+
Если вы хотите запускать своё приложение с последней версией Sinatra, то
|
2871
3157
|
рекомендуем использовать [Bundler](http://bundler.io).
|
2872
3158
|
|
2873
|
-
|
3159
|
+
Для начала установите Bundler, если у вас его ещё нет:
|
2874
3160
|
|
2875
|
-
```
|
3161
|
+
```shell
|
2876
3162
|
gem install bundler
|
2877
3163
|
```
|
2878
3164
|
|
2879
3165
|
Затем создайте файл `Gemfile` в директории вашего проекта:
|
2880
3166
|
|
2881
3167
|
```ruby
|
2882
|
-
source
|
2883
|
-
gem 'sinatra', :
|
3168
|
+
source 'https://rubygems.org'
|
3169
|
+
gem 'sinatra', :github => 'sinatra/sinatra'
|
2884
3170
|
|
2885
3171
|
# другие зависимости
|
2886
|
-
gem 'haml' #
|
2887
|
-
gem 'activerecord', '~> 3.0' # может быть, вам нужен и ActiveRecord 3.x
|
3172
|
+
gem 'haml' # в том случае, если используете haml
|
2888
3173
|
```
|
2889
3174
|
|
2890
|
-
|
2891
|
-
в
|
2892
|
-
|
3175
|
+
Имейте ввиду, что вам необходимо будет указывать все зависимости вашего приложения
|
3176
|
+
в `Gemfile`. Необходимые зависимости самой библиотеки Sinatra (Rack и Tilt)
|
3177
|
+
будут автоматически скачаны и добавлены Bundler.
|
2893
3178
|
|
2894
|
-
Теперь вы можете запускать
|
3179
|
+
Теперь вы можете запускать своё приложение следующим образом:
|
2895
3180
|
|
2896
|
-
```
|
3181
|
+
```shell
|
2897
3182
|
bundle exec ruby myapp.rb
|
2898
3183
|
```
|
2899
3184
|
|
2900
|
-
### Вручную
|
2901
|
-
|
2902
|
-
Создайте локальный клон репозитория и запускайте свое приложение с
|
2903
|
-
`sinatra/lib` директорией в `$LOAD_PATH`:
|
2904
|
-
|
2905
|
-
```
|
2906
|
-
cd myapp
|
2907
|
-
git clone git://github.com/sinatra/sinatra.git
|
2908
|
-
ruby -Isinatra/lib myapp.rb
|
2909
|
-
```
|
2910
|
-
|
2911
|
-
Чтобы обновить исходники Sinatra:
|
2912
|
-
|
2913
|
-
```
|
2914
|
-
cd myapp/sinatra
|
2915
|
-
git pull
|
2916
|
-
```
|
2917
|
-
|
2918
|
-
### Установка глобально
|
2919
|
-
|
2920
|
-
Вы можете самостоятельно собрать gem:
|
2921
|
-
|
2922
|
-
```
|
2923
|
-
git clone git://github.com/sinatra/sinatra.git
|
2924
|
-
cd sinatra
|
2925
|
-
rake sinatra.gemspec
|
2926
|
-
rake install
|
2927
|
-
```
|
2928
|
-
|
2929
|
-
Если вы устанавливаете пакеты (gem) от пользователя root, то вашим последним
|
2930
|
-
шагом должна быть команда
|
2931
|
-
|
2932
|
-
```
|
2933
|
-
sudo rake install
|
2934
|
-
```
|
2935
|
-
|
2936
3185
|
## Версии
|
2937
3186
|
|
2938
|
-
Sinatra использует [Semantic Versioning](
|
3187
|
+
Sinatra использует [Semantic Versioning](https://semver.org/): как SemVer, так и
|
2939
3188
|
SemVerTag.
|
2940
3189
|
|
2941
3190
|
## Дальнейшее чтение
|
@@ -2946,11 +3195,11 @@ SemVerTag.
|
|
2946
3195
|
баг? Нужна помощь? Написали патч?
|
2947
3196
|
* [Отслеживание проблем/ошибок](https://github.com/sinatra/sinatra/issues)
|
2948
3197
|
* [Twitter](https://twitter.com/sinatra)
|
2949
|
-
* [Группы рассылки](
|
2950
|
-
* IRC: [#sinatra](irc://chat.freenode.net/#sinatra) на
|
3198
|
+
* [Группы рассылки](https://groups.google.com/forum/#!forum/sinatrarb)
|
3199
|
+
* IRC: [#sinatra](irc://chat.freenode.net/#sinatra) на [Freenode](https://freenode.net)
|
2951
3200
|
* [Sinatra и Друзья](https://sinatrarb.slack.com) на Slack, а так же
|
2952
|
-
[ссылка](https://sinatra-slack.herokuapp.com/)
|
2953
|
-
* [Sinatra Book](https://github.com/sinatra/sinatra-book
|
3201
|
+
[ссылка для инвайта](https://sinatra-slack.herokuapp.com/).
|
3202
|
+
* [Sinatra Book](https://github.com/sinatra/sinatra-book) учебник и сборник рецептов
|
2954
3203
|
* [Sinatra Recipes](http://recipes.sinatrarb.com/) сборник рецептов
|
2955
3204
|
* API документация к [последнему релизу](http://www.rubydoc.info/gems/sinatra)
|
2956
3205
|
или [текущему HEAD](http://www.rubydoc.info/github/sinatra/sinatra) на
|