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