sinatra 1.3.0.e → 1.3.0.f
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.
- data/.travis.yml +16 -0
- data/CHANGES +77 -18
- data/Gemfile +43 -26
- data/README.de.rdoc +264 -88
- data/README.es.rdoc +241 -80
- data/README.fr.rdoc +206 -81
- data/README.hu.rdoc +2 -2
- data/README.jp.rdoc +2 -2
- data/README.pt-br.rdoc +2 -2
- data/README.pt-pt.rdoc +2 -2
- data/README.rdoc +169 -23
- data/README.ru.rdoc +373 -433
- data/README.zh.rdoc +5 -5
- data/Rakefile +8 -2
- data/lib/sinatra/base.rb +191 -46
- data/lib/sinatra/main.rb +1 -1
- data/lib/sinatra/showexceptions.rb +2 -2
- data/lib/sinatra/version.rb +1 -1
- data/sinatra.gemspec +7 -5
- data/test/contest.rb +62 -28
- data/test/filter_test.rb +2 -2
- data/test/helpers_test.rb +185 -12
- data/test/mapped_error_test.rb +25 -6
- data/test/nokogiri_test.rb +5 -6
- data/test/response_test.rb +10 -1
- data/test/result_test.rb +2 -2
- data/test/routing_test.rb +13 -0
- data/test/server_test.rb +3 -2
- data/test/settings_test.rb +98 -11
- data/test/slim_test.rb +15 -25
- data/test/static_test.rb +3 -3
- data/test/streaming_test.rb +100 -0
- metadata +82 -35
data/README.hu.rdoc
CHANGED
@@ -99,9 +99,9 @@ tervezhetők, így például az user agent karakterláncot alapul véve:
|
|
99
99
|
|
100
100
|
A statikus fájlok kiszolgálása a <tt>./public</tt> könyvtárból
|
101
101
|
történik, de természetesen más könyvtárat is megadhatsz erre a célra,
|
102
|
-
mégpedig a <tt>:
|
102
|
+
mégpedig a <tt>:public_folder</tt> kapcsoló beállításával:
|
103
103
|
|
104
|
-
set :
|
104
|
+
set :public_folder, File.dirname(__FILE__) + '/static'
|
105
105
|
|
106
106
|
Fontos mgejegyezni, hogy a nyilvános könyvtár neve nem szerepel az URL-ben.
|
107
107
|
A <tt>./public/css/style.css</tt> fájl az
|
data/README.jp.rdoc
CHANGED
@@ -153,9 +153,9 @@ Rackレスポンス、Rackボディオブジェクト、HTTPステータスコ
|
|
153
153
|
== 静的ファイル
|
154
154
|
|
155
155
|
静的ファイルは<tt>./public</tt>ディレクトリから配信されます。
|
156
|
-
<tt>:
|
156
|
+
<tt>:public_folder</tt>オプションを指定することで別の場所を指定することができます。
|
157
157
|
|
158
|
-
set :
|
158
|
+
set :public_folder, File.dirname(__FILE__) + '/static'
|
159
159
|
|
160
160
|
注意: この静的ファイル用のディレクトリ名はURL中に含まれません。
|
161
161
|
例えば、<tt>./public/css/style.css</tt>は<tt>http://example.com/css/style.css</tt>でアクセスできます。
|
data/README.pt-br.rdoc
CHANGED
@@ -95,9 +95,9 @@ Rotas podem incluir uma variedade de condições correspondes, tal como o agente
|
|
95
95
|
== Arquivos estáticos
|
96
96
|
|
97
97
|
Arquivos estáticos são disponibilizados a partir do diretório <tt>./public</tt>. Você pode especificar
|
98
|
-
um local diferente pela opção <tt>:
|
98
|
+
um local diferente pela opção <tt>:public_folder</tt>
|
99
99
|
|
100
|
-
set :
|
100
|
+
set :public_folder, File.dirname(__FILE__) + '/estatico'
|
101
101
|
|
102
102
|
Note que o nome do diretório público não é incluido na URL. Um arquivo
|
103
103
|
<tt>./public/css/style.css</tt> é disponibilizado como
|
data/README.pt-pt.rdoc
CHANGED
@@ -95,9 +95,9 @@ Rotas podem incluir uma variedade de condições correspondentes, por exemplo, o
|
|
95
95
|
== Arquivos estáticos
|
96
96
|
|
97
97
|
Arquivos estáticos são disponibilizados a partir do directório <tt>./public</tt>. Você pode especificar
|
98
|
-
um local diferente através da opção <tt>:
|
98
|
+
um local diferente através da opção <tt>:public_folder</tt>
|
99
99
|
|
100
|
-
set :
|
100
|
+
set :public_folder, File.dirname(__FILE__) + '/estatico'
|
101
101
|
|
102
102
|
Note que o nome do directório público não é incluido no URL. Um arquivo
|
103
103
|
<tt>./public/css/style.css</tt> é disponibilizado como
|
data/README.rdoc
CHANGED
@@ -98,6 +98,15 @@ Or with a block parameter:
|
|
98
98
|
"Hello, #{c}!"
|
99
99
|
end
|
100
100
|
|
101
|
+
Route patterns may have optional parameters:
|
102
|
+
|
103
|
+
get '/posts.?:format?' do
|
104
|
+
# matches "GET /posts" and any extension "GET /posts.json", "GET /posts.xml" etc.
|
105
|
+
end
|
106
|
+
|
107
|
+
By the way, unless you disable the path traversal attack protection (see below),
|
108
|
+
the request path might be modified before matching against your routes.
|
109
|
+
|
101
110
|
=== Conditions
|
102
111
|
|
103
112
|
Routes may include a variety of matching conditions, such as the user agent:
|
@@ -135,7 +144,25 @@ You can easily define your own conditions:
|
|
135
144
|
get '/win_a_car' do
|
136
145
|
"Sorry, you lost."
|
137
146
|
end
|
147
|
+
|
148
|
+
For a condition that takes multiple values use a splat:
|
138
149
|
|
150
|
+
set(:auth) do |*roles| # <- notice the splat here
|
151
|
+
condition do
|
152
|
+
unless logged_in? && roles.any? {|role| current_user.in_role? role }
|
153
|
+
redirect "/login/", 303
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
get "/my/account/", :auth => [:user, :admin] do
|
159
|
+
"Your Account Details"
|
160
|
+
end
|
161
|
+
|
162
|
+
get "/only/admin/", :auth => :admin do
|
163
|
+
"Only admins are allowed here!"
|
164
|
+
end
|
165
|
+
|
139
166
|
=== Return Values
|
140
167
|
|
141
168
|
The return value of a route block determines at least the response body passed
|
@@ -164,6 +191,9 @@ That way we can, for instance, easily implement a streaming example:
|
|
164
191
|
|
165
192
|
get('/') { Stream.new }
|
166
193
|
|
194
|
+
You can also use the +stream+ helper method (described below) to reduce boiler
|
195
|
+
plate and embed the streaming logic in the route.
|
196
|
+
|
167
197
|
=== Custom Route Matchers
|
168
198
|
|
169
199
|
As shown above, Sinatra ships with built-in support for using String patterns
|
@@ -208,9 +238,9 @@ Or, using negative look ahead:
|
|
208
238
|
== Static Files
|
209
239
|
|
210
240
|
Static files are served from the <tt>./public</tt> directory. You can specify
|
211
|
-
a different location by setting the <tt>:
|
241
|
+
a different location by setting the <tt>:public_folder</tt> option:
|
212
242
|
|
213
|
-
set :
|
243
|
+
set :public_folder, File.dirname(__FILE__) + '/static'
|
214
244
|
|
215
245
|
Note that the public directory name is not included in the URL. A file
|
216
246
|
<tt>./public/css/style.css</tt> is made available as
|
@@ -291,7 +321,7 @@ Available Options:
|
|
291
321
|
[layout_engine]
|
292
322
|
Template engine to use for rendering the layout. Useful for languages that
|
293
323
|
do not support layouts otherwise. Defaults to the engine used for the
|
294
|
-
|
324
|
+
template. Example: <tt>set :rdoc, :layout_engine => :erb</tt>
|
295
325
|
|
296
326
|
Templates are assumed to be located directly under the <tt>./views</tt>
|
297
327
|
directory. To use a different views directory:
|
@@ -418,7 +448,7 @@ template than for the layout by passing the <tt>:layout_engine</tt> option.
|
|
418
448
|
|
419
449
|
Dependency:: {rdoc}[http://rdoc.rubyforge.org/]
|
420
450
|
File Extensions:: <tt>.rdoc</tt>
|
421
|
-
Example:: <tt>
|
451
|
+
Example:: <tt>rdoc :README, :layout_engine => :erb</tt>
|
422
452
|
|
423
453
|
It is not possible to call methods from rdoc, nor to pass locals to it. You
|
424
454
|
therefore will usually use it in combination with another rendering engine:
|
@@ -668,7 +698,7 @@ Note that <tt>enable :sessions</tt> actually stores all data in a cookie. This
|
|
668
698
|
might not always be what you want (storing lots of data will increase your
|
669
699
|
traffic, for instance). You can use any Rack session middleware: in order to
|
670
700
|
do so, do *not* call <tt>enable :sessions</tt>, but instead pull in your
|
671
|
-
middleware of choice
|
701
|
+
middleware of choice as you would any other middleware:
|
672
702
|
|
673
703
|
use Rack::Session::Pool, :expire_after => 2592000
|
674
704
|
|
@@ -781,7 +811,7 @@ Similar to the body, you can also set the status code and headers:
|
|
781
811
|
get '/foo' do
|
782
812
|
status 418
|
783
813
|
headers \
|
784
|
-
"Allow" => "BREW, POST, GET, PROPFIND, WHEN"
|
814
|
+
"Allow" => "BREW, POST, GET, PROPFIND, WHEN",
|
785
815
|
"Refresh" => "Refresh: 20; http://www.ietf.org/rfc/rfc2324.txt"
|
786
816
|
body "I'm a tea pot!"
|
787
817
|
end
|
@@ -789,6 +819,54 @@ Similar to the body, you can also set the status code and headers:
|
|
789
819
|
Like +body+, +headers+ and +status+ with no arguments can be used to access
|
790
820
|
their current values.
|
791
821
|
|
822
|
+
=== Streaming Responses
|
823
|
+
|
824
|
+
Sometimes you want to start sending out data while still generating parts of
|
825
|
+
the response body. In extreme examples, you want to keep sending data until
|
826
|
+
the client closes the connection. You can use the +stream+ helper to avoid
|
827
|
+
creating your own wrapper:
|
828
|
+
|
829
|
+
get '/' do
|
830
|
+
stream do |out|
|
831
|
+
out << "It's gonna be legen -\n"
|
832
|
+
sleep 0.5
|
833
|
+
out << " (wait for it) \n"
|
834
|
+
sleep 1
|
835
|
+
out << "- dary!\n"
|
836
|
+
end
|
837
|
+
end
|
838
|
+
|
839
|
+
This allows you to implement streaming APIs,
|
840
|
+
{Server Sent Events}[http://dev.w3.org/html5/eventsource/] and can be used as
|
841
|
+
basis for {WebSockets}[http://en.wikipedia.org/wiki/WebSocket]. It can also be
|
842
|
+
used to increase throughput if some but not all content depends on a slow
|
843
|
+
resource.
|
844
|
+
|
845
|
+
Note that the streaming behavior, especially the number of concurrent request,
|
846
|
+
highly depends on the web server used to serve the application. Some servers,
|
847
|
+
like WEBRick, might not even support streaming at all. If the server does not
|
848
|
+
support streaming, the body will be sent all at once after the block passed to
|
849
|
+
+stream+ finished executing.
|
850
|
+
|
851
|
+
If the optional parameter is set to +keep_open+, it will not call +close+ on
|
852
|
+
the stream object, allowing you to close it at any later point in the
|
853
|
+
execution flow. This only works on evented servers, like Thin and Rainbows.
|
854
|
+
Other servers will still close the stream:
|
855
|
+
|
856
|
+
set :server, :thin
|
857
|
+
connections = []
|
858
|
+
|
859
|
+
get '/' do
|
860
|
+
# keep stream open
|
861
|
+
stream(:keep_open) { |out| connections << out }
|
862
|
+
end
|
863
|
+
|
864
|
+
post '/' do
|
865
|
+
# write to all open streams
|
866
|
+
connections.each { |out| out << params[:message] << "\n" }
|
867
|
+
"message sent"
|
868
|
+
end
|
869
|
+
|
792
870
|
=== Logging
|
793
871
|
|
794
872
|
In the request scope, the +logger+ helper exposes a +Logger+ instance:
|
@@ -870,7 +948,7 @@ To pass arguments with a redirect, either add them to the query:
|
|
870
948
|
|
871
949
|
Or use a session:
|
872
950
|
|
873
|
-
enable :
|
951
|
+
enable :sessions
|
874
952
|
|
875
953
|
get '/foo' do
|
876
954
|
session[:secret] = 'foo'
|
@@ -905,7 +983,7 @@ If you are using the +expires+ helper to set the corresponding header,
|
|
905
983
|
expires 500, :public, :must_revalidate
|
906
984
|
end
|
907
985
|
|
908
|
-
To properly use caches, you should consider using +etag+
|
986
|
+
To properly use caches, you should consider using +etag+ or +last_modified+.
|
909
987
|
It is recommended to call those helpers *before* doing heavy lifting, as they
|
910
988
|
will immediately flush a response if the client already has the current
|
911
989
|
version in its cache:
|
@@ -923,7 +1001,7 @@ It is also possible to use a
|
|
923
1001
|
etag @article.sha1, :weak
|
924
1002
|
|
925
1003
|
These helpers will not do any caching for you, but rather feed the necessary
|
926
|
-
information to your cache. If you are looking for a quick caching
|
1004
|
+
information to your cache. If you are looking for a quick reverse-proxy caching solution,
|
927
1005
|
try {rack-cache}[http://rtomayko.github.com/rack-cache/]:
|
928
1006
|
|
929
1007
|
require "rack/cache"
|
@@ -1044,6 +1122,37 @@ You can also pass it a file name:
|
|
1044
1122
|
"store it!"
|
1045
1123
|
end
|
1046
1124
|
|
1125
|
+
=== Dealing with Date and Time
|
1126
|
+
|
1127
|
+
Sinatra offers a +time_for+ helper method, which, from the given value
|
1128
|
+
generates a Time object. It is also able to convert +DateTime+, +Date+ and
|
1129
|
+
similar classes:
|
1130
|
+
|
1131
|
+
get '/' do
|
1132
|
+
pass if Time.now > time_for('Dec 23, 2012')
|
1133
|
+
"still time"
|
1134
|
+
end
|
1135
|
+
|
1136
|
+
This method is used internally by +expires+, +last_modified+ and akin. You can
|
1137
|
+
therefore easily extend the behavior of those methods by overriding +time_for+
|
1138
|
+
in your application:
|
1139
|
+
|
1140
|
+
helpers do
|
1141
|
+
def time_for(value)
|
1142
|
+
case value
|
1143
|
+
when :yesterday then Time.now - 24*60*60
|
1144
|
+
when :tomorrow then Time.now + 24*60*60
|
1145
|
+
else super
|
1146
|
+
end
|
1147
|
+
end
|
1148
|
+
end
|
1149
|
+
|
1150
|
+
get '/' do
|
1151
|
+
last_modified :yesterday
|
1152
|
+
expires :tomorrow
|
1153
|
+
"hello"
|
1154
|
+
end
|
1155
|
+
|
1047
1156
|
=== Looking Up Template Files
|
1048
1157
|
|
1049
1158
|
The <tt>find_template</tt> helper is used to find template files for rendering:
|
@@ -1132,6 +1241,23 @@ You can access those options via <tt>settings</tt>:
|
|
1132
1241
|
...
|
1133
1242
|
end
|
1134
1243
|
|
1244
|
+
=== Configuring attack protection
|
1245
|
+
|
1246
|
+
Sinatra is using
|
1247
|
+
{Rack::Protection}[https://github.com/rkh/rack-protection#readme] to defend
|
1248
|
+
you application against common, opportunistic attacks. You can easily disable
|
1249
|
+
this behavior (which should result in performance gains):
|
1250
|
+
|
1251
|
+
disable :protection
|
1252
|
+
|
1253
|
+
To skip a single defense layer, set +protection+ to an options hash:
|
1254
|
+
|
1255
|
+
set :protection, :except => :path_traversal
|
1256
|
+
|
1257
|
+
You can also hand in an array in order to disable a list of protections:
|
1258
|
+
|
1259
|
+
set :protections, :except => [:path_traversal, :session_hijacking]
|
1260
|
+
|
1135
1261
|
=== Available Settings
|
1136
1262
|
|
1137
1263
|
[absolute_redirects] If disabled, Sinatra will allow relative redirects,
|
@@ -1184,7 +1310,10 @@ You can access those options via <tt>settings</tt>:
|
|
1184
1310
|
<tt>redirect '/foo'</tt> would behave like
|
1185
1311
|
<tt>redirect to('/foo')</tt>. Disabled per default.
|
1186
1312
|
|
1187
|
-
[
|
1313
|
+
[protection] Whether or not to enable web attack protections. See
|
1314
|
+
protection section above.
|
1315
|
+
|
1316
|
+
[public_folder] folder public files are served from
|
1188
1317
|
|
1189
1318
|
[reload_templates] whether or not to reload templates between requests.
|
1190
1319
|
Enabled in development mode.
|
@@ -1219,6 +1348,9 @@ You can access those options via <tt>settings</tt>:
|
|
1219
1348
|
Use an explicit array when setting multiple values:
|
1220
1349
|
<tt>set :static_cache_control, [:public, :max_age => 300]</tt>
|
1221
1350
|
|
1351
|
+
[threaded] If set to +true+, will tell Thin to use
|
1352
|
+
<tt>EventMachine.defer</tt> for processing the request.
|
1353
|
+
|
1222
1354
|
[views] views folder.
|
1223
1355
|
|
1224
1356
|
== Error Handling
|
@@ -1523,6 +1655,7 @@ assign them to a constant, you can do this with <tt>Sinatra.new</tt>:
|
|
1523
1655
|
|
1524
1656
|
It takes the application to inherit from as optional argument:
|
1525
1657
|
|
1658
|
+
# config.ru
|
1526
1659
|
require 'sinatra/base'
|
1527
1660
|
|
1528
1661
|
controller = Sinatra.new do
|
@@ -1659,47 +1792,59 @@ The following Ruby versions are officially supported:
|
|
1659
1792
|
|
1660
1793
|
[ Ruby 1.8.7 ]
|
1661
1794
|
1.8.7 is fully supported, however, if nothing is keeping you from it, we
|
1662
|
-
recommend upgrading to 1.9.2 or switching to JRuby or Rubinius.
|
1795
|
+
recommend upgrading to 1.9.2 or switching to JRuby or Rubinius. Support for
|
1796
|
+
1.8.7 will not be dropped before Sinatra 2.0 and Ruby 2.0 except maybe for
|
1797
|
+
the unlikely event of 1.8.8 being released. Even then, we might continue
|
1798
|
+
supporting it. <b>Ruby 1.8.6 is no longer supported.</b> If you want to run
|
1799
|
+
with 1.8.6, downgrade to Sinatra 1.2, which will receive bug fixes until
|
1800
|
+
Sinatra 1.4.0 is released.
|
1663
1801
|
|
1664
1802
|
[ Ruby 1.9.2 ]
|
1665
|
-
1.9.2 is supported and recommended. Note that Radius and Markaby
|
1666
|
-
currently not 1.9 compatible. Do not use 1.9.2p0, it is known to cause
|
1667
|
-
segmentation faults when running Sinatra.
|
1803
|
+
1.9.2 is fully supported and recommended. Note that Radius and Markaby
|
1804
|
+
are currently not 1.9 compatible. Do not use 1.9.2p0, it is known to cause
|
1805
|
+
segmentation faults when running Sinatra. Support will continue at least
|
1806
|
+
until the release of Ruby 1.9.4/2.0 and support for the latest 1.9 release
|
1807
|
+
will continue as long as it is still supported by the Ruby core team.
|
1808
|
+
|
1809
|
+
[ Ruby 1.9.3 ]
|
1810
|
+
While we test against 1.9.3 we do not know of anyone using it in
|
1811
|
+
production yet, and as with 1.9.2, you might want to be careful with
|
1812
|
+
patch level zero.
|
1668
1813
|
|
1669
1814
|
[ Rubinius ]
|
1670
|
-
Rubinius is officially supported (Rubinius >= 1.2.
|
1815
|
+
Rubinius is officially supported (Rubinius >= 1.2.4), everything, including
|
1671
1816
|
all template languages, works.
|
1672
1817
|
|
1673
1818
|
[ JRuby ]
|
1674
|
-
JRuby is officially supported (JRuby >= 1.6.
|
1819
|
+
JRuby is officially supported (JRuby >= 1.6.3). No issues with third party
|
1675
1820
|
template libraries are known, however, if you choose to use JRuby, please
|
1676
1821
|
look into JRuby rack handlers, as the Thin web server is not fully supported
|
1677
1822
|
on JRuby. JRuby's support for C extensions is still experimental, which only
|
1678
1823
|
affects RDiscount and Redcarpet at the moment.
|
1679
1824
|
|
1680
|
-
<b>Ruby 1.8.6 is no longer supported.</b> If you want to run with 1.8.6,
|
1681
|
-
downgrade to Sinatra 1.2, which will receive bug fixes until Sinatra 1.4.0 is
|
1682
|
-
released.
|
1683
|
-
|
1684
1825
|
We also keep an eye on upcoming Ruby versions.
|
1685
1826
|
|
1686
1827
|
The following Ruby implementations are not officially supported but still are
|
1687
1828
|
known to run Sinatra:
|
1688
1829
|
|
1689
1830
|
* Older versions of JRuby and Rubinius
|
1831
|
+
* Ruby Enterprise Edition
|
1690
1832
|
* MacRuby, Maglev, IronRuby
|
1691
|
-
* Ruby 1.9.0 and 1.9.1
|
1833
|
+
* Ruby 1.9.0 and 1.9.1 (but we do recommend against using those)
|
1692
1834
|
|
1693
1835
|
Not being officially supported means if things only break there and not on a
|
1694
1836
|
supported platform, we assume it's not our issue but theirs.
|
1695
1837
|
|
1696
|
-
We also run our CI against ruby-head (the upcoming 1.9.
|
1697
|
-
guarantee anything, since it is constantly moving. Expect 1.9.
|
1838
|
+
We also run our CI against ruby-head (the upcoming 1.9.4), but we can't
|
1839
|
+
guarantee anything, since it is constantly moving. Expect 1.9.4p0 to be
|
1698
1840
|
supported.
|
1699
1841
|
|
1700
1842
|
Sinatra should work on any operating system supported by the chosen Ruby
|
1701
1843
|
implementation.
|
1702
1844
|
|
1845
|
+
You will not be able to run Sinatra on Cardinal, SmallRuby, BlueRuby or any
|
1846
|
+
Ruby version prior to 1.8.7 as of the time being.
|
1847
|
+
|
1703
1848
|
== The Bleeding Edge
|
1704
1849
|
|
1705
1850
|
If you would like to use Sinatra's latest bleeding code, feel free to run your
|
@@ -1785,3 +1930,4 @@ SemVerTag.
|
|
1785
1930
|
* API documentation for the {latest release}[http://rubydoc.info/gems/sinatra]
|
1786
1931
|
or the {current HEAD}[http://rubydoc.info/github/sinatra/sinatra] on
|
1787
1932
|
http://rubydoc.info
|
1933
|
+
* {CI server}[http://ci.rkh.im/view/Sinatra/]
|
data/README.ru.rdoc
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
= Sinatra
|
2
|
-
<i>Внимание: Этот документ является переводом
|
2
|
+
<i>Внимание: Этот документ является переводом английской версии и может быть устаревшим</i>
|
3
3
|
|
4
4
|
Sinatra — это предметно-ориентированный каркас (DSL) для быстрого создания функциональных веб-приложений на Ruby:
|
5
5
|
|
@@ -52,7 +52,8 @@ Thin - это более производительный и функциона
|
|
52
52
|
.. что-то ответить ..
|
53
53
|
end
|
54
54
|
|
55
|
-
Маршруты сверяются с запросом в порядке очередности их записи в файле приложения. По
|
55
|
+
Маршруты сверяются с запросом в порядке очередности их записи в файле приложения. По умолчанию
|
56
|
+
будет вызван первый совпавший с запросом маршрут.
|
56
57
|
|
57
58
|
Шаблоны маршрутов могут включать в себя параметры доступные в
|
58
59
|
<tt>params</tt> xэше:
|
@@ -82,6 +83,12 @@ Thin - это более производительный и функциона
|
|
82
83
|
params[:splat] # => ["path/to/file", "xml"]
|
83
84
|
end
|
84
85
|
|
86
|
+
Или с параметрами блока:
|
87
|
+
|
88
|
+
get '/download/*.*' do |path, ext|
|
89
|
+
[path, ext] # => ["path/to/file", "xml"]
|
90
|
+
end
|
91
|
+
|
85
92
|
Маршруты также могут содержать регулярные выражения:
|
86
93
|
|
87
94
|
get %r{/hello/([\w]+)} do
|
@@ -138,7 +145,8 @@ Thin - это более производительный и функциона
|
|
138
145
|
или следующей "прослойкой" (middleware) в Rack стеке. Чаще всего это строка, как в примерах выше.
|
139
146
|
Но и другие значения также приемлемы.
|
140
147
|
|
141
|
-
Вы можете вернуть любой объект, который будет либо корректным Rack ответом, объектом Rack body,
|
148
|
+
Вы можете вернуть любой объект, который будет либо корректным Rack ответом, объектом Rack body,
|
149
|
+
либо кодом состояния HTTP:
|
142
150
|
|
143
151
|
* массив с тремя переменными: <tt>[status (Fixnum), headers (Hash), response body (должен отвечать на #each)]</tt>;
|
144
152
|
* массив с двумя переменными: <tt>[status (Fixnum), response body (должен отвечать на #each)]</tt>;
|
@@ -198,208 +206,177 @@ Thin - это более производительный и функциона
|
|
198
206
|
== Статические файлы
|
199
207
|
|
200
208
|
Статические файлы отдаются из <tt>./public</tt> директории. Вы можете указать другое место,
|
201
|
-
указав его через опцию <tt>:
|
209
|
+
указав его через опцию <tt>:public_folder</tt>:
|
202
210
|
|
203
|
-
set :
|
211
|
+
set :public_folder, File.dirname(__FILE__) + '/static'
|
204
212
|
|
205
213
|
Учтите, что имя директории со статическими файлами не включено в URL. Например, файл
|
206
214
|
<tt>./public/css/style.css</tt> будет доступен как
|
207
215
|
<tt>http://example.com/css/style.css</tt>.
|
208
216
|
|
209
|
-
|
210
|
-
|
211
|
-
Шаблоны по умолчанию должны находиться в директории <tt>./views</tt>.
|
212
|
-
Для использования другой директории шаблонов:
|
217
|
+
Используйте опцию <tt>:static_cache_control</tt> (см. ниже), чтобы
|
218
|
+
добавить заголовок <tt>Cache-Control</tt>.
|
213
219
|
|
214
|
-
|
215
|
-
|
216
|
-
Важно помнить, что вы всегда должны указывать шаблоны
|
217
|
-
с помощью символов, даже если это подкаталог (в этом случае
|
218
|
-
используйте <tt>:'subdir/template'</tt>). Вы должны использовать
|
219
|
-
символ, иначе методы рендеринга, отобразят просто переданную им строку.
|
220
|
-
|
221
|
-
=== Haml шаблоны
|
222
|
-
|
223
|
-
<tt>haml</tt> gem/библиотека необходима для рендеринга HAML шаблонов:
|
220
|
+
== Представления / Шаблоны
|
224
221
|
|
225
|
-
|
226
|
-
|
222
|
+
Каждый шаблонизатор представлен своим собственным методом. Эти методы
|
223
|
+
попросту возвращают строку:
|
227
224
|
|
228
225
|
get '/' do
|
229
|
-
|
226
|
+
erb :index
|
230
227
|
end
|
231
228
|
|
232
|
-
Отобразит <tt
|
233
|
-
|
234
|
-
{Опции Haml}[http://haml-lang.com/docs/yardoc/file.HAML_REFERENCE.html#options]
|
235
|
-
могут быть установлены глобально через конфигурацию Sinatra,
|
236
|
-
см. {Опции и Конфигурация}[http://www.sinatrarb.com/configuration.html],
|
237
|
-
и переопределены локально.
|
229
|
+
Отобразит <tt>views/index.erb</tt>.
|
238
230
|
|
239
|
-
|
231
|
+
Вместо имени шаблона вы так же можете передавать непосредственно само
|
232
|
+
содержимое шаблона
|
240
233
|
|
241
234
|
get '/' do
|
242
|
-
|
235
|
+
code = "<%= Time.now >"
|
236
|
+
erb code
|
243
237
|
end
|
244
238
|
|
245
|
-
|
246
|
-
=== Erb шаблоны
|
247
|
-
|
248
|
-
# Вам нужно будет подключить erb в приложении
|
249
|
-
require 'erb'
|
239
|
+
Эти методы принимают второй аргумент, хеш с опциями:
|
250
240
|
|
251
241
|
get '/' do
|
252
|
-
erb :index
|
242
|
+
erb :index, :layout => :post
|
253
243
|
end
|
254
244
|
|
255
|
-
Отобразит <tt
|
256
|
-
|
257
|
-
=== Erubis шаблоны
|
245
|
+
Отобразит <tt>views/index.erb</tt>, вложенным в
|
246
|
+
<tt>views/post.erb</tt> (по умолчанию: <tt>views/layout.erb</tt>, если существует).
|
258
247
|
|
259
|
-
|
260
|
-
|
261
|
-
# Вам нужно будет подключить Erubis в приложении
|
262
|
-
require 'erubis'
|
248
|
+
Любые опции, не понимаемые Sinatra, будут переданы в шаблонизатор
|
263
249
|
|
264
250
|
get '/' do
|
265
|
-
|
251
|
+
haml :index, :format => :html5
|
266
252
|
end
|
267
253
|
|
268
|
-
|
269
|
-
|
270
|
-
Также возможно заменить Erb на Erubis:
|
254
|
+
Вы также можете задавать опции для шаблонизаторов в общем:
|
271
255
|
|
272
|
-
|
273
|
-
Tilt.register :erb, Tilt[:erubis]
|
256
|
+
set :haml, :format => :html5
|
274
257
|
|
275
258
|
get '/' do
|
276
|
-
|
259
|
+
haml :index
|
277
260
|
end
|
278
261
|
|
279
|
-
|
262
|
+
Опции, переданные в метод, переопределяют опции, заданные с помощью
|
263
|
+
+set+.
|
280
264
|
|
281
|
-
|
265
|
+
Доступные опции:
|
282
266
|
|
283
|
-
|
267
|
+
[locals]
|
268
|
+
Список локальных переменных, передаваемых в документ.
|
269
|
+
Например: <tt>erb "<%= foo %>", :locals => {:foo => "bar"}</tt>
|
284
270
|
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
get '/' do
|
289
|
-
builder :index
|
290
|
-
end
|
271
|
+
[default_encoding]
|
272
|
+
Кодировка, которую следует использовать, если не удалось определить
|
273
|
+
оригинальную. По умолчанию: <tt>settings.default_encoding</tt>.
|
291
274
|
|
292
|
-
|
275
|
+
[views]
|
276
|
+
Директория с шаблонами. По умолчанию: <tt>settings.views</tt>.
|
293
277
|
|
294
|
-
|
278
|
+
[layout]
|
279
|
+
Использовать или нет лэйаут (+true+ или +false+). Если же значение Symbol,
|
280
|
+
то указывает, какой шаблон использовать в качестве лэйаута. Например:
|
281
|
+
<tt>erb :index, :layout => !request.xhr?</tt>
|
295
282
|
|
296
|
-
|
283
|
+
[content_type]
|
284
|
+
Content-Type отображенного шаблона. По умолчанию: задается шаблонизатором.
|
297
285
|
|
298
|
-
|
299
|
-
|
286
|
+
[scope]
|
287
|
+
Область видимости, в которой рендерятся шаблоны. По умолчанию: экземпляр
|
288
|
+
приложения. Если вы измените эту опцию, то переменные экземпляра и
|
289
|
+
методы-помощники станут недоступными в ваших шаблонах.
|
300
290
|
|
301
|
-
|
302
|
-
|
303
|
-
|
291
|
+
[layout_engine]
|
292
|
+
Шаблонизатор, который следует использовать для отображения лэйаута. Полезная
|
293
|
+
опция для шаблонизаторов, в которых нет никакой поддержки лэйаутов. По
|
294
|
+
умолчанию: тот же шаблонизатор, что используется и для самого шаблона.
|
295
|
+
Пример: <tt>set :rdoc, :layout_engine => :erb</tt>
|
304
296
|
|
305
|
-
|
297
|
+
По умолчанию считается, что шаблоны находятся в директории <tt>./views</tt>.
|
298
|
+
Чтобы использовать другую директорию с шаблонами:
|
306
299
|
|
307
|
-
|
300
|
+
set :views, settings.root + '/templates'
|
308
301
|
|
309
|
-
|
302
|
+
Важное замечание: вы всегда должны ссылаться на шаблоны с помощью символов
|
303
|
+
(Symbol), даже когда они в поддиректории (в этом случае используйте
|
304
|
+
<tt>:'subdir/template'</tt>). Вы должны использовать символы, потому что
|
305
|
+
иначе шаблонизаторы попросту отображают любые строки, переданные им.
|
310
306
|
|
311
|
-
|
312
|
-
require 'sass'
|
307
|
+
=== Доступные шаблонизаторы
|
313
308
|
|
314
|
-
|
315
|
-
|
316
|
-
|
309
|
+
Некоторые языки шаблонов имеют несколько реализаций. Чтобы указать, какую
|
310
|
+
реализацию использовать, вам следует просто подключить нужную
|
311
|
+
библиотеку:
|
317
312
|
|
318
|
-
|
313
|
+
require 'rdiscount' # или require 'bluecloth'
|
314
|
+
get('/') { markdown :index }
|
319
315
|
|
320
|
-
|
321
|
-
могут быть установлены глобально через конфигурацию Sinatra,
|
322
|
-
см. {Опции и Конфигурация}[http://www.sinatrarb.com/configuration.html],
|
323
|
-
и переопределены локально.
|
316
|
+
=== Haml шаблоны
|
324
317
|
|
325
|
-
|
318
|
+
Зависимости:: {haml}[http://haml-lang.com/]
|
319
|
+
Расширения файлов:: <tt>.haml</tt>
|
320
|
+
Пример:: <tt>haml :index, :format => :html5</tt>
|
326
321
|
|
327
|
-
|
328
|
-
sass :stylesheet, :style => :expanded # переопределен
|
329
|
-
end
|
322
|
+
=== Erb шаблоны
|
330
323
|
|
331
|
-
|
324
|
+
Зависимости:: {erubis}[http://www.kuwata-lab.com/erubis/] или erb (включен в Ruby)
|
325
|
+
Расширения файлов:: <tt>.erb</tt>, <tt>.rhtml</tt> or <tt>.erubis</tt> (только Erubis)
|
326
|
+
Пример:: <tt>erb :index</tt>
|
332
327
|
|
333
|
-
|
328
|
+
=== Builder шаблоны
|
334
329
|
|
335
|
-
|
336
|
-
|
330
|
+
Зависимости:: {builder}[http://builder.rubyforge.org/]
|
331
|
+
Расширения файлов:: <tt>.builder</tt>
|
332
|
+
Пример:: <tt>builder { |xml| xml.em "hi" }</tt>
|
337
333
|
|
338
|
-
|
339
|
-
scss :stylesheet
|
340
|
-
end
|
334
|
+
Блок также используется и для встроенных шаблонов (см. пример).
|
341
335
|
|
342
|
-
|
336
|
+
=== Nokogiri шаблоны
|
343
337
|
|
344
|
-
{
|
345
|
-
|
346
|
-
|
347
|
-
и переопределены локально.
|
338
|
+
Зависимости:: {nokogiri}[http://nokogiri.org/]
|
339
|
+
Расширения файлов:: <tt>.nokogiri</tt>
|
340
|
+
Пример:: <tt>nokogiri { |xml| xml.em "hi" }</tt>
|
348
341
|
|
349
|
-
|
342
|
+
Блок также используется и для встроенных шаблонов (см. пример).
|
350
343
|
|
351
|
-
|
352
|
-
scss :stylesheet, :style => :expanded # переопределен
|
353
|
-
end
|
344
|
+
=== Sass шаблоны
|
354
345
|
|
355
|
-
|
346
|
+
Зависимости:: {sass}[http://sass-lang.com/]
|
347
|
+
Расширения файлов:: <tt>.sass</tt>
|
348
|
+
Пример:: <tt>sass :stylesheet, :style => :expanded</tt>
|
356
349
|
|
357
|
-
|
350
|
+
=== SCSS шаблоны
|
358
351
|
|
359
|
-
|
360
|
-
|
352
|
+
Зависимости:: {sass}[http://sass-lang.com/]
|
353
|
+
Расширения файлов:: <tt>.scss</tt>
|
354
|
+
Пример:: <tt>scss :stylesheet, :style => :expanded</tt>
|
361
355
|
|
362
|
-
|
363
|
-
less :stylesheet
|
364
|
-
end
|
356
|
+
=== Less шаблоны
|
365
357
|
|
366
|
-
|
358
|
+
Зависимости:: {less}[http://www.lesscss.org/]
|
359
|
+
Расширения файлов:: <tt>.less</tt>
|
360
|
+
Пример:: <tt>less :stylesheet</tt>
|
367
361
|
|
368
362
|
=== Liquid шаблоны
|
369
363
|
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
require 'liquid'
|
374
|
-
|
375
|
-
get '/' do
|
376
|
-
liquid :index
|
377
|
-
end
|
378
|
-
|
379
|
-
Отобразит <tt>./views/index.liquid</tt>.
|
380
|
-
|
381
|
-
Так как в Liquid шаблонах невозможно вызывать методы из Ruby (кроме +yield+),
|
382
|
-
то вы почти всегда будете передавать локальные переменные:
|
364
|
+
Зависимости:: {liquid}[http://www.liquidmarkup.org/]
|
365
|
+
Расширения файлов:: <tt>.liquid</tt>
|
366
|
+
Пример:: <tt>liquid :index, :locals => { :key => 'value' }</tt>
|
383
367
|
|
384
|
-
|
368
|
+
Так как в Liquid шаблонах невозможно вызывать методы из Ruby (кроме yield), то
|
369
|
+
вы почти всегда будете передавать в шаблон локальные переменные.
|
385
370
|
|
386
371
|
=== Markdown шаблоны
|
387
372
|
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
require 'rdiscount'
|
392
|
-
|
393
|
-
get '/' do
|
394
|
-
markdown :index
|
395
|
-
end
|
396
|
-
|
397
|
-
Отобразит <tt>./views/index.markdown</tt> (+md+ и +mkd+ также являются допустимыми файловыми
|
398
|
-
расширениями).
|
373
|
+
Зависимости:: {rdiscount}[https://github.com/rtomayko/rdiscount], {redcarpet}[https://github.com/tanoku/redcarpet], {bluecloth}[http://deveiate.org/projects/BlueCloth], {kramdown}[http://kramdown.rubyforge.org/] или {maruku}[http://maruku.rubyforge.org/]
|
374
|
+
Расширения файлов:: <tt>.markdown</tt>, <tt>.mkd</tt> and <tt>.md</tt>
|
375
|
+
Пример:: <tt>markdown :index, :layout_engine => :erb</tt>
|
399
376
|
|
400
377
|
В Markdown невозможно вызывать методы или передавать локальные переменные.
|
401
|
-
Следовательно, вам, скорее всего, придется использовать этот шаблон совместно
|
402
|
-
|
378
|
+
Следовательно, вам, скорее всего, придется использовать этот шаблон совместно
|
379
|
+
с другим шаблонизатором:
|
403
380
|
|
404
381
|
erb :overview, :locals => { :text => markdown(:introduction) }
|
405
382
|
|
@@ -408,57 +385,20 @@ Thin - это более производительный и функциона
|
|
408
385
|
%h1 Hello From Haml!
|
409
386
|
%p= markdown(:greetings)
|
410
387
|
|
411
|
-
Вы не можете вызывать Ruby из Markdown, соответственно, вы не можете
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
get '/' do
|
416
|
-
markdown :index, :layout_engine => :erb
|
417
|
-
end
|
418
|
-
|
419
|
-
Отобразит <tt>./views/index.md</tt> с <tt>./views/layout.erb</tt> в качестве
|
420
|
-
лэйаута (разметки).
|
421
|
-
|
422
|
-
Также вы можете задать такие опции рендеринга глобально:
|
423
|
-
|
424
|
-
set :markdown, :layout_engine => :haml, :layout => :post
|
425
|
-
|
426
|
-
get '/' do
|
427
|
-
markdown :index
|
428
|
-
end
|
429
|
-
|
430
|
-
Отобразит <tt>./views/index.md</tt> (и любой другой шаблон на Markdown) с
|
431
|
-
<tt>./views/post.haml</tt> в качестве лэйаута (разметки).
|
432
|
-
|
433
|
-
Также возможно обрабатывать Markdown с помощью BlueCloth, а не RDiscount:
|
434
|
-
|
435
|
-
require 'bluecloth'
|
436
|
-
|
437
|
-
Tilt.register 'markdown', BlueClothTemplate
|
438
|
-
Tilt.register 'mkd', BlueClothTemplate
|
439
|
-
Tilt.register 'md', BlueClothTemplate
|
440
|
-
|
441
|
-
get '/' do
|
442
|
-
markdown :index
|
443
|
-
end
|
444
|
-
|
445
|
-
Отобразит <tt>./views/index.md</tt> с помощью BlueCloth.
|
388
|
+
Вы не можете вызывать Ruby из Markdown, соответственно, вы не можете
|
389
|
+
использовать лэйауты на Markdown. Тем не менее, есть возможность использовать
|
390
|
+
один шаблонизатор для отображения шаблона, а другой для лэйаута с помощью
|
391
|
+
опции <tt>:layout_engine</tt>.
|
446
392
|
|
447
393
|
=== Textile шаблоны
|
448
394
|
|
449
|
-
|
395
|
+
Зависимости:: {RedCloth}[http://redcloth.org/]
|
396
|
+
Расширения файлов:: <tt>.textile</tt>
|
397
|
+
Пример:: <tt>textile :index, :layout_engine => :erb</tt>
|
450
398
|
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
get '/' do
|
455
|
-
textile :index
|
456
|
-
end
|
457
|
-
|
458
|
-
Отобразит <tt>./views/index.textile</tt>.
|
459
|
-
|
460
|
-
В Textile невозможно вызывать методы или передавать локальные переменные. Следовательно, вам, скорее всего,
|
461
|
-
придется использовать этот шаблон совместно с другим движком рендеринга:
|
399
|
+
В Textile невозможно вызывать методы или передавать локальные переменные.
|
400
|
+
Следовательно, вам, скорее всего, придется использовать этот шаблон совместно с
|
401
|
+
другим шаблонизатором:
|
462
402
|
|
463
403
|
erb :overview, :locals => { :text => textile(:introduction) }
|
464
404
|
|
@@ -467,43 +407,20 @@ Thin - это более производительный и функциона
|
|
467
407
|
%h1 Hello From Haml!
|
468
408
|
%p= textile(:greetings)
|
469
409
|
|
470
|
-
Вы не можете вызывать Ruby из Textile, соответственно, вы не можете
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
get '/' do
|
475
|
-
textile :index, :layout_engine => :erb
|
476
|
-
end
|
477
|
-
|
478
|
-
Отобразит <tt>./views/index.textile</tt> с <tt>./views/layout.erb</tt> в качестве
|
479
|
-
лэйаута (разметки).
|
480
|
-
|
481
|
-
Также вы можете задать такие опции рендеринга глобально:
|
482
|
-
|
483
|
-
set :textile, :layout_engine => :haml, :layout => :post
|
484
|
-
|
485
|
-
get '/' do
|
486
|
-
textile :index
|
487
|
-
end
|
488
|
-
|
489
|
-
Отобразит <tt>./views/index.textile</tt> (и любой другой шаблон на Textile) с
|
490
|
-
<tt>./views/post.haml</tt> в качестве лэйаута (разметки).
|
410
|
+
Вы не можете вызывать Ruby из Textile, соответственно, вы не можете
|
411
|
+
использовать лэйауты на Textile. Тем не менее, есть возможность использовать
|
412
|
+
один шаблонизатор для отображения шаблона, а другой для лэйаута с помощью
|
413
|
+
опции <tt>:layout_engine</tt>.
|
491
414
|
|
492
415
|
=== RDoc шаблоны
|
493
416
|
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
require 'rdoc/markup/to_html'
|
498
|
-
|
499
|
-
get '/' do
|
500
|
-
rdoc :index
|
501
|
-
end
|
502
|
-
|
503
|
-
Отобразит <tt>./views/index.rdoc</tt>.
|
417
|
+
Зависимости:: {rdoc}[http://rdoc.rubyforge.org/]
|
418
|
+
Расширения файлов:: <tt>.rdoc</tt>
|
419
|
+
Пример:: <tt>textile :README, :layout_engine => :erb</tt>
|
504
420
|
|
505
|
-
В RDoc невозможно вызывать методы или передавать локальные переменные.
|
506
|
-
придется использовать этот шаблон совместно с
|
421
|
+
В RDoc невозможно вызывать методы или передавать локальные переменные.
|
422
|
+
Следовательно, вам, скорее всего, придется использовать этот шаблон совместно с
|
423
|
+
другим шаблонизатором:
|
507
424
|
|
508
425
|
erb :overview, :locals => { :text => rdoc(:introduction) }
|
509
426
|
|
@@ -512,112 +429,61 @@ Thin - это более производительный и функциона
|
|
512
429
|
%h1 Hello From Haml!
|
513
430
|
%p= rdoc(:greetings)
|
514
431
|
|
515
|
-
Вы не можете вызывать Ruby из RDoc, соответственно, вы не можете
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
get '/' do
|
520
|
-
rdoc :index, :layout_engine => :erb
|
521
|
-
end
|
522
|
-
|
523
|
-
Отобразит <tt>./views/index.rdoc</tt> с <tt>./views/layout.erb</tt> в качестве
|
524
|
-
лэйаута (разметки).
|
525
|
-
|
526
|
-
Также вы можете задать такие опции рендеринга глобально:
|
527
|
-
|
528
|
-
set :rdoc, :layout_engine => :haml, :layout => :post
|
529
|
-
|
530
|
-
get '/' do
|
531
|
-
rdoc :index
|
532
|
-
end
|
533
|
-
|
534
|
-
Отобразит <tt>./views/index.rdoc</tt> (и любой другой шаблон на RDoc) с
|
535
|
-
<tt>./views/post.haml</tt> в качестве лэйаута (разметки).
|
432
|
+
Вы не можете вызывать Ruby из RDoc, соответственно, вы не можете
|
433
|
+
использовать лэйауты на RDoc. Тем не менее, есть возможность использовать
|
434
|
+
один шаблонизатор для отображения шаблона, а другой для лэйаута с помощью
|
435
|
+
опции <tt>:layout_engine</tt>.
|
536
436
|
|
537
437
|
=== Radius шаблоны
|
538
438
|
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
require 'radius'
|
543
|
-
|
544
|
-
get '/' do
|
545
|
-
radius :index
|
546
|
-
end
|
547
|
-
|
548
|
-
Отобразит <tt>./views/index.radius</tt>.
|
549
|
-
|
550
|
-
Так как в Radius шаблоне невозможно вызывать методы из Ruby (кроме +yield+),
|
551
|
-
то вы почти всегда будете передавать локальные переменные:
|
439
|
+
Зависимости:: {radius}[http://radius.rubyforge.org/]
|
440
|
+
Расширения файлов:: <tt>.radius</tt>
|
441
|
+
Пример:: <tt>radius :index, :locals => { :key => 'value' }</tt>
|
552
442
|
|
553
|
-
|
443
|
+
Так как в Radius шаблонах невозможно вызывать методы из Ruby напрямую, то
|
444
|
+
вы почти всегда будете передавать в шаблон локальные переменные.
|
554
445
|
|
555
446
|
=== Markaby шаблоны
|
556
447
|
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
require 'markaby'
|
561
|
-
|
562
|
-
get '/' do
|
563
|
-
markaby :index
|
564
|
-
end
|
565
|
-
|
566
|
-
Отобразит <tt>./views/index.mab</tt>.
|
567
|
-
|
568
|
-
Вы также можете использовать внутристроковые Markaby шаблоны:
|
448
|
+
Зависимости:: {markaby}[http://markaby.github.com/]
|
449
|
+
Расширения файлов:: <tt>.mab</tt>
|
450
|
+
Пример:: <tt>markaby { h1 "Welcome!" }</tt>
|
569
451
|
|
570
|
-
|
571
|
-
markaby { h1 "Welcome!" }
|
572
|
-
end
|
452
|
+
Блок также используется и для встроенных шаблонов (см. пример).
|
573
453
|
|
574
454
|
=== Slim шаблоны
|
575
455
|
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
require 'slim'
|
580
|
-
|
581
|
-
get '/' do
|
582
|
-
slim :index
|
583
|
-
end
|
584
|
-
|
585
|
-
Отобразит <tt>./views/index.slim</tt>.
|
456
|
+
Зависимости:: {slim}[http://slim-lang.com/]
|
457
|
+
Расширения файлов:: <tt>.slim</tt>
|
458
|
+
Пример:: <tt>slim :index</tt>
|
586
459
|
|
587
460
|
=== Creole шаблоны
|
588
461
|
|
589
|
-
|
462
|
+
Зависимости:: {creole}[https://github.com/minad/creole]
|
463
|
+
Расширения файлов:: <tt>.creole</tt>
|
464
|
+
Пример:: <tt>creole :wiki, :layout_engine => :erb</tt>
|
590
465
|
|
591
|
-
|
592
|
-
|
466
|
+
В Creole невозможно вызывать методы или передавать локальные переменные.
|
467
|
+
Следовательно, вам, скорее всего, придется использовать этот шаблон совместно с
|
468
|
+
другим шаблонизатором:
|
593
469
|
|
594
|
-
|
595
|
-
creole :index
|
596
|
-
end
|
597
|
-
|
598
|
-
Отобразит <tt>./views/index.creole</tt>.
|
599
|
-
|
600
|
-
=== CoffeeScript шаблоны
|
470
|
+
erb :overview, :locals => { :text => creole(:introduction) }
|
601
471
|
|
602
|
-
|
603
|
-
чтобы запускать JavaScript:
|
472
|
+
Заметьте, что вы можете вызывать метод +creole+ из других шаблонов:
|
604
473
|
|
605
|
-
|
606
|
-
|
607
|
-
* +therubyracer+ gem/библиотека.
|
608
|
-
|
609
|
-
Подробнее смотрите на {странице проекта}[http://github.com/josh/ruby-coffee-script].
|
610
|
-
|
611
|
-
Таким образом, вы можете использовать CoffeeScript шаблоны.
|
474
|
+
%h1 Hello From Haml!
|
475
|
+
%p= creole(:greetings)
|
612
476
|
|
613
|
-
|
614
|
-
|
477
|
+
Вы не можете вызывать Ruby из Creole, соответственно, вы не можете
|
478
|
+
использовать лэйауты на Creole. Тем не менее, есть возможность использовать
|
479
|
+
один шаблонизатор для отображения шаблона, а другой для лэйаута с помощью
|
480
|
+
опции <tt>:layout_engine</tt>.
|
615
481
|
|
616
|
-
|
617
|
-
coffee :application
|
618
|
-
end
|
482
|
+
=== CoffeeScript шаблоны
|
619
483
|
|
620
|
-
|
484
|
+
Зависимости:: {coffee-script}[https://github.com/josh/ruby-coffee-script] и {способ запускать javascript}[https://github.com/sstephenson/execjs/blob/master/README.md#readme]
|
485
|
+
Расширения файлов:: <tt>.coffee</tt>
|
486
|
+
Пример:: <tt>coffee :index</tt>
|
621
487
|
|
622
488
|
=== Встроенные шаблоны
|
623
489
|
|
@@ -625,7 +491,7 @@ Thin - это более производительный и функциона
|
|
625
491
|
haml '%div.title Hello World'
|
626
492
|
end
|
627
493
|
|
628
|
-
Отобразит
|
494
|
+
Отобразит встроенный шаблон, переданный строкой.
|
629
495
|
|
630
496
|
=== Доступ к переменным в шаблонах
|
631
497
|
|
@@ -641,7 +507,7 @@ Thin - это более производительный и функциона
|
|
641
507
|
|
642
508
|
get '/:id' do
|
643
509
|
foo = Foo.find(params[:id])
|
644
|
-
haml '%h1=
|
510
|
+
haml '%h1= bar.name', :locals => { :bar => foo }
|
645
511
|
end
|
646
512
|
|
647
513
|
Это обычный подход, когда шаблоны рендерятся как части других шаблонов.
|
@@ -686,8 +552,9 @@ Thin - это более производительный и функциона
|
|
686
552
|
end
|
687
553
|
|
688
554
|
Если шаблон с именем "layout" существует, то он будет использоваться каждый раз
|
689
|
-
при рендеринге. Вы можете отключать лэйаут
|
690
|
-
<tt>:layout => false</tt> или отключить его для всего приложения, например, так:
|
555
|
+
при рендеринге. Вы можете отключать лэйаут в каждом конкретном случае с помощью
|
556
|
+
<tt>:layout => false</tt> или отключить его для всего приложения, например, так:
|
557
|
+
<tt>set :haml, :layout => false</tt>:
|
691
558
|
|
692
559
|
get '/' do
|
693
560
|
haml :index, :layout => !request.xhr?
|
@@ -782,7 +649,7 @@ Thin - это более производительный и функциона
|
|
782
649
|
=== Использование сессий
|
783
650
|
|
784
651
|
Сессия используется, чтобы сохранять состояние между запросами. Если эта опция
|
785
|
-
включена, то у вас будет один
|
652
|
+
включена, то у вас будет один хеш сессии на одну пользовательскую сессию:
|
786
653
|
|
787
654
|
enable :sessions
|
788
655
|
|
@@ -799,7 +666,7 @@ Thin - это более производительный и функциона
|
|
799
666
|
сохранение больших объемов данных увеличит ваш трафик). В таком случае вы
|
800
667
|
можете использовать альтернативную Rack "прослойку" (middleware), реализующую
|
801
668
|
механизм сессий. Для этого *не надо* вызывать <tt>enable :sessions</tt>,
|
802
|
-
вместо этого следует подключить ее
|
669
|
+
вместо этого следует подключить ее так же, как и любую другую "прослойку":
|
803
670
|
|
804
671
|
use Rack::Session::Pool, :expire_after => 2592000
|
805
672
|
|
@@ -815,11 +682,11 @@ Thin - это более производительный и функциона
|
|
815
682
|
ключом. Секретный ключ генерируется Sinatra. Тем не менее, так как этот
|
816
683
|
ключ будет меняться с каждым запуском приложения, вы, возможно, захотите
|
817
684
|
установить ключ вручную, чтобы у всех экземпляров вашего приложения
|
818
|
-
|
685
|
+
был один и тот же ключ:
|
819
686
|
|
820
687
|
set :session_secret, 'super secret'
|
821
688
|
|
822
|
-
Если вы хотите больше настроек для сессий, вы можете задать их, передав
|
689
|
+
Если вы хотите больше настроек для сессий, вы можете задать их, передав хеш опций в параметр +sessions+:
|
823
690
|
|
824
691
|
set :sessions, :domain => 'foo.com'
|
825
692
|
|
@@ -913,7 +780,7 @@ Thin - это более производительный и функциона
|
|
913
780
|
get '/foo' do
|
914
781
|
status 418
|
915
782
|
headers \
|
916
|
-
"Allow" => "BREW, POST, GET, PROPFIND, WHEN"
|
783
|
+
"Allow" => "BREW, POST, GET, PROPFIND, WHEN",
|
917
784
|
"Refresh" => "Refresh: 20; http://www.ietf.org/rfc/rfc2324.txt"
|
918
785
|
body "I'm a tea pot!"
|
919
786
|
end
|
@@ -949,7 +816,9 @@ Thin - это более производительный и функциона
|
|
949
816
|
Когда вы используете <tt>send_file</tt> или статические файлы, у вас могут быть mime-типы, которые Sinatra
|
950
817
|
не понимает по умолчанию. Используйте +mime_type+ для их регистрации по расширению файла:
|
951
818
|
|
952
|
-
|
819
|
+
configure do
|
820
|
+
mime_type :foo, 'text/foo'
|
821
|
+
end
|
953
822
|
|
954
823
|
Вы также можете использовать это в +content_type+ методе-помощнике:
|
955
824
|
|
@@ -997,9 +866,9 @@ Thin - это более производительный и функциона
|
|
997
866
|
|
998
867
|
redirect to('/bar?sum=42')
|
999
868
|
|
1000
|
-
|
869
|
+
либо используйте сессию:
|
1001
870
|
|
1002
|
-
enable :
|
871
|
+
enable :sessions
|
1003
872
|
|
1004
873
|
get '/foo' do
|
1005
874
|
session[:secret] = 'foo'
|
@@ -1034,9 +903,9 @@ Thin - это более производительный и функциона
|
|
1034
903
|
expires 500, :public, :must_revalidate
|
1035
904
|
end
|
1036
905
|
|
1037
|
-
Чтобы как следует использовать
|
906
|
+
Чтобы как следует использовать кэширование, вам следует подумать об использовании
|
1038
907
|
+etag+ и +last_modified+. Рекомендуется использовать эти методы-помощники *до*
|
1039
|
-
выполнения
|
908
|
+
выполнения ресурсоемких вычислений, так как они немедленно отправят ответ клиенту,
|
1040
909
|
если текущая версия уже есть в их кэше:
|
1041
910
|
|
1042
911
|
get '/article/:id' do
|
@@ -1066,6 +935,9 @@ Thin - это более производительный и функциона
|
|
1066
935
|
"hello"
|
1067
936
|
end
|
1068
937
|
|
938
|
+
Используйте опцию <tt>:static_cache_control</tt> (см. ниже), чтобы
|
939
|
+
добавить заголовок <tt>Cache-Control</tt> к статическим файлам.
|
940
|
+
|
1069
941
|
=== Отправка файлов
|
1070
942
|
|
1071
943
|
Для отправки файлов пользователю вы можете использовать метод <tt>send_file</tt>:
|
@@ -1109,29 +981,33 @@ Thin - это более производительный и функциона
|
|
1109
981
|
|
1110
982
|
# приложение запущено на http://example.com/example
|
1111
983
|
get '/foo' do
|
1112
|
-
|
1113
|
-
request.
|
1114
|
-
request.
|
1115
|
-
request.
|
1116
|
-
request.
|
1117
|
-
request.
|
1118
|
-
request.
|
1119
|
-
request.
|
1120
|
-
request.
|
1121
|
-
request.
|
1122
|
-
request.
|
1123
|
-
request.
|
1124
|
-
request
|
1125
|
-
request.
|
1126
|
-
request.
|
1127
|
-
request.
|
1128
|
-
request
|
1129
|
-
request.
|
1130
|
-
request.
|
1131
|
-
request.
|
1132
|
-
request.
|
1133
|
-
request.
|
1134
|
-
request.
|
984
|
+
t = %w[text/css text/html application/javascript]
|
985
|
+
request.accept # ['text/html', '*/*']
|
986
|
+
request.accept? 'text/xml' # true
|
987
|
+
request.preferred_type(t) # 'text/html'
|
988
|
+
request.body # тело запроса, посланное клиентом (см. ниже)
|
989
|
+
request.scheme # "http"
|
990
|
+
request.script_name # "/example"
|
991
|
+
request.path_info # "/foo"
|
992
|
+
request.port # 80
|
993
|
+
request.request_method # "GET"
|
994
|
+
request.query_string # ""
|
995
|
+
request.content_length # длина тела запроса
|
996
|
+
request.media_type # медиатип тела запроса
|
997
|
+
request.host # "example.com"
|
998
|
+
request.get? # true (есть аналоги для других методов HTTP)
|
999
|
+
request.form_data? # false
|
1000
|
+
request["SOME_HEADER"] # значение заголовка SOME_HEADER
|
1001
|
+
request.referrer # источник запроса клиента либо '/'
|
1002
|
+
request.user_agent # user agent (используется для :agent условия)
|
1003
|
+
request.cookies # хеш, содержащий cookies браузера
|
1004
|
+
request.xhr? # является ли запрос ajax запросом?
|
1005
|
+
request.url # "http://example.com/example/foo"
|
1006
|
+
request.path # "/example/foo"
|
1007
|
+
request.ip # IP-адрес клиента
|
1008
|
+
request.secure? # false (true, если запрос сделан через SSL)
|
1009
|
+
request.forwarded? # true (если сервер работает за обратным прокси)
|
1010
|
+
request.env # "сырой" env хеш, полученный Rack
|
1135
1011
|
end
|
1136
1012
|
|
1137
1013
|
Некоторые опции, такие как <tt>script_name</tt> или <tt>path_info</tt> доступны для изменения:
|
@@ -1175,7 +1051,7 @@ Thin - это более производительный и функциона
|
|
1175
1051
|
puts "could be #{file}"
|
1176
1052
|
end
|
1177
1053
|
|
1178
|
-
Это не
|
1054
|
+
Это не слишком полезный пример. Зато полезен тот факт, что вы можете переопределить
|
1179
1055
|
этот метод, чтобы использовать свой собственный механизм поиска. Например, если вы
|
1180
1056
|
хотите, чтобы можно было использовать несколько директорий с шаблонами:
|
1181
1057
|
|
@@ -1201,12 +1077,12 @@ Thin - это более производительный и функциона
|
|
1201
1077
|
|
1202
1078
|
Вы можете легко вынести этот код в расширение и поделиться им с остальными!
|
1203
1079
|
|
1204
|
-
Заметьте, что <tt>find_template</tt не проверяет, существует ли файл на самом деле,
|
1080
|
+
Заметьте, что <tt>find_template</tt> не проверяет, существует ли файл на самом деле,
|
1205
1081
|
а вызывает заданный блок для всех возможных путей. Дело тут не в производительности,
|
1206
1082
|
дело в том, что +render+ вызовет +break+, как только файл не будет найден.
|
1207
1083
|
Содержимое и местонахождение шаблонов будет закэшировано, если приложение запущено не
|
1208
1084
|
в режиме разработки (set :environment, :development). Вы должны помнить об этих нюансах,
|
1209
|
-
если пишите по-настоящему "
|
1085
|
+
если пишите по-настоящему "сумасшедший" метод.
|
1210
1086
|
|
1211
1087
|
== Конфигурация
|
1212
1088
|
|
@@ -1255,90 +1131,97 @@ Thin - это более производительный и функциона
|
|
1255
1131
|
|
1256
1132
|
=== Доступные настройки
|
1257
1133
|
|
1258
|
-
[absolute_redirects]
|
1259
|
-
|
1260
|
-
|
1261
|
-
|
1134
|
+
[absolute_redirects] если отключено, то Sinatra будет позволять использование
|
1135
|
+
относительных перенаправлений, но при этом перестанет
|
1136
|
+
соответствовать RFC 2616 (HTTP 1.1), который разрешает только
|
1137
|
+
абсолютные перенаправления.
|
1138
|
+
|
1139
|
+
Включайте эту опцию, если ваше приложение работает за обратным прокси,
|
1140
|
+
который настроен не совсем корректно. Обратите внимание, метод +url+
|
1141
|
+
все равно будет генерировать абсолютные URL, если вы не передадите
|
1142
|
+
+false+ вторым аргументом.
|
1262
1143
|
|
1263
|
-
|
1264
|
-
который настроен не совсем корректно. Обратите внимание, метод +url+
|
1265
|
-
все равно будет генерировать абсолютные URL, если вы не передадите
|
1266
|
-
+false+ вторым аргументом.
|
1144
|
+
Отключено по умолчанию.
|
1267
1145
|
|
1268
|
-
|
1146
|
+
[add_charsets] mime-типы, к которым метод <tt>content_type</tt> будет автоматически
|
1147
|
+
добавлять информацию о кодировке.
|
1269
1148
|
|
1270
|
-
|
1271
|
-
добавлять информацию о кодировке.
|
1149
|
+
Вам следует добавлять значения к этой опции вместо ее переопределения:
|
1272
1150
|
|
1273
|
-
|
1151
|
+
settings.add_charsets << "application/foobar"
|
1274
1152
|
|
1275
|
-
|
1153
|
+
[app_file] главный файл приложения, используется для определения корневой директории
|
1154
|
+
проекта, директорий с шаблонами и статическими файлами, вложенных шаблонов.
|
1276
1155
|
|
1277
|
-
[
|
1278
|
-
|
1156
|
+
[bind] используемый IP-адрес (по умолчанию: 0.0.0.0). Используется только
|
1157
|
+
встроенным сервером.
|
1279
1158
|
|
1280
|
-
[
|
1281
|
-
встроенным сервером.
|
1159
|
+
[default_encoding] кодировка, если неизвестна (по умолчанию: <tt>"utf-8"</tt>).
|
1282
1160
|
|
1283
|
-
[
|
1161
|
+
[dump_errors] отображать ошибки в логе.
|
1284
1162
|
|
1285
|
-
[
|
1163
|
+
[environment] текущее окружение, по умолчанию, значение <tt>ENV['RACK_ENV']</tt>
|
1164
|
+
или <tt>"development"</tt>, если <tt>ENV['RACK_ENV']</tt> не доступна.
|
1286
1165
|
|
1287
|
-
[
|
1288
|
-
или <tt>"development"</tt>, если <tt>ENV['RACK_ENV']</tt> не доступна.
|
1166
|
+
[logging] использовать логер.
|
1289
1167
|
|
1290
|
-
[
|
1168
|
+
[lock] создает блокировку для каждого запроса, которая гарантирует обработку
|
1169
|
+
только одного запроса в текущий момент времени в Ruby процессе.
|
1291
1170
|
|
1292
|
-
|
1293
|
-
|
1171
|
+
Включайте, если ваше приложение не потоко-безопасно (thread-safe).
|
1172
|
+
Отключено по умолчанию.
|
1294
1173
|
|
1295
|
-
|
1296
|
-
|
1174
|
+
[method_override] использовать "магический" параметр <tt>_method</tt>, чтобы позволить
|
1175
|
+
использование PUT/DELETE форм в браузерах, которые не поддерживают
|
1176
|
+
эти методы.
|
1297
1177
|
|
1298
|
-
[
|
1299
|
-
|
1300
|
-
эти методы.
|
1178
|
+
[port] порт, на котором будет работать сервер. Используется только
|
1179
|
+
встроенным сервером.
|
1301
1180
|
|
1302
|
-
[
|
1303
|
-
|
1181
|
+
[prefixed_redirects] добавлять или нет параметр <tt>request.script_name</tt> к редиректам,
|
1182
|
+
если не задан абсолютный путь. Таким образом, <tt>redirect '/foo'</tt>
|
1183
|
+
будет вести себя как <tt>redirect to('/foo')</tt>. Отключено по умолчанию.
|
1304
1184
|
|
1305
|
-
[
|
1306
|
-
если не задан абсолютный путь. Таким образом, <tt>redirect '/foo'</tt>
|
1307
|
-
будет вести себя как <tt>redirect to('/foo')</tt>. Отключено по умолчанию.
|
1185
|
+
[public_folder] директория, откуда будут раздаваться статические файлы.
|
1308
1186
|
|
1309
|
-
[
|
1187
|
+
[reload_templates] перезагружать или нет шаблоны на каждый запрос.
|
1188
|
+
Включено в режиме разработки.
|
1310
1189
|
|
1311
|
-
[
|
1312
|
-
Включено в режиме разработки.
|
1190
|
+
[root] корневая директория проекта.
|
1313
1191
|
|
1314
|
-
[
|
1192
|
+
[raise_errors] выбрасывать исключения (будет останавливать приложение).
|
1315
1193
|
|
1316
|
-
[
|
1194
|
+
[run] если включено, Sinatra будет самостоятельно запускать веб-сервер.
|
1195
|
+
Не включайте, если используете rackup или аналогичные средства.
|
1317
1196
|
|
1318
|
-
[
|
1319
|
-
|
1197
|
+
[running] работает ли сейчас встроенный сервер?
|
1198
|
+
Не меняйте эту опцию!
|
1320
1199
|
|
1321
|
-
[
|
1322
|
-
|
1200
|
+
[server] сервер или список серверов, которые следует использовать в качестве
|
1201
|
+
встроенного сервера. По умолчанию: ['thin', 'mongrel', 'webrick'],
|
1202
|
+
порядок задает приоритет.
|
1323
1203
|
|
1324
|
-
[
|
1325
|
-
встроенного сервера. По умолчанию: ['thin', 'mongrel', 'webrick'],
|
1326
|
-
порядок задает приоритет.
|
1204
|
+
[sessions] включить сессии на основе кук (cookie).
|
1327
1205
|
|
1328
|
-
[
|
1206
|
+
[show_exceptions] показывать исключения/стек вызовов (stack trace) в браузере.
|
1329
1207
|
|
1330
|
-
[
|
1208
|
+
[static] должна ли Sinatra осуществлять раздачу статических файлов.
|
1209
|
+
Отключите, когда используете какой-либо веб-сервер для этой цели.
|
1210
|
+
Отключение значительно улучшит производительность приложения.
|
1211
|
+
По умолчанию включено в классических и отключено в модульных
|
1212
|
+
приложениях.
|
1331
1213
|
|
1332
|
-
[
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1214
|
+
[static_cache_control] Когда Sinatra отдает статические файлы, используйте эту опцию,
|
1215
|
+
чтобы добавить им заголовок <tt>Cache-Control</tt>. Для этого
|
1216
|
+
используется метод-помощник +cache_control+. По умолчанию отключено.
|
1217
|
+
Используйте массив, когда надо задать несколько значений:
|
1218
|
+
<tt>set :static_cache_control, [:public, :max_age => 300]</tt>
|
1336
1219
|
|
1337
1220
|
[views] директория с шаблонами.
|
1338
1221
|
|
1339
1222
|
== Обработка ошибок
|
1340
1223
|
|
1341
|
-
Обработчики ошибок исполняются в том же контексте, что и маршруты, +before+-фильтры, а это означает, что всякие
|
1224
|
+
Обработчики ошибок исполняются в том же контексте, что и маршруты, и +before+-фильтры, а это означает, что всякие
|
1342
1225
|
прелести вроде <tt>haml</tt>, <tt>erb</tt>, <tt>halt</tt> и т.д. доступны и им.
|
1343
1226
|
|
1344
1227
|
=== Not Found
|
@@ -1416,8 +1299,8 @@ HTTP запросами/ответами для предоставления р
|
|
1416
1299
|
|
1417
1300
|
Семантика +use+ идентична той, что определена для
|
1418
1301
|
Rack::Builder[http://rack.rubyforge.org/doc/classes/Rack/Builder.html] DSL
|
1419
|
-
(чаще всего используется в rackup файлах). Например, +use+
|
1420
|
-
множественные переменные,
|
1302
|
+
(чаще всего используется в rackup файлах). Например, метод +use+ принимает
|
1303
|
+
как множественные переменные, так и блоки:
|
1421
1304
|
|
1422
1305
|
use Rack::Auth::Basic do |username, password|
|
1423
1306
|
username == 'admin' && password == 'secret'
|
@@ -1428,10 +1311,16 @@ Rack распространяется с различными стандартн
|
|
1428
1311
|
многие из этих компонентов автоматически, основываясь на конфигурации, чтобы вам не приходилось
|
1429
1312
|
подключать (+use+) их вручную.
|
1430
1313
|
|
1314
|
+
Вы можете найти полезные прослойки в
|
1315
|
+
{rack}[https://github.com/rack/rack/tree/master/lib/rack],
|
1316
|
+
{rack-contrib}[https://github.com/rack/rack-contrib#readme],
|
1317
|
+
{CodeRack}[http://coderack.org/] или в
|
1318
|
+
{Rack wiki}[https://github.com/rack/rack/wiki/List-of-Middleware].
|
1319
|
+
|
1431
1320
|
== Тестирование
|
1432
1321
|
|
1433
1322
|
Тесты для Sinatra приложений могут быть написаны с помощью библиотек, фреймворков, поддерживающих
|
1434
|
-
тестирование Rack. {Rack::Test}[http://
|
1323
|
+
тестирование Rack. {Rack::Test}[http://rdoc.info/github/brynary/rack-test/master/frames] рекомендован:
|
1435
1324
|
|
1436
1325
|
require 'my_sinatra_app'
|
1437
1326
|
require 'test/unit'
|
@@ -1460,19 +1349,18 @@ Rack распространяется с различными стандартн
|
|
1460
1349
|
end
|
1461
1350
|
end
|
1462
1351
|
|
1463
|
-
Обратите внимание: Встроенные модуль Sinatra::Test и класс Sinatra::TestHarness являются
|
1464
|
-
устаревшими, начиная с релиза 0.9.2.
|
1465
|
-
|
1466
1352
|
== Sinatra::Base — "прослойки", библиотеки и модульные приложения
|
1467
1353
|
|
1468
|
-
Описание своего приложения самым простейшим способом (с помощью DSL верхнего уровня,
|
1469
|
-
|
1470
|
-
|
1354
|
+
Описание своего приложения самым простейшим способом (с помощью DSL верхнего уровня,
|
1355
|
+
как в примерах выше) отлично работает для крохотных приложений. Тем не менее,
|
1356
|
+
такой метод имеет множество недостатков при создании компонентов, таких как
|
1357
|
+
Rack middleware ("прослоек"), Rails metal, простых библиотек с серверными компонентами,
|
1358
|
+
расширений Sinatra.
|
1471
1359
|
|
1472
1360
|
DSL верхнего уровня "загрязняет" пространство имен <tt>Object</tt> и подразумевает стиль конфигурации
|
1473
|
-
микро-приложения (например, единый файл приложения,
|
1474
|
-
|
1475
|
-
и т.д.). И тут на помощь приходит Sinatra::Base
|
1361
|
+
микро-приложения (например, единый файл приложения, <tt>./public</tt> и
|
1362
|
+
<tt>./views</tt> директории, логирование, страницу деталей об исключениях
|
1363
|
+
и т.д.). И тут на помощь приходит <tt>Sinatra::Base</tt>:
|
1476
1364
|
|
1477
1365
|
require 'sinatra/base'
|
1478
1366
|
|
@@ -1485,31 +1373,31 @@ DSL верхнего уровня "загрязняет" пространств
|
|
1485
1373
|
end
|
1486
1374
|
end
|
1487
1375
|
|
1488
|
-
Методы, доступные Sinatra::Base подклассам идентичны тем, что доступны
|
1376
|
+
Методы, доступные <tt>Sinatra::Base</tt> подклассам идентичны тем, что доступны
|
1489
1377
|
в DSL верхнего уровня. Большинство приложений верхнего уровня могут быть
|
1490
|
-
конвертированы в Sinatra::Base компоненты с помощью двух модификаций:
|
1378
|
+
конвертированы в <tt>Sinatra::Base</tt> компоненты с помощью двух модификаций:
|
1491
1379
|
|
1492
1380
|
* Вы должны подключать <tt>sinatra/base</tt> вместо +sinatra+,
|
1493
|
-
иначе все
|
1494
|
-
* Поместите все маршруты, обработчики ошибок, фильтры и опции в подкласс Sinatra::Base
|
1381
|
+
иначе все методы, предоставляемые Sinatra, будут импортированы в глобальное пространство имен.
|
1382
|
+
* Поместите все маршруты, обработчики ошибок, фильтры и опции в подкласс <tt>Sinatra::Base</tt>.
|
1495
1383
|
|
1496
1384
|
<tt>Sinatra::Base</tt> — это чистый лист. Большинство опций, включая встроенный сервер, по умолчанию отключены.
|
1497
|
-
Смотрите {Опции и
|
1385
|
+
Смотрите {Опции и конфигурация}[http://www.sinatrarb.com/configuration.html] для детальной информации
|
1498
1386
|
об опциях и их поведении.
|
1499
1387
|
|
1500
1388
|
=== Модульные приложения против классических
|
1501
1389
|
|
1502
|
-
Вопреки всеобщему
|
1390
|
+
Вопреки всеобщему убеждению, в классическом стиле (самом простом) нет ничего плохого.
|
1503
1391
|
Если этот стиль подходит вашему приложению, вы не обязаны переписывать его в модульное
|
1504
1392
|
приложение.
|
1505
1393
|
|
1506
1394
|
У классического стиля есть всего два недостатка относительно модульного:
|
1507
1395
|
|
1508
|
-
* У вас может быть только одно приложение Sinatra на Ruby процесс. Если вы планируете
|
1396
|
+
* У вас может быть только одно приложение Sinatra на один Ruby процесс. Если вы планируете
|
1509
1397
|
использовать больше, то переключайтесь на модульный стиль.
|
1510
1398
|
|
1511
1399
|
* Приложения, использующие классический стиль, добавляют методы к Object. Если вы
|
1512
|
-
планируете поставлять свое приложение в виде библиотеки/gem, то
|
1400
|
+
планируете поставлять свое приложение в виде библиотеки/gem, то переходите
|
1513
1401
|
на модульный стиль.
|
1514
1402
|
|
1515
1403
|
Не существует причин, по которым вы не могли бы смешивать модульный и классический стили.
|
@@ -1518,11 +1406,12 @@ DSL верхнего уровня "загрязняет" пространств
|
|
1518
1406
|
|
1519
1407
|
Опция Классический Модульный
|
1520
1408
|
|
1521
|
-
app_file файл с приложением
|
1409
|
+
app_file файл с приложением файл с подклассом Sinatra::Base
|
1522
1410
|
run $0 == app_file false
|
1523
1411
|
logging true false
|
1524
1412
|
method_override true false
|
1525
1413
|
inline_templates true false
|
1414
|
+
static true false
|
1526
1415
|
|
1527
1416
|
|
1528
1417
|
=== Запуск модульных приложений
|
@@ -1585,7 +1474,7 @@ Rack-совместимый сервер приложений.
|
|
1585
1474
|
|
1586
1475
|
=== Использование Sinatra в качестве "прослойки"
|
1587
1476
|
|
1588
|
-
Не только
|
1477
|
+
Не только сама Sinatra может использовать "прослойки" Rack, но и любое Sinatra приложение
|
1589
1478
|
само может быть добавлено к любому Rack endpoint в качестве "прослойки". Этим endpoint (конечной точкой)
|
1590
1479
|
может быть другое Sinatra приложение, или приложение, основанное на Rack (Rails/Ramaze/Camping/...):
|
1591
1480
|
|
@@ -1597,7 +1486,7 @@ Rack-совместимый сервер приложений.
|
|
1597
1486
|
get('/login') { haml :login }
|
1598
1487
|
|
1599
1488
|
post('/login') do
|
1600
|
-
if params[:name]
|
1489
|
+
if params[:name] == 'admin' && params[:password] == 'admin'
|
1601
1490
|
session['user_name'] = params[:name]
|
1602
1491
|
else
|
1603
1492
|
redirect '/login'
|
@@ -1618,6 +1507,48 @@ Rack-совместимый сервер приложений.
|
|
1618
1507
|
get('/') { "Hello #{session['user_name']}." }
|
1619
1508
|
end
|
1620
1509
|
|
1510
|
+
=== Создание приложений "на лету"
|
1511
|
+
|
1512
|
+
Иногда требуется создавать Sinatra приложения "на лету" (например,
|
1513
|
+
из другого приложения). Это возможно с помощью <tt>Sinatra.new</tt>:
|
1514
|
+
|
1515
|
+
require 'sinatra/base'
|
1516
|
+
my_app = Sinatra.new { get('/') { "hi" } }
|
1517
|
+
my_app.run!
|
1518
|
+
|
1519
|
+
Этот метод может принимать аргументом приложение, от которого
|
1520
|
+
следует наследоваться:
|
1521
|
+
|
1522
|
+
# config.ru
|
1523
|
+
require 'sinatra/base'
|
1524
|
+
|
1525
|
+
controller = Sinatra.new do
|
1526
|
+
enable :logging
|
1527
|
+
helpers MyHelpers
|
1528
|
+
end
|
1529
|
+
|
1530
|
+
map('/a') do
|
1531
|
+
run Sinatra.new(controller) { get('/') { 'a' } }
|
1532
|
+
end
|
1533
|
+
|
1534
|
+
map('/b') do
|
1535
|
+
run Sinatra.new(controller) { get('/') { 'b' } }
|
1536
|
+
end
|
1537
|
+
|
1538
|
+
Это особенно полезно для тестирования расширений Sinatra и при
|
1539
|
+
использовании Sinatra внутри вашей библиотеки.
|
1540
|
+
|
1541
|
+
Благодаря этому, использовать Sinatra как "прослойку" очень просто:
|
1542
|
+
|
1543
|
+
require 'sinatra/base'
|
1544
|
+
|
1545
|
+
use Sinatra do
|
1546
|
+
get('/') { ... }
|
1547
|
+
end
|
1548
|
+
|
1549
|
+
run RailsProject::Application
|
1550
|
+
|
1551
|
+
|
1621
1552
|
== Области видимости и привязка
|
1622
1553
|
|
1623
1554
|
Текущая область видимости определяет методы и переменные, доступные
|
@@ -1625,11 +1556,11 @@ Rack-совместимый сервер приложений.
|
|
1625
1556
|
|
1626
1557
|
=== Область видимости приложения / класса
|
1627
1558
|
|
1628
|
-
Любое Sinatra приложение соответствует подклассу Sinatra::Base
|
1559
|
+
Любое Sinatra приложение соответствует подклассу <tt>Sinatra::Base</tt>. Если вы
|
1629
1560
|
используете DSL верхнего уровня (<tt>require 'sinatra'</tt>), то этим классом будет
|
1630
|
-
Sinatra::Application
|
1561
|
+
<tt>Sinatra::Application</tt>, иначе это будет подкласс, который вы создали вручную.
|
1631
1562
|
На уровне класса вам будут доступны такие методы, как +get+ или +before+, но вы
|
1632
|
-
не сможете
|
1563
|
+
не сможете получить доступ к объектам +request+ или +session+, так как существует
|
1633
1564
|
только один класс приложения для всех запросов.
|
1634
1565
|
|
1635
1566
|
Опции, созданные с помощью +set+, являются методами уровня класса:
|
@@ -1649,7 +1580,8 @@ Sinatra::Application, иначе это будет подкласс, котор
|
|
1649
1580
|
* тела вашего класса приложения;
|
1650
1581
|
* методов, определенных расширениями;
|
1651
1582
|
* блока, переданного в +helpers+;
|
1652
|
-
* блоков, использованных как значения для +set
|
1583
|
+
* блоков, использованных как значения для +set+;
|
1584
|
+
* блока, переданного в <tt>Sinatra.new</tt>.
|
1653
1585
|
|
1654
1586
|
Вы можете получить доступ к объекту области видимости (классу приложения) следующими способами:
|
1655
1587
|
|
@@ -1679,9 +1611,9 @@ Sinatra::Application, иначе это будет подкласс, котор
|
|
1679
1611
|
end
|
1680
1612
|
end
|
1681
1613
|
|
1682
|
-
У вас будет область видимости запроса
|
1614
|
+
У вас будет область видимости запроса в:
|
1683
1615
|
|
1684
|
-
* get/head/post/put/delete/options
|
1616
|
+
* get/head/post/put/delete/options блоках;
|
1685
1617
|
* before/after фильтрах;
|
1686
1618
|
* методах-помощниках;
|
1687
1619
|
* шаблонах/отображениях.
|
@@ -1689,10 +1621,10 @@ Sinatra::Application, иначе это будет подкласс, котор
|
|
1689
1621
|
=== Область видимости делегирования
|
1690
1622
|
|
1691
1623
|
Область видимости делегирования просто перенаправляет методы в область видимости класса.
|
1692
|
-
Однако,
|
1693
|
-
|
1694
|
-
|
1695
|
-
|
1624
|
+
Однако, она не полностью ведет себя как область видимости класса, так как у вас нет
|
1625
|
+
привязки к классу. Только методы, явно помеченные для делегирования, будут доступны,
|
1626
|
+
а переменных/состояний области видимости класса не будет (иначе говоря,
|
1627
|
+
у вас будет другой +self+ объект). Вы можете
|
1696
1628
|
непосредственно добавить методы делегирования, используя
|
1697
1629
|
<tt>Sinatra::Delegator.delegate :method_name</tt>.
|
1698
1630
|
|
@@ -1731,7 +1663,7 @@ Sinatra приложения могут быть запущены напряму
|
|
1731
1663
|
[ Ruby 1.9.2 ]
|
1732
1664
|
1.9.2 поддерживается и рекомендована к использованию. Заметьте, что Radius и Markaby
|
1733
1665
|
пока несовместимы с 1.9.2. Не используйте 1.9.2p0, известно, что эта
|
1734
|
-
версия весьма
|
1666
|
+
версия весьма нестабильна при использовании Sinatra.
|
1735
1667
|
|
1736
1668
|
[ Rubinius ]
|
1737
1669
|
Rubinius официально поддерживается (Rubinius >= 1.2.3), всё, включая все
|
@@ -1742,9 +1674,12 @@ Sinatra приложения могут быть запущены напряму
|
|
1742
1674
|
использованием альтернативных шаблонов. Тем не менее, если вы выбираете
|
1743
1675
|
JRuby, то, пожалуйста, посмотрите на JRuby Rack-сервера, так как Thin не
|
1744
1676
|
поддерживается полностью на JRuby. Поддержка расширений на C в JRuby все
|
1745
|
-
еще экспериментальная, что на данный момент затрагивает только RDiscount
|
1677
|
+
еще экспериментальная, что на данный момент затрагивает только RDiscount и
|
1678
|
+
Redcarpet.
|
1746
1679
|
|
1747
|
-
<b>Ruby 1.8.6 больше не поддерживается.</b>
|
1680
|
+
<b>Ruby 1.8.6 больше не поддерживается.</b> Если вы хотите запускать свое
|
1681
|
+
приложение на 1.8.6, откатитесь до Sinatra 1.2, которая будет получать все
|
1682
|
+
исправления ошибок до тех пор, пока не будет выпущена Sinatra 1.4.0
|
1748
1683
|
|
1749
1684
|
Мы также следим за предстоящими к выходу версиями Ruby.
|
1750
1685
|
|
@@ -1759,7 +1694,7 @@ Sinatra приложения могут быть запущены напряму
|
|
1759
1694
|
То, что версия официально не поддерживается, означает, что, если что-то не
|
1760
1695
|
работает на этой версии, а на поддерживаемой работает - это не наша проблема, а их.
|
1761
1696
|
|
1762
|
-
Мы также запускаем наши CI-тесты на последней версии Ruby (
|
1697
|
+
Мы также запускаем наши CI-тесты на последней версии Ruby (предстоящей 1.9.3),
|
1763
1698
|
но мы не можем ничего гарантировать, так как она постоянно развивается.
|
1764
1699
|
Предполагается, что 1.9.3p0 будет поддерживаться.
|
1765
1700
|
|
@@ -1768,7 +1703,7 @@ Sinatra должна работать на любой операционной
|
|
1768
1703
|
== На острие
|
1769
1704
|
|
1770
1705
|
Если вы хотите использовать самый последний код Sinatra, не бойтесь запускать
|
1771
|
-
свое приложение вместе из master ветки Sinatra, она весьма стабильна.
|
1706
|
+
свое приложение вместе с кодом из master ветки Sinatra, она весьма стабильна.
|
1772
1707
|
|
1773
1708
|
Мы также время от времени выпускаем предварительные версии, так что вы можете делать так:
|
1774
1709
|
|
@@ -1825,7 +1760,7 @@ Sinatra должна работать на любой операционной
|
|
1825
1760
|
rake sinatra.gemspec
|
1826
1761
|
rake install
|
1827
1762
|
|
1828
|
-
Если вы устанавливаете пакеты (gem) от пользователя root, то вашим
|
1763
|
+
Если вы устанавливаете пакеты (gem) от пользователя root, то вашим следующим шагом должна быть команда
|
1829
1764
|
|
1830
1765
|
sudo rake install
|
1831
1766
|
|
@@ -1842,4 +1777,9 @@ SemVerTag.
|
|
1842
1777
|
* {Слежение за проблемами/ошибками}[http://github.com/sinatra/sinatra/issues]
|
1843
1778
|
* {Twitter}[http://twitter.com/sinatra]
|
1844
1779
|
* {Группы рассылки}[http://groups.google.com/group/sinatrarb/topics]
|
1845
|
-
* {IRC: #sinatra}[irc://chat.freenode.net/#sinatra]
|
1780
|
+
* {IRC: #sinatra}[irc://chat.freenode.net/#sinatra] на http://freenode.net
|
1781
|
+
* {Sinatra Book}[http://sinatra-book.gittr.com] учебник и сборник рецептов
|
1782
|
+
* {Sinatra Book Contrib}[http://sinatra-book-contrib.com/] сборник рецептов
|
1783
|
+
* API документация к {последнему релизу}[http://rubydoc.info/gems/sinatra]
|
1784
|
+
или {текущему HEAD}[http://rubydoc.info/github/sinatra/sinatra] на
|
1785
|
+
http://rubydoc.info
|