sinatra 1.2.9 → 1.3.0.a

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sinatra might be problematic. Click here for more details.

@@ -18,6 +18,9 @@ Sinatra — это предметно-ориентированный язык (D
18
18
 
19
19
  Результат будет тут: http://localhost:4567
20
20
 
21
+ Рекомендуется также запустить <tt>gem install thin</tt>, чтобы Sinatra
22
+ могла использовать thin в качестве сервера.
23
+
21
24
  == Маршруты
22
25
 
23
26
  В Sinatra маршрут — это пара: HTTP метод и шаблон (образец) URL.
@@ -32,7 +35,11 @@ Sinatra — это предметно-ориентированный язык (D
32
35
  end
33
36
 
34
37
  put '/' do
35
- .. что-то обновить ..
38
+ .. что-то заменить ..
39
+ end
40
+
41
+ patch '/' do
42
+ .. что-то изменить ..
36
43
  end
37
44
 
38
45
  delete '/' do
@@ -61,7 +68,7 @@ Sinatra — это предметно-ориентированный язык (D
61
68
  end
62
69
 
63
70
  Шаблоны маршрутов также могут включать splat (wildcard, *, любая строка символов) параметры доступные
64
- в <tt>params[:splat]</tt> массиве.
71
+ в <tt>params[:splat]</tt> массиве:
65
72
 
66
73
  get '/say/*/to/*' do
67
74
  # соответствует /say/hello/to/world
@@ -147,6 +154,47 @@ Sinatra — это предметно-ориентированный язык (D
147
154
 
148
155
  get('/') { Stream.new }
149
156
 
157
+ === Собственные детекторы совпадений для маршрутов
158
+
159
+ Как показано выше, Sinatra поставляется со встроенной поддержкой строк и
160
+ регулярных выражений как шаблонов URL. Но и это еще не все. Вы можете
161
+ легко определить свои собственные детекторы совпадений (matchers) для маршрутов:
162
+
163
+ class AllButPattern
164
+ Match = Struct.new(:captures)
165
+
166
+ def initialize(except)
167
+ @except = except
168
+ @captures = Match.new([])
169
+ end
170
+
171
+ def match(str)
172
+ @captures unless @except === str
173
+ end
174
+ end
175
+
176
+ def all_but(pattern)
177
+ AllButPattern.new(pattern)
178
+ end
179
+
180
+ get all_but("/index") do
181
+ # ...
182
+ end
183
+
184
+ Заметьте, что предыдущий пример довольно переусложнен, ведь он также может
185
+ быть записан в следующем виде:
186
+
187
+ get // do
188
+ pass if request.path_info == "/index"
189
+ # ...
190
+ end
191
+
192
+ Или с использованием негативного просмотра вперед:
193
+
194
+ get %r{^(?!/index$)} do
195
+ # ...
196
+ end
197
+
150
198
  == Статические файлы
151
199
 
152
200
  Статические файлы отдаются из <tt>./public</tt> директории. Вы можете указать другое место,
@@ -362,7 +410,7 @@ Sinatra — это предметно-ориентированный язык (D
362
410
 
363
411
  Вы не можете вызывать Ruby из Markdown, соответственно, вы не можете использовать
364
412
  лэйаут-шаблоны (layouts) на Markdown. Тем не менее, есть возможность использовать один
365
- движок рендеринга для шаблона, а другой для лэйаута с помощью опции `:layout_engine`:
413
+ движок рендеринга для шаблона, а другой для лэйаута с помощью опции <tt>:layout_engine</tt>:
366
414
 
367
415
  get '/' do
368
416
  markdown :index, :layout_engine => :erb
@@ -421,7 +469,7 @@ Sinatra — это предметно-ориентированный язык (D
421
469
 
422
470
  Вы не можете вызывать Ruby из Textile, соответственно, вы не можете использовать
423
471
  лэйаут-шаблоны на Textile. Тем не менее, есть возможность использовать один
424
- движок рендеринга для шаблона, а другой для лэйаута с помощью опции `:layout_engine`:
472
+ движок рендеринга для шаблона, а другой для лэйаута с помощью опции <tt>:layout_engine</tt>:
425
473
 
426
474
  get '/' do
427
475
  textile :index, :layout_engine => :erb
@@ -466,7 +514,7 @@ Sinatra — это предметно-ориентированный язык (D
466
514
 
467
515
  Вы не можете вызывать Ruby из RDoc, соответственно, вы не можете использовать
468
516
  лэйаут-шаблоны на RDoc. Тем не менее, есть возможность использовать один
469
- движок рендеринга для шаблона, а другой для лэйаута с помощью опции `:layout_engine`:
517
+ движок рендеринга для шаблона, а другой для лэйаута с помощью опции <tt>:layout_engine</tt>:
470
518
 
471
519
  get '/' do
472
520
  rdoc :index, :layout_engine => :erb
@@ -604,7 +652,7 @@ Sinatra — это предметно-ориентированный язык (D
604
652
  @@ index
605
653
  %div.title Hello world!!!!!
606
654
 
607
- Заметьте: Вложенные шаблоны, определенные в файле-исходнике, который подключил Sinatra, будут
655
+ Заметьте: вложенные шаблоны, определенные в файле-исходнике, который подключил Sinatra, будут
608
656
  автоматически загружены. Вызовите <tt>enable :inline_templates</tt> напрямую, если у вас вложенные
609
657
  шаблоны в других файлах.
610
658
 
@@ -626,7 +674,7 @@ Sinatra — это предметно-ориентированный язык (D
626
674
 
627
675
  Если шаблон с именем "layout" существует, то он будет использован каждый раз,
628
676
  когда шаблоны будут отрисовываться. Вы можете отключать лэйаут в каждом конкретном случае с помощью
629
- <tt>:layout => false</tt> или отключить его для всего приложения, например, так: <tt>set :haml, :layout => false</tt>.
677
+ <tt>:layout => false</tt> или отключить его для всего приложения, например, так: <tt>set :haml, :layout => false</tt>:
630
678
 
631
679
  get '/' do
632
680
  haml :index, :layout => !request.xhr?
@@ -657,24 +705,9 @@ Sinatra — это предметно-ориентированный язык (D
657
705
  Отрисует <tt>./views/index.myat</tt>. Чтобы узнать больше о Tilt,
658
706
  смотрите https://github.com/rtomayko/tilt
659
707
 
660
- == Методы-помощники
661
-
662
- Используйте метод <tt>helpers</tt>, чтобы определить методы-помощники, которые
663
- в дальнейшем можно будет использовать в обработчиках маршрутов и шаблонах:
664
-
665
- helpers do
666
- def bar(name)
667
- "#{name}bar"
668
- end
669
- end
670
-
671
- get '/:name' do
672
- bar(params[:name])
673
- end
674
-
675
708
  == Фильтры
676
709
 
677
- Before-фильтры выполняются перед каждым запросом в том же контексте, что и маршруты. Фильтры могут изменять
710
+ +before+-фильтры выполняются перед каждым запросом в том же контексте, что и маршруты. Фильтры могут изменять
678
711
  как запрос, так и ответ на него. Переменные экземпляра, установленные в фильтрах, доступны в маршрутах и шаблонах:
679
712
 
680
713
  before do
@@ -687,13 +720,17 @@ Before-фильтры выполняются перед каждым запро
687
720
  params[:splat] #=> 'bar/baz'
688
721
  end
689
722
 
690
- After-фильтры выполняются после каждого запроса в том же контексте, что и пути. Фильтры могут изменять
691
- как запрос, так и ответ на него. Переменные экземпляра, установленные в before-фильтрах и маршрутах, будут доступны в after-фильтрах:
723
+ +after+-фильтры выполняются после каждого запроса в том же контексте, что и пути. Фильтры могут изменять
724
+ как запрос, так и ответ на него. Переменные экземпляра, установленные в +before+-фильтрах и маршрутах,
725
+ будут доступны в +after+-фильтрах:
692
726
 
693
727
  after do
694
728
  puts response.status
695
729
  end
696
730
 
731
+ Заметьте: если вы используете метод +body+, а не просто возвращаете строку из
732
+ маршрута, то тело ответа не будет доступно в +after+-фильтрах, потому что оно будет сгенерировано позднее.
733
+
697
734
  Фильтры могут использовать шаблоны URL и будут интерпретированы, только если путь запроса совпадет с этим шаблоном:
698
735
 
699
736
  before '/protected/*' do
@@ -714,7 +751,67 @@ After-фильтры выполняются после каждого запро
714
751
  # ...
715
752
  end
716
753
 
717
- == Прерывание
754
+ == Методы-помощники
755
+
756
+ Используйте метод <tt>helpers</tt>, чтобы определить методы-помощники, которые
757
+ в дальнейшем можно будет использовать в обработчиках маршрутов и шаблонах:
758
+
759
+ helpers do
760
+ def bar(name)
761
+ "#{name}bar"
762
+ end
763
+ end
764
+
765
+ get '/:name' do
766
+ bar(params[:name])
767
+ end
768
+
769
+ === Использование сессий
770
+
771
+ Сессия используется, чтобы сохранять состояние между запросами. Если эта опция
772
+ включена, то у вас будет один хэш сессии на одну пользовательскую сессию:
773
+
774
+ enable :sessions
775
+
776
+ get '/' do
777
+ "value = " << session[:value].inspect
778
+ end
779
+
780
+ get '/:value' do
781
+ session[:value] = params[:value]
782
+ end
783
+
784
+ Заметьте, что при использовании <tt>enable :sessions</tt> все данные
785
+ сохраняются в куки. Это может быть не совсем то, что вы хотите (например,
786
+ сохранение больших объемов данных увеличит ваш трафик). В таком случае вы
787
+ можете использовать альтернативную Rack "прослойку" (middleware), реализующую
788
+ механизм сессий. Для этого *не надо* вызывать <tt>enable :sessions</tt>,
789
+ вместо этого следует подключить ее также как и любую другую "прослойку":
790
+
791
+ use Rack::Session::Pool, :expire_after => 2592000
792
+
793
+ get '/' do
794
+ "value = " << session[:value].inspect
795
+ end
796
+
797
+ get '/:value' do
798
+ session[:value] = params[:value]
799
+ end
800
+
801
+ Для повышения безопасности данные сессии в куках подписываются секретным
802
+ ключом. Секретный ключ генерируется Sinatra. Тем не менее, так как этот
803
+ ключ будет меняться с каждым запуском приложения, вы, возможно, захотите
804
+ установить ключ вручную, чтобы у всех экземпляров вашего приложения
805
+ быд один и тот же ключ:
806
+
807
+ set :session_secret, 'super secret'
808
+
809
+ Если вы хотите больше настроек для сессий, вы можете задать их, используя
810
+ хэш с опциями и параметр +sessions+:
811
+
812
+ set :sessions, :domain => 'foo.com'
813
+
814
+ === Прерывание
718
815
 
719
816
  Чтобы незамедлительно прервать обработку запроса внутри фильтра или маршрута, используйте:
720
817
 
@@ -736,7 +833,11 @@ After-фильтры выполняются после каждого запро
736
833
 
737
834
  halt 402, {'Content-Type' => 'text/plain'}, 'revenge'
738
835
 
739
- == Передача
836
+ И, конечно, можно использовать шаблоны с +halt+:
837
+
838
+ halt erb(:error)
839
+
840
+ === Передача
740
841
 
741
842
  Маршрут может передать обработку запроса следующему совпадающему маршруту, используя <tt>pass</tt>:
742
843
 
@@ -752,10 +853,224 @@ After-фильтры выполняются после каждого запро
752
853
  Блок маршрута сразу же прерывается, и контроль переходит к следующему совпадающему маршруту.
753
854
  Если соответствующий маршрут не найден, то ответом на запрос будет 404.
754
855
 
755
- == Доспут к объекту запроса
856
+ === Вызов другого маршрута
857
+
858
+ Иногда +pass+ не подходит, например, если вы хотите получить результат
859
+ вызова другого обработчика маршрута. В таком случае просто используйте +call+:
860
+
861
+ get '/foo' do
862
+ status, headers, body = call request.env.merge("PATH_INFO" => '/bar')
863
+ [status, body.upcase]
864
+ end
865
+
866
+ get '/bar' do
867
+ "bar"
868
+ end
869
+
870
+ Заметьте, что в предыдущем примере можно облегчить тестирование и повысить
871
+ производительность, перенеся <tt>"bar"</tt> в метод-помощник, используемый
872
+ и в <tt>/foo</tt>, и в <tt>/bar</tt>.
873
+
874
+ Если вы хотите, чтобы запрос был отправлен в тот же экземпляр приложения, а не
875
+ в его копию, используйте <tt>call!</tt> вместо <tt>call</tt>.
876
+
877
+ Если хотите узнать больше о <tt>call</tt>, смотрите спецификацию Rack.
878
+
879
+ === Задание тела, кода и заголовков ответа
880
+
881
+ Хорошим тоном является установка кода состояния HTTP и тела ответа в возвращаемом
882
+ значении обработчика маршрута. Тем не менее, в некоторых ситуациях вам, возможно,
883
+ понадобится задать тело ответа в произвольной точке потока исполнения. Вы можете
884
+ сделать это с помощью метода-помощника +body+. Если вы задействуете метод +body+,
885
+ то вы можете использовать его и в дальнейшем, чтобы получить доступ к телу ответа.
886
+
887
+ get '/foo' do
888
+ body "bar"
889
+ end
890
+
891
+ after do
892
+ puts body
893
+ end
894
+
895
+ Также можно передать блок в метод +body+, который затем будет вызван
896
+ обработчиком Rack (такой подход может быть использован для реализации поточного
897
+ ответа, см. "Возвращаемые значения").
898
+
899
+ Аналогично вы можете установить код ответа и его заголовки:
900
+
901
+ get '/foo' do
902
+ status 418
903
+ headers \
904
+ "Allow" => "BREW, POST, GET, PROPFIND, WHEN"
905
+ "Refresh" => "Refresh: 20; http://www.ietf.org/rfc/rfc2324.txt"
906
+ body "I'm a tea pot!"
907
+ end
908
+
909
+ Как и +body+, методы +headers+ и +status+, вызванные без аргументов, возвращают
910
+ свои текущие значения.
911
+
912
+ === Mime-типы
913
+
914
+ Когда вы используете <tt>send_file</tt> или статические файлы, у вас могут быть mime-типы, которые Sinatra
915
+ не понимает по умолчанию. Используйте +mime_type+ для их регистрации по расширению файла:
916
+
917
+ mime_type :foo, 'text/foo'
918
+
919
+ Вы также можете использовать это в +content_type+ помощнике:
920
+
921
+ get '/' do
922
+ content_type :foo
923
+ "foo foo foo"
924
+ end
925
+
926
+ === Генерирование URL
927
+
928
+ Чтобы сформировать URL вам следует использовать метод +url+, например, в Haml:
929
+
930
+ %a{:href => url('/foo')} foo
931
+
932
+ Этот метод учитывает обратные прокси и маршрутизаторы Rack, если они присутствуют.
933
+
934
+ Наряду с +url+ вы можете использовать +to+ (смотрите пример ниже).
935
+
936
+ === Перенаправление (редирект)
937
+
938
+ Вы можете перенаправить браузер пользователя с помощью метода +redirect+:
939
+
940
+ get '/foo' do
941
+ redirect to('/bar')
942
+ end
943
+
944
+ Любые дополнительные параметры используются по аналогии с аргументами метода +halt+:
945
+
946
+ redirect to('/bar'), 303
947
+ redirect 'http://google.com', 'wrong place, buddy'
948
+
949
+ Вы также можете перенаправить пользователя обратно, на страницу с которой он пришел,
950
+ с помощью <tt>redirect back</tt>:
951
+
952
+ get '/foo' do
953
+ "<a href='/bar'>do something</a>"
954
+ end
955
+
956
+ get '/bar' do
957
+ do_something
958
+ redirect back
959
+ end
960
+
961
+ Чтобы передать какие-либо параметры вместе с перенаправлением, либо добавьте их в строку запроса:
962
+
963
+ redirect to('/bar?sum=42')
964
+
965
+ Либо используйте сессию:
966
+
967
+ enable :session
968
+
969
+ get '/foo' do
970
+ session[:secret] = 'foo'
971
+ redirect to('/bar')
972
+ end
973
+
974
+ get '/bar' do
975
+ session[:secret]
976
+ end
977
+
978
+ === Управление кэшированием
979
+
980
+ Установка корректных заголовков — основа правильного HTTP кэширования.
981
+
982
+ Вы можете легко выставить заголовок Cache-Control таким образом:
983
+
984
+ get '/' do
985
+ cache_control :public
986
+ "cache it!"
987
+ end
988
+
989
+ Совет: задавайте кэширование в +before+-фильтре:
990
+
991
+ before do
992
+ cache_control :public, :must_revalidate, :max_age => 60
993
+ end
994
+
995
+ Если вы используете метод +expires+ для задания соответствующего заголовка,
996
+ то <tt>Cache-Control</tt> будет выставлен автоматически:
997
+
998
+ before do
999
+ expires 500, :public, :must_revalidate
1000
+ end
1001
+
1002
+ Чтобы как следует использовать кэши, вам следует подумать об использовании
1003
+ +etag+ и +last_modified+. Рекомендуется использовать эти методы *до*
1004
+ выполнения "тяжелых" вычислений, так как они немедленно отправят ответ клиенту,
1005
+ если текущая версия уже есть в его кэше:
1006
+
1007
+ get '/article/:id' do
1008
+ @article = Article.find params[:id]
1009
+ last_modified @article.updated_at
1010
+ etag @article.sha1
1011
+ erb :article
1012
+ end
1013
+
1014
+ Так же вы можете использовать
1015
+ {weak ETag}[http://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation]:
1016
+
1017
+ etag @article.sha1, :weak
1018
+
1019
+ Эти методы-помощники не станут ничего кэшировать для вас, но они дадут
1020
+ необходимую информацию для вашего кэша. Если вы ищите легкое решение для
1021
+ кэширования, попробуйте {rack-cache}[http://rtomayko.github.com/rack-cache/]:
1022
+
1023
+ require "rack/cache"
1024
+ require "sinatra"
1025
+
1026
+ use Rack::Cache
1027
+
1028
+ get '/' do
1029
+ cache_control :public, :max_age => 36000
1030
+ sleep 5
1031
+ "hello"
1032
+ end
1033
+
1034
+ === Отправка файлов
1035
+
1036
+ Для отправки файлов пользователю вы можете использовать метод <tt>send_file</tt>:
1037
+
1038
+ get '/' do
1039
+ send_file 'foo.png'
1040
+ end
1041
+
1042
+ Этот метод имеет несколько опций:
1043
+
1044
+ send_file 'foo.png', :type => :jpg
1045
+
1046
+ Возможные опции:
1047
+
1048
+ [filename]
1049
+ имя файла, по умолчанию: реальное имя файла.
1050
+
1051
+ [last_modified]
1052
+ значение для заголовка Last-Modified, по умолчанию: mtime (время изменения) файла.
1053
+
1054
+ [type]
1055
+ тип файла, по умолчанию: угадывается по расширению файла.
1056
+
1057
+ [disposition]
1058
+ используется для заголовка Content-Disposition, возможные значения:
1059
+ +nil+ (по умолчанию), <tt>:attachment</tt> и <tt>:inline</tt>.
1060
+
1061
+ [length]
1062
+ значения для заголовка Content-Length, по умолчанию: размер файла.
1063
+
1064
+
1065
+ Этот метод будет использовать возможности Rack сервера для отправки файлов, если они
1066
+ доступны, а в противном случае, будет напрямую отдавать файл из Ruby процесса.
1067
+ Метод <tt>send_file</tt> также обеспечивает автоматическую обработку частичных (range)
1068
+ запросов с помощью Sinatra.
756
1069
 
757
- Объект входящего запроса доступен на уровне обработки запроса (в фильтрах, маршрутах, обработчиках ошибок)
758
- с помощью `request` метода:
1070
+ === Доспут к объекту запроса
1071
+
1072
+ Объект входящего запроса доступен на уровне обработки запроса (в фильтрах, маршрутах,
1073
+ обработчиках ошибок) с помощью <tt>request</tt> метода:
759
1074
 
760
1075
  # приложение запущено на http://example.com/example
761
1076
  get '/foo' do
@@ -772,14 +1087,15 @@ After-фильтры выполняются после каждого запро
772
1087
  request.get? # true (есть аналоги для других методов HTTP)
773
1088
  request.form_data? # false
774
1089
  request["SOME_HEADER"] # значение заголовка SOME_HEADER
775
- request.referer # источник запроса клиента либо '/'
1090
+ request.referrer # источник запроса клиента либо '/'
776
1091
  request.user_agent # user agent (используется для :agent условия)
777
1092
  request.cookies # хеш с куками браузера
778
1093
  request.xhr? # является ли запрос ajax запросом?
779
1094
  request.url # "http://example.com/example/foo"
780
1095
  request.path # "/example/foo"
781
1096
  request.ip # IP-адрес клиента
782
- request.secure? # false
1097
+ request.secure? # false (true, если запрос сделан через SSL)
1098
+ request.forwarded? # true (если сервер работает за обратным прокси)
783
1099
  request.env # "сырой" env хеш, полученный Rack
784
1100
  end
785
1101
 
@@ -799,16 +1115,86 @@ After-фильтры выполняются после каждого запро
799
1115
  "Hello #{data['name']}!"
800
1116
  end
801
1117
 
1118
+ === Вложения
1119
+
1120
+ Вы можете использовать метод +attachment+, чтобы сказать браузеру, что ответ
1121
+ сервера должен быть сохранен на диск, а не отображен:
1122
+
1123
+ get '/' do
1124
+ attachment
1125
+ "store it!"
1126
+ end
1127
+
1128
+ Вы также можете указать и имя файла:
1129
+
1130
+ get '/' do
1131
+ attachment "info.txt"
1132
+ "store it!"
1133
+ end
1134
+
1135
+ === Поиск шаблонов
1136
+
1137
+ Для поиска шаблонов и их последующего рендеринга используется метод <tt>find_template</tt>:
1138
+
1139
+ find_template settings.views, 'foo', Tilt[:haml] do |file|
1140
+ puts "could be #{file}"
1141
+ end
1142
+
1143
+ Это не очень-то полезный пример. Зато полезен тот факт, что вы можете переопределить
1144
+ этот метод, чтобы использовать свой собственный механизм поиска. Например, если вы
1145
+ хотите, чтобы можно было использовать несколько директорий с шаблонами:
1146
+
1147
+ set :views, ['views', 'templates']
1148
+
1149
+ helpers do
1150
+ def find_template(views, name, engine, &block)
1151
+ Array(views).each { |v| super(v, name, engine, &block) }
1152
+ end
1153
+ end
1154
+
1155
+ Другой пример, в котором используются разные директории для движков рендеринга:
1156
+
1157
+ set :views, :sass => 'views/sass', :haml => 'templates', :default => 'views'
1158
+
1159
+ helpers do
1160
+ def find_template(views, name, engine, &block)
1161
+ _, folder = views.detect { |k,v| engine == Tilt[k] }
1162
+ folder ||= views[:default]
1163
+ super(folder, name, engine, &block)
1164
+ end
1165
+ end
1166
+
1167
+ Вы можете легко вынести этот код в расширение и поделиться им с остальными!
1168
+
1169
+ Заметьте, что <tt>find_template</tt не проверяет, существует ли файл на самом деле,
1170
+ а вызывает заданный блок для всех возможных путей. Дело тут не в производительности,
1171
+ дело в том, что +render+ вызовет +break+, как только файл не будет найден.
1172
+ Содержимое и местонахождение шаблонов будет закэшировано, если приложение запущено не
1173
+ в режиме разработки. Вы должны помнить об этих нюансах, если пишите по-настоящему
1174
+ сумашедший метод.
1175
+
802
1176
  == Конфигурация
803
1177
 
804
1178
  Этот блок исполняется один раз при старте в любом окружении, режиме (environment):
805
1179
 
806
1180
  configure do
807
- ...
1181
+ # задание одной опции
1182
+ set :option, 'value'
1183
+
1184
+ # устанавливаем несколько опций
1185
+ set :a => 1, :b => 2
1186
+
1187
+ # то же самое, что и `set :option, true`
1188
+ enable :option
1189
+
1190
+ # то же самое, что и `set :option, false`
1191
+ disable :option
1192
+
1193
+ # у вас могут быть "динамические" опции с блоками
1194
+ set(:css_dir) { File.join(views, 'css') }
808
1195
  end
809
1196
 
810
- Будет запущено, когда окружение (RACK_ENV переменная) установлена в
811
- <tt>:production</tt>:
1197
+ Будет запущено, когда окружение (RACK_ENV переменная) <tt>:production</tt>:
812
1198
 
813
1199
  configure :production do
814
1200
  ...
@@ -820,9 +1206,104 @@ After-фильтры выполняются после каждого запро
820
1206
  ...
821
1207
  end
822
1208
 
1209
+ Вы можете получить доступ к этим опциям с помощью <tt>settings</tt>:
1210
+
1211
+ configure do
1212
+ set :foo, 'bar'
1213
+ end
1214
+
1215
+ get '/' do
1216
+ settings.foo? # => true
1217
+ settings.foo # => 'bar'
1218
+ ...
1219
+ end
1220
+
1221
+ === Доступные настройки
1222
+
1223
+ [absolute_redirects] если отключено, то Sinatra будет позволять использование
1224
+ относительных перенаправлений, тем не менее, Sinatra перестанет
1225
+ соответствовать RFC 2616 (HTTP 1.1), который разрешает только
1226
+ абсолютные перенаправления.
1227
+
1228
+ Включайте эту опцию, если ваше приложение работает за обратным прокси,
1229
+ который настроен не совсем корректно. Обратите внимание, метод +url+
1230
+ все равно будет генерировать абсолютные URL, если вы не передадите
1231
+ +false+ вторым аргументом.
1232
+
1233
+ Отключено по умолчанию.
1234
+
1235
+ [add_charsets] mime-типы, к которым метод <tt>content_type</tt> будет автоматически
1236
+ добавлять информацию о кодировке.
1237
+
1238
+ Вам следует добавлять значения к этой опции вместо ее переопределения:
1239
+
1240
+ settings.add_charsets << "application/foobar"
1241
+
1242
+ [app_file] главный файл приложения, используется для определения корневой директории
1243
+ проекта, директорий с шаблонами и статическими файлами, вложенных шаблонов.
1244
+
1245
+ [bind] используемый IP-адрес (по умолчанию: 0.0.0.0). Используется только
1246
+ встроенным сервером.
1247
+
1248
+ [default_encoding] кодировка, если неизвестна (по умолчанию: <tt>"utf-8"</tt>).
1249
+
1250
+ [dump_errors] отображать ошибки в логе.
1251
+
1252
+ [environment] текущее окружение, по умолчанию, значение <tt>ENV['RACK_ENV']</tt>
1253
+ или <tt>"development"</tt>, если <tt>ENV['RACK_ENV']</tt> не доступна.
1254
+
1255
+ [logging] использовать логгер.
1256
+
1257
+ [lock] создает блокировку для каждого запроса, которая гарантирует обработку
1258
+ только одного запроса в текущий момент времени в Ruby процессе.
1259
+
1260
+ Включайте, если ваше приложение не потоко-безопасно (thread-safe).
1261
+ Отключено по умолчанию.
1262
+
1263
+ [method_override] использовать "магический" параметр <tt>_method</tt>, чтобы позволить
1264
+ использование PUT/DELETE форм в браузерах, которые не поддерживают
1265
+ эти методы.
1266
+
1267
+ [port] порт, на котором будет работать сервер. Используется только
1268
+ встроенным сервером.
1269
+
1270
+ [prefixed_redirects] добавлять или нет параметр <tt>request.script_name</tt> к редиректам,
1271
+ если не задан абсолютный путь. Таким образом <tt>redirect '/foo'</tt>
1272
+ будет вести себя как <tt>redirect to('/foo')</tt>. Отключено по умолчанию.
1273
+
1274
+ [public] директория, откуда будут раздаваться статические файлы.
1275
+
1276
+ [reload_templates] перезагружать или нет шаблоны на каждый запрос.
1277
+ Включено в режиме разработки.
1278
+
1279
+ [root] корневая директория проекта.
1280
+
1281
+ [raise_errors] возбуждать исключения (будет останавливать приложение).
1282
+
1283
+ [run] если включено, Sinatra будет самостоятельно запускать веб-сервер.
1284
+ Не включайте, если используете rackup или аналогичные средства.
1285
+
1286
+ [running] работает ли сейчас встроенный сервер?
1287
+ Не меняйте эту опцию!
1288
+
1289
+ [server] сервер или список серверов, которые следует использовать в качестве
1290
+ встроенного сервера. По умолчанию: ['thin', 'mongrel', 'webrick'],
1291
+ порядок задает приоритет.
1292
+
1293
+ [sessions] включить сессии на основе кук (cookie).
1294
+
1295
+ [show_exceptions] показывать стек вызовов (stack trace) в браузере.
1296
+
1297
+ [static] должен ли Sinatra осуществлять раздачу статических файлов.
1298
+ Отключите, когда используете какой-либо веб-сервер для этой цели.
1299
+ Отключение значительно улучшит производительность приложения.
1300
+ Включено по умолчанию.
1301
+
1302
+ [views] директория с шаблонами.
1303
+
823
1304
  == Обработка ошибок
824
1305
 
825
- Обработчики ошибок исполняются в том же контексте, что и маршруты, before-фильтры, а это означает, что всякие
1306
+ Обработчики ошибок исполняются в том же контексте, что и маршруты, +before+-фильтры, а это означает, что всякие
826
1307
  прелести вроде <tt>haml</tt>, <tt>erb</tt>, <tt>halt</tt> и т.д. доступны и им.
827
1308
 
828
1309
  === NotFound
@@ -875,20 +1356,9 @@ After-фильтры выполняются после каждого запро
875
1356
  'Boom'
876
1357
  end
877
1358
 
878
- Sinatra устанавливает специальные <tt>not_found</tt> и <tt>error</tt> обработчики, когда запущена в режиме
1359
+ Sinatra устанавливает специальные <tt>not_found</tt> и <tt>error</tt> обработчики, когда запущен в режиме
879
1360
  разработки (окружение <tt>:development</tt>).
880
1361
 
881
- == Mime-типы
882
-
883
- Когда вы используете <tt>send_file</tt> или статические файлы, у вас могут быть mime-типы, которые Sinatra
884
- не понимает по умолчанию. Используйте +mime_type+ для их регистрации по расширению файла:
885
-
886
- mime_type :foo, 'text/foo'
887
-
888
- Вы также можете использовать это в +content_type+ помощнике:
889
-
890
- content_type :foo
891
-
892
1362
  == Rack "прослойки"
893
1363
 
894
1364
  Sinatra использует Rack[http://rack.rubyforge.org/], минимальный стандартный
@@ -984,14 +1454,42 @@ DSL верхнего уровня загрязняет пространство
984
1454
  в DSL верхнего уровня. Большинство приложений верхнего уровня могут быть
985
1455
  конвертированы в Sinatra::Base компоненты с помощью двух модификаций:
986
1456
 
987
- * Вы должны подключать +sinatra/base+ вместо +sinatra+,
988
- иначе все методы предоставляемые Sinatra будут импортированные в глобальное пространство имен.
1457
+ * Вы должны подключать <tt>sinatra/base</tt> вместо +sinatra+,
1458
+ иначе все методы предоставляемые Sinatra будут импортированы в глобальное пространство имен.
989
1459
  * Поместите все маршруты, обработчики ошибок, фильтры и опции в сабкласс Sinatra::Base.
990
1460
 
991
1461
  <tt>Sinatra::Base</tt> — это чистый лист. Большинство опций, включая встроенный сервер, по умолчанию отключены.
992
1462
  Смотрите {Опции и Конфигурация}[http://www.sinatrarb.com/configuration.html] для детальной информации
993
1463
  об опциях и их поведении.
994
1464
 
1465
+ === Модульные приложения против классических
1466
+
1467
+ Вопреки всеобщему убеждению в классическом стиле (самом простом) нет ничего плохого.
1468
+ Если этот стиль подходит вашему приложению, вы не обязаны переписывать его в модульное
1469
+ приложение.
1470
+
1471
+ У классического стиля есть всего два недостатка относительно модульного:
1472
+
1473
+ * У вас может быть только одно приложение Sinatra на Ruby процесс. Если вы планируете
1474
+ использовать больше, то переключайтесь на модульный стиль.
1475
+
1476
+ * Приложения, использующие классический стиль, добавляют методы к Object. Если вы
1477
+ планируете поставлять свое приложение в виде библиотеки/gem, то переключайтесь
1478
+ на модульный стиль.
1479
+
1480
+ Не существует причин, по которым вы не могли бы смешивать модульный и классический стили.
1481
+
1482
+ Переходя с одного стиля на другой, примите во внимание следующие изменения в настройках:
1483
+
1484
+ Опция Классический Модульный
1485
+
1486
+ app_file файл с приложением nil
1487
+ run $0 == app_file false
1488
+ logging true false
1489
+ method_override true false
1490
+ inline_templates true false
1491
+
1492
+
995
1493
  === Запуск модульных приложений
996
1494
 
997
1495
  Есть два общепринятых способа запускать модульные приложения: запуск напрямую с помощью <tt>run!</tt>:
@@ -1014,14 +1512,14 @@ DSL верхнего уровня загрязняет пространство
1014
1512
  Rack-совместимый сервер приложений.
1015
1513
 
1016
1514
  # config.ru
1017
- require './my_app'
1515
+ require 'my_app'
1018
1516
  run MyApp
1019
1517
 
1020
1518
  Запускаем:
1021
1519
 
1022
1520
  rackup -p 4567
1023
1521
 
1024
- === Запуск "классических" приложений с config.ru
1522
+ === Запуск классических приложений с config.ru
1025
1523
 
1026
1524
  Файл приложения:
1027
1525
 
@@ -1034,7 +1532,7 @@ Rack-совместимый сервер приложений.
1034
1532
 
1035
1533
  И соответствующий <tt>config.ru</tt>:
1036
1534
 
1037
- require './app'
1535
+ require 'app'
1038
1536
  run Sinatra::Application
1039
1537
 
1040
1538
  === Когда использовать config.ru?
@@ -1052,9 +1550,9 @@ Rack-совместимый сервер приложений.
1052
1550
 
1053
1551
  === Использование Sinatra в качестве "прослойки"
1054
1552
 
1055
- Не только сама Sinatra может использовать "прослойки" Rack, но и любое Sinatra приложение
1553
+ Не только сам Sinatra может использовать "прослойки" Rack, но и любое Sinatra приложение
1056
1554
  само может быть добавлено к любому Rack эндпоинту в качестве "прослойки". Этим эндпоинтом
1057
- может быть другое Sinatra приложение, или приложение, основанное на Rack (Rails/Ramaze/Camping/...).
1555
+ может быть другое Sinatra приложение, или приложение, основанное на Rack (Rails/Ramaze/Camping/...):
1058
1556
 
1059
1557
  require 'sinatra/base'
1060
1558
 
@@ -1096,11 +1594,11 @@ Rack-совместимый сервер приложений.
1096
1594
  используете DSL верхнего
1097
1595
  уровня (<tt>require 'sinatra'</tt>), то этим классом будет
1098
1596
  Sinatra::Application, иначе это будет сабкласс, который вы создали вручную.
1099
- На уровне класса вам будут доступны такие методы, как `get` или `before`, но вы
1100
- не сможете иметь доступ к объектам `request` или `session`, так как существует
1101
- только единый класс приложения для всех запросов.
1597
+ На уровне класса вам будут доступны такие методы, как +get+ или +before+, но вы
1598
+ не сможете иметь доступ к объектам +request+ или +session+, так как существует
1599
+ только один класс приложения для всех запросов.
1102
1600
 
1103
- Опции, созданные с помощью `set`, являются методами уровня класса:
1601
+ Опции, созданные с помощью +set+, являются методами уровня класса:
1104
1602
 
1105
1603
  class MyApp < Sinatra::Base
1106
1604
  # Я в области видимости приложения!
@@ -1116,21 +1614,21 @@ Sinatra::Application, иначе это будет сабкласс, котор
1116
1614
 
1117
1615
  * Тела вашего класса приложения
1118
1616
  * Методов, определенных расширениями
1119
- * Блока, переданного в `helpers`
1120
- * Блоков, использованных как значения для `set`
1617
+ * Блока, переданного в +helpers+
1618
+ * Блоков, использованных как значения для +set+
1121
1619
 
1122
1620
  Вы можете получить доступ к объекту области видимости (классу приложения) следующими способами:
1123
1621
 
1124
1622
  * объект, переданный блокам конфигурации (<tt>configure { |c| ... }</tt>)
1125
- * `settings` внутри области видимости запроса
1623
+ * +settings+ внутри области видимости запроса
1126
1624
 
1127
1625
  === Область видимости запроса/экземпляра
1128
1626
 
1129
1627
  Для каждого входящего запроса будет создан новый экземпляр вашего приложения,
1130
1628
  и все блоки обработчика будут запущены в этом контексте. В этой области
1131
- видимости вам доступны `request` и `session` объекты, вызовы методов
1132
- рендеринга, такие как `erb` или `haml`. Вы можете получить доступ к
1133
- области видимости приложения из контекста запроса, используя помощник `settings`:
1629
+ видимости вам доступны +request+ и +session+ объекты, вызовы методов
1630
+ рендеринга, такие как +erb+ или +haml+. Вы можете получить доступ к
1631
+ области видимости приложения из контекста запроса, используя помощник +settings+:
1134
1632
 
1135
1633
  class MyApp < Sinatra::Base
1136
1634
  # Я в области видимости приложения!
@@ -1160,14 +1658,14 @@ Sinatra::Application, иначе это будет сабкласс, котор
1160
1658
  Однако, оно не полностью на 100% ведет себя как область видимости класса,
1161
1659
  так как у вас нету привязки к классу: только методы, явно помеченные для
1162
1660
  делегирования, будут доступны, а переменных/состояний области видимости класса
1163
- не будет (иначе говоря, у вас будет другой `self` объект). Вы можете
1661
+ не будет (иначе говоря, у вас будет другой +self+ объект). Вы можете
1164
1662
  непосредственно добавить методы делегирования, используя
1165
1663
  <tt>Sinatra::Delegator.delegate :method_name</tt>.
1166
1664
 
1167
1665
  У вас будет контекст делегирования внутри:
1168
1666
 
1169
1667
  * Привязки верхнего уровня, если вы сделали <tt>require "sinatra"</tt>
1170
- * Объекта, расширенного с помощью примеси `Sinatra::Delegator`
1668
+ * Объекта, расширенного с помощью примеси <tt>Sinatra::Delegator</tt>
1171
1669
 
1172
1670
  Посмотрите сами в код: тут
1173
1671
  {Sinatra::Delegator примесь}[http://github.com/sinatra/sinatra/blob/ceac46f0bc129a6e994a06100aa854f606fe5992/lib/sinatra/base.rb#L1128]
@@ -1188,6 +1686,53 @@ Sinatra приложения могут быть запущены напряму
1188
1686
  -s # настроить rack сервер/обработчик (по умолчанию thin)
1189
1687
  -x # включить мьютекс (по умолчанию выключен)
1190
1688
 
1689
+ == Системные требования
1690
+
1691
+ Следующие версии Ruby официально поддерживаются:
1692
+
1693
+ [ Ruby 1.8.7 ]
1694
+ 1.8.7 полностью поддерживается, тем не менее, если вас ничто не держит на
1695
+ этой версии, рекомендуем обновиться до 1.9.2 или перейти на JRuby или Rubinius.
1696
+
1697
+ [ Ruby 1.9.2 ]
1698
+ 1.9.2 поддерживается и рекомендована. Заметьте, что Radius и Markaby
1699
+ пока несовместимы с 1.9.2. Не используйте 1.9.2p0, известно, что эта
1700
+ версия весьма не стабильна при использовании Sinatra.
1701
+
1702
+ [ Rubinius ]
1703
+ Rubinius официально поддерживается (Rubinius >= 1.2.3), все, включая все
1704
+ языки шаблонов, работает.
1705
+
1706
+ [ JRuby ]
1707
+ JRuby официально поддерживается (JRuby >= 1.6.0). Нет никаких проблем с
1708
+ использованием альтернативных шаблонов. Тем не менее, если вы выбираете
1709
+ JRuby, то, пожалуйста, посмотрите на JRuby Rack-сервера, так как Thin не
1710
+ поддерживается полностью на JRuby. Поддержка расширений на C в JRuby все
1711
+ еще экспериментальная, что на данный момент затрагивает только RDiscount.
1712
+
1713
+ <b>Ruby 1.8.6 больше не поддерживается.</b>
1714
+
1715
+ Мы также следим за новыми версиями Ruby.
1716
+
1717
+ Следующие реализации Ruby не поддерживаются официально, но известно, что на
1718
+ них запускается Sinatra:
1719
+
1720
+ * Старые версии JRuby и Rubinius
1721
+ * MacRuby, Maglev, IronRuby
1722
+ * Ruby 1.9.0 и 1.9.1
1723
+ * Ruby 1.8.6 с помощью {backports}[https://github.com/marcandre/backports/#readme]
1724
+
1725
+ То, что версия официально не поддерживается, означает, что, если что-то не
1726
+ работает на этой версии, а на поддерживаемой работает, то мы предполагаем,
1727
+ что это не наша проблема, а их.
1728
+
1729
+ Мы также запускаем наши CI-тесты на последней версии Ruby (предстоящий 1.9.3),
1730
+ но мы не можем ничего гарантировать, так как она постоянно развивается.
1731
+ Предполагается, что 1.9.3p0 будет поддерживаться.
1732
+
1733
+ Sinatra должен работать на любой операционной системе, поддерживаемой выбранной
1734
+ реализацией Ruby.
1735
+
1191
1736
  == На острие
1192
1737
 
1193
1738
  Если вы хотите использовать самый последний код Sinatra, не бойтесь запускать
@@ -1228,7 +1773,7 @@ Sinatra приложения могут быть запущены напряму
1228
1773
  === Вручную
1229
1774
 
1230
1775
  Создайте локальный клон репозитория и запускайте свое приложение с <tt>sinatra/lib</tt>
1231
- директорией в <tt>LOAD_PATH</tt>:
1776
+ директорией в <tt>$LOAD_PATH</tt>:
1232
1777
 
1233
1778
  cd myapp
1234
1779
  git clone git://github.com/sinatra/sinatra.git
@@ -1252,6 +1797,11 @@ Sinatra приложения могут быть запущены напряму
1252
1797
 
1253
1798
  sudo rake install
1254
1799
 
1800
+ == Версии
1801
+
1802
+ Sinatra использует {Semantic Versioning}[http://semver.org/], SemVer и
1803
+ SemVerTag.
1804
+
1255
1805
  == Дальнейшее чтение
1256
1806
 
1257
1807
  * {Вебсайт проекта}[http://www.sinatrarb.com/] - Дополнительная документация,