roda 3.28.0 → 3.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG +40 -0
- data/README.rdoc +15 -1
- data/doc/conventions.rdoc +17 -8
- data/doc/release_notes/3.29.0.txt +15 -0
- data/doc/release_notes/3.30.0.txt +14 -0
- data/doc/release_notes/3.31.0.txt +11 -0
- data/doc/release_notes/3.32.0.txt +42 -0
- data/doc/release_notes/3.33.0.txt +8 -0
- data/lib/roda.rb +3 -0
- data/lib/roda/plugins/_symbol_regexp_matchers.rb +2 -0
- data/lib/roda/plugins/assets.rb +26 -5
- data/lib/roda/plugins/caching.rb +2 -0
- data/lib/roda/plugins/common_logger.rb +1 -1
- data/lib/roda/plugins/content_security_policy.rb +2 -0
- data/lib/roda/plugins/default_headers.rb +2 -0
- data/lib/roda/plugins/exception_page.rb +9 -5
- data/lib/roda/plugins/hash_matcher.rb +1 -1
- data/lib/roda/plugins/header_matchers.rb +5 -1
- data/lib/roda/plugins/indifferent_params.rb +4 -0
- data/lib/roda/plugins/partials.rb +33 -6
- data/lib/roda/plugins/path.rb +42 -15
- data/lib/roda/plugins/placeholder_string_matchers.rb +2 -0
- data/lib/roda/plugins/public.rb +25 -17
- data/lib/roda/plugins/relative_path.rb +73 -0
- data/lib/roda/plugins/render.rb +17 -5
- data/lib/roda/plugins/render_each.rb +11 -3
- data/lib/roda/plugins/run_append_slash.rb +1 -1
- data/lib/roda/plugins/symbol_matchers.rb +2 -2
- data/lib/roda/version.rb +1 -1
- metadata +13 -214
- data/Rakefile +0 -108
- data/doc/release_notes/1.0.0.txt +0 -329
- data/doc/release_notes/1.1.0.txt +0 -226
- data/doc/release_notes/1.2.0.txt +0 -406
- data/doc/release_notes/1.3.0.txt +0 -109
- data/doc/release_notes/2.0.0.txt +0 -75
- data/doc/release_notes/2.1.0.txt +0 -124
- data/doc/release_notes/2.10.0.txt +0 -27
- data/doc/release_notes/2.11.0.txt +0 -70
- data/doc/release_notes/2.12.0.txt +0 -40
- data/doc/release_notes/2.13.0.txt +0 -10
- data/doc/release_notes/2.14.0.txt +0 -44
- data/doc/release_notes/2.15.0.txt +0 -53
- data/doc/release_notes/2.16.0.txt +0 -48
- data/doc/release_notes/2.17.0.txt +0 -62
- data/doc/release_notes/2.18.0.txt +0 -69
- data/doc/release_notes/2.19.0.txt +0 -30
- data/doc/release_notes/2.2.0.txt +0 -97
- data/doc/release_notes/2.20.0.txt +0 -5
- data/doc/release_notes/2.21.0.txt +0 -17
- data/doc/release_notes/2.22.0.txt +0 -41
- data/doc/release_notes/2.23.0.txt +0 -29
- data/doc/release_notes/2.24.0.txt +0 -65
- data/doc/release_notes/2.25.0.txt +0 -14
- data/doc/release_notes/2.26.0.txt +0 -13
- data/doc/release_notes/2.27.0.txt +0 -56
- data/doc/release_notes/2.28.0.txt +0 -17
- data/doc/release_notes/2.29.0.txt +0 -156
- data/doc/release_notes/2.3.0.txt +0 -109
- data/doc/release_notes/2.4.0.txt +0 -55
- data/doc/release_notes/2.5.0.txt +0 -23
- data/doc/release_notes/2.5.1.txt +0 -4
- data/doc/release_notes/2.6.0.txt +0 -21
- data/doc/release_notes/2.7.0.txt +0 -75
- data/doc/release_notes/2.8.0.txt +0 -44
- data/doc/release_notes/2.9.0.txt +0 -6
- data/spec/all.rb +0 -1
- data/spec/assets/css/app.scss +0 -1
- data/spec/assets/css/no_access.css +0 -1
- data/spec/assets/css/raw.css +0 -1
- data/spec/assets/js/head/app.js +0 -1
- data/spec/composition_spec.rb +0 -31
- data/spec/define_roda_method_spec.rb +0 -274
- data/spec/env_spec.rb +0 -11
- data/spec/freeze_spec.rb +0 -37
- data/spec/integration_spec.rb +0 -209
- data/spec/matchers_spec.rb +0 -832
- data/spec/opts_spec.rb +0 -42
- data/spec/plugin/_after_hook_spec.rb +0 -19
- data/spec/plugin/all_verbs_spec.rb +0 -29
- data/spec/plugin/assets_preloading_spec.rb +0 -98
- data/spec/plugin/assets_spec.rb +0 -745
- data/spec/plugin/backtracking_array_spec.rb +0 -42
- data/spec/plugin/branch_locals_spec.rb +0 -106
- data/spec/plugin/caching_spec.rb +0 -337
- data/spec/plugin/chunked_spec.rb +0 -201
- data/spec/plugin/class_level_routing_spec.rb +0 -164
- data/spec/plugin/class_matchers_spec.rb +0 -40
- data/spec/plugin/common_logger_spec.rb +0 -85
- data/spec/plugin/content_for_spec.rb +0 -162
- data/spec/plugin/content_security_policy_spec.rb +0 -175
- data/spec/plugin/cookies_spec.rb +0 -51
- data/spec/plugin/csrf_spec.rb +0 -111
- data/spec/plugin/default_headers_spec.rb +0 -82
- data/spec/plugin/default_status_spec.rb +0 -95
- data/spec/plugin/delay_build_spec.rb +0 -23
- data/spec/plugin/delegate_spec.rb +0 -23
- data/spec/plugin/delete_empty_headers_spec.rb +0 -27
- data/spec/plugin/direct_call_spec.rb +0 -28
- data/spec/plugin/disallow_file_uploads_spec.rb +0 -25
- data/spec/plugin/drop_body_spec.rb +0 -24
- data/spec/plugin/early_hints_spec.rb +0 -19
- data/spec/plugin/empty_root_spec.rb +0 -14
- data/spec/plugin/environments_spec.rb +0 -42
- data/spec/plugin/error_email_spec.rb +0 -97
- data/spec/plugin/error_handler_spec.rb +0 -216
- data/spec/plugin/error_mail_spec.rb +0 -93
- data/spec/plugin/exception_page_spec.rb +0 -168
- data/spec/plugin/flash_spec.rb +0 -121
- data/spec/plugin/h_spec.rb +0 -11
- data/spec/plugin/halt_spec.rb +0 -119
- data/spec/plugin/hash_matcher_spec.rb +0 -27
- data/spec/plugin/hash_routes_spec.rb +0 -535
- data/spec/plugin/head_spec.rb +0 -52
- data/spec/plugin/header_matchers_spec.rb +0 -98
- data/spec/plugin/heartbeat_spec.rb +0 -74
- data/spec/plugin/hooks_spec.rb +0 -152
- data/spec/plugin/indifferent_params_spec.rb +0 -14
- data/spec/plugin/json_parser_spec.rb +0 -141
- data/spec/plugin/json_spec.rb +0 -83
- data/spec/plugin/mail_processor_spec.rb +0 -451
- data/spec/plugin/mailer_spec.rb +0 -282
- data/spec/plugin/match_affix_spec.rb +0 -43
- data/spec/plugin/match_hook_spec.rb +0 -79
- data/spec/plugin/middleware_spec.rb +0 -237
- data/spec/plugin/middleware_stack_spec.rb +0 -81
- data/spec/plugin/module_include_spec.rb +0 -48
- data/spec/plugin/multi_route_spec.rb +0 -268
- data/spec/plugin/multi_run_spec.rb +0 -87
- data/spec/plugin/multi_view_spec.rb +0 -50
- data/spec/plugin/multibyte_string_matcher_spec.rb +0 -44
- data/spec/plugin/named_templates_spec.rb +0 -96
- data/spec/plugin/not_allowed_spec.rb +0 -69
- data/spec/plugin/not_found_spec.rb +0 -128
- data/spec/plugin/optimized_string_matchers_spec.rb +0 -43
- data/spec/plugin/padrino_render_spec.rb +0 -34
- data/spec/plugin/param_matchers_spec.rb +0 -69
- data/spec/plugin/params_capturing_spec.rb +0 -33
- data/spec/plugin/partials_spec.rb +0 -43
- data/spec/plugin/pass_spec.rb +0 -29
- data/spec/plugin/path_matchers_spec.rb +0 -42
- data/spec/plugin/path_rewriter_spec.rb +0 -45
- data/spec/plugin/path_spec.rb +0 -222
- data/spec/plugin/placeholder_string_matchers_spec.rb +0 -126
- data/spec/plugin/precompile_templates_spec.rb +0 -61
- data/spec/plugin/public_spec.rb +0 -85
- data/spec/plugin/render_each_spec.rb +0 -82
- data/spec/plugin/render_locals_spec.rb +0 -114
- data/spec/plugin/render_spec.rb +0 -912
- data/spec/plugin/request_aref_spec.rb +0 -51
- data/spec/plugin/request_headers_spec.rb +0 -39
- data/spec/plugin/response_request_spec.rb +0 -43
- data/spec/plugin/route_block_args_spec.rb +0 -86
- data/spec/plugin/route_csrf_spec.rb +0 -305
- data/spec/plugin/run_append_slash_spec.rb +0 -77
- data/spec/plugin/run_handler_spec.rb +0 -53
- data/spec/plugin/sessions_spec.rb +0 -452
- data/spec/plugin/shared_vars_spec.rb +0 -45
- data/spec/plugin/sinatra_helpers_spec.rb +0 -537
- data/spec/plugin/slash_path_empty_spec.rb +0 -22
- data/spec/plugin/static_routing_spec.rb +0 -192
- data/spec/plugin/static_spec.rb +0 -30
- data/spec/plugin/status_303_spec.rb +0 -28
- data/spec/plugin/status_handler_spec.rb +0 -158
- data/spec/plugin/streaming_spec.rb +0 -246
- data/spec/plugin/strip_path_prefix_spec.rb +0 -24
- data/spec/plugin/symbol_matchers_spec.rb +0 -51
- data/spec/plugin/symbol_status_spec.rb +0 -25
- data/spec/plugin/symbol_views_spec.rb +0 -32
- data/spec/plugin/timestamp_public_spec.rb +0 -85
- data/spec/plugin/type_routing_spec.rb +0 -348
- data/spec/plugin/typecast_params_spec.rb +0 -1370
- data/spec/plugin/unescape_path_spec.rb +0 -22
- data/spec/plugin/view_options_spec.rb +0 -170
- data/spec/plugin_spec.rb +0 -71
- data/spec/redirect_spec.rb +0 -41
- data/spec/request_spec.rb +0 -97
- data/spec/response_spec.rb +0 -199
- data/spec/route_spec.rb +0 -39
- data/spec/session_middleware_spec.rb +0 -129
- data/spec/session_spec.rb +0 -37
- data/spec/spec_helper.rb +0 -137
- data/spec/version_spec.rb +0 -14
- data/spec/views/_test.erb +0 -1
- data/spec/views/a.erb +0 -1
- data/spec/views/a.rdoc +0 -2
- data/spec/views/about.erb +0 -1
- data/spec/views/about.str +0 -1
- data/spec/views/about/_test.css.gz +0 -0
- data/spec/views/about/_test.erb +0 -1
- data/spec/views/about/_test.erb.gz +0 -0
- data/spec/views/about/comp_test.erb +0 -1
- data/spec/views/b.erb +0 -1
- data/spec/views/c.erb +0 -1
- data/spec/views/comp_layout.erb +0 -1
- data/spec/views/comp_test.erb +0 -1
- data/spec/views/content-yield.erb +0 -1
- data/spec/views/each.str +0 -1
- data/spec/views/home.erb +0 -2
- data/spec/views/home.str +0 -2
- data/spec/views/iv.erb +0 -1
- data/spec/views/layout-alternative.erb +0 -2
- data/spec/views/layout-yield.erb +0 -3
- data/spec/views/layout.erb +0 -2
- data/spec/views/layout.str +0 -2
- data/spec/views/multiple-layout.erb +0 -1
- data/spec/views/multiple.erb +0 -1
data/doc/release_notes/1.1.0.txt
DELETED
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
= New Plugins
|
|
2
|
-
|
|
3
|
-
* An assets plugin has been added, for rendering your CSS and
|
|
4
|
-
javascript asset files on the fly in development, and compiling
|
|
5
|
-
them to a single, compressed file in production.
|
|
6
|
-
|
|
7
|
-
When loading the plugin, you just specify the assets to use via :css
|
|
8
|
-
and/or :js options:
|
|
9
|
-
|
|
10
|
-
plugin :assets, :css=>'some_file.scss', :js=>'some_file.coffee'
|
|
11
|
-
|
|
12
|
-
Inside your Roda.route block, you call r.assets to serve the assets:
|
|
13
|
-
|
|
14
|
-
route do |r|
|
|
15
|
-
r.assets
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
In your views, you can call the assets method, which returns strings
|
|
19
|
-
containing link/script tags for your assets:
|
|
20
|
-
|
|
21
|
-
<%= assets(:css) %>
|
|
22
|
-
<%= assets(:js) %>
|
|
23
|
-
|
|
24
|
-
In production mode, you call compile_assets after loading the
|
|
25
|
-
plugin, and it will compile all of the asset files into a single
|
|
26
|
-
file per type, optionally compress it (using yuicompressor), and
|
|
27
|
-
write the file to the public folder where it can be served by the
|
|
28
|
-
webserver. In compiled mode, calling assets in your views will
|
|
29
|
-
reference the compiled file.
|
|
30
|
-
|
|
31
|
-
It's possible to precompile your assets before application boot, so
|
|
32
|
-
they don't need to be compiled every time your application boots.
|
|
33
|
-
|
|
34
|
-
The assets plugin also supports asset groups, useful when different
|
|
35
|
-
sections of your application use different sets of assets.
|
|
36
|
-
|
|
37
|
-
* A chunked plugin has been added, for streaming template rendering
|
|
38
|
-
using Transfer-Encoding: chunked. By default, this flushes the
|
|
39
|
-
rendering of the top part of the layout template before rendering
|
|
40
|
-
the content template, allowing the client to load the assets
|
|
41
|
-
necessary to fully render the page while the content template is
|
|
42
|
-
still being rendered on the server. This can significantly decrease
|
|
43
|
-
client rendering times.
|
|
44
|
-
|
|
45
|
-
To use chunked encoding for a response, just call the chunked method
|
|
46
|
-
instead of view:
|
|
47
|
-
|
|
48
|
-
r.root do
|
|
49
|
-
chunked(:index)
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
If you want to execute code after flushing the top part of the layout
|
|
53
|
-
template, but before rendering the content template, pass a block to
|
|
54
|
-
chunked:
|
|
55
|
-
|
|
56
|
-
r.root do
|
|
57
|
-
chunked(:index) do
|
|
58
|
-
# expensive calculation here
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
If you want to use chunked encoding for all responses, pass the
|
|
63
|
-
:chunk_by_default option when loading the plugin:
|
|
64
|
-
|
|
65
|
-
plugin :chunked, :chunk_by_default => true
|
|
66
|
-
|
|
67
|
-
Inside your layout or content templates, you can call the flush method
|
|
68
|
-
to flush the current result of the template to the user, useful for
|
|
69
|
-
streaming large datasets.
|
|
70
|
-
|
|
71
|
-
<% (1..100).each do |i| %>
|
|
72
|
-
<%= i %>
|
|
73
|
-
<% sleep 0.1 %>
|
|
74
|
-
<% flush %>
|
|
75
|
-
<% end %>
|
|
76
|
-
|
|
77
|
-
* A caching plugin has been added, for simple HTTP caching support.
|
|
78
|
-
The implementation is based on Sinatra's, and offers
|
|
79
|
-
r.last_modifed and r.etag methods for conditional responses:
|
|
80
|
-
|
|
81
|
-
r.get '/albums/:d' do |album_id|
|
|
82
|
-
@album = Album[album_id]
|
|
83
|
-
r.last_modified @album.updated_at
|
|
84
|
-
r.etag @album.sha1
|
|
85
|
-
view('album')
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
This also adds response.cache_control and response.expires methods
|
|
89
|
-
for setting the Cache-Control/Expires headers for the response.
|
|
90
|
-
|
|
91
|
-
* A path plugin has been added for simple support for named paths:
|
|
92
|
-
|
|
93
|
-
plugin :path
|
|
94
|
-
path :foo, '/foo' # foo_path => '/foo'
|
|
95
|
-
path :bar do |bar| # bar_path(bar) => '/bar/1'
|
|
96
|
-
"/bar/#{bar.id}"
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
* An error_email plugin has been added, for easily emailing error
|
|
100
|
-
notifications for an exception. This is designed for use with
|
|
101
|
-
the error_handler plugin, and should only be used in low-traffic
|
|
102
|
-
environments:
|
|
103
|
-
|
|
104
|
-
plugin :error_email, :to=>'to@example.com',
|
|
105
|
-
:from=>'from@example.com'
|
|
106
|
-
plugin :error_handler do |e|
|
|
107
|
-
error_email(e)
|
|
108
|
-
'Internal Server Error'
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
= multi_route Plugin Improvements
|
|
112
|
-
|
|
113
|
-
* The multi_route plugin now supports namespaces, allowing it to
|
|
114
|
-
support routing trees of arbitrary complexity. Previously, only
|
|
115
|
-
a single namespace was supported. For example, if you want
|
|
116
|
-
to store your named routes in a directory tree:
|
|
117
|
-
|
|
118
|
-
/routes/foo.rb
|
|
119
|
-
/routes/foo/baz.rb
|
|
120
|
-
/routes/foo/quux.rb
|
|
121
|
-
/routes/bar.rb
|
|
122
|
-
/routes/bar/baz.rb
|
|
123
|
-
/routes/bar/quux.rb
|
|
124
|
-
|
|
125
|
-
You can load all of the routing files in the routes subdirectory
|
|
126
|
-
tree, and structure your routing tree as follows:
|
|
127
|
-
|
|
128
|
-
# app.rb
|
|
129
|
-
route do |r|
|
|
130
|
-
r.multi_route
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
# routes/foo.rb
|
|
134
|
-
route('foo') do |r|
|
|
135
|
-
check_foo_access!
|
|
136
|
-
r.multi_route('foo')
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
# routes/bar.rb
|
|
140
|
-
route('bar') do |r|
|
|
141
|
-
check_bar_access!
|
|
142
|
-
r.multi_route('bar')
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
# routes/foo/baz.rb
|
|
146
|
-
route('baz', 'foo') do
|
|
147
|
-
# ...
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
* Newly added named routes are now picked up while running, useful in
|
|
151
|
-
development when using code reloading.
|
|
152
|
-
|
|
153
|
-
* r.multi_route now ignores non-String named routes, allowing you to
|
|
154
|
-
only dispatch to the String named routes. Previously, calling
|
|
155
|
-
r.multi_route when any non-String names routes were present resulted
|
|
156
|
-
in an error.
|
|
157
|
-
|
|
158
|
-
* r.multi_route now prefers longer routes to shorter routes if
|
|
159
|
-
routes have the same prefix. This can fix behavior if you have
|
|
160
|
-
named routes such as "foo" and "foo/bar".
|
|
161
|
-
|
|
162
|
-
* If you don't pass a block to r.multi_route, it will use the
|
|
163
|
-
return value of the named route as the block value to return,
|
|
164
|
-
instead of always returning nil.
|
|
165
|
-
|
|
166
|
-
= Optimizations
|
|
167
|
-
|
|
168
|
-
* Dispatch speed is slightly improved by using allocate instead of
|
|
169
|
-
new to create new instances.
|
|
170
|
-
|
|
171
|
-
* Hash allocations in the render plugin have been reduced.
|
|
172
|
-
|
|
173
|
-
= Other Improvements
|
|
174
|
-
|
|
175
|
-
* The Roda.route block is now inherited when subclassing, making
|
|
176
|
-
it possible to subclass a Roda application and have the subclass
|
|
177
|
-
work without adding a route block.
|
|
178
|
-
|
|
179
|
-
* Middleware added to a Roda app after the Roda.route method is
|
|
180
|
-
called are now used instead of being ignored.
|
|
181
|
-
|
|
182
|
-
* A response.finish_with_body method has been added, for overriding
|
|
183
|
-
the response body to use. This is useful if you want to support
|
|
184
|
-
arbitrary response bodies.
|
|
185
|
-
|
|
186
|
-
* The render plugin now defaults the locals argument to an empty
|
|
187
|
-
frozen hash instead of nil when rendering templates via tilt.
|
|
188
|
-
This is faster as it avoids a hash allocation inside tilt, and
|
|
189
|
-
also works with broken external tilt templates that require that
|
|
190
|
-
the locals argument be a hash.
|
|
191
|
-
|
|
192
|
-
* Plugins that ship with Roda no longer set constants inside
|
|
193
|
-
InstanceMethods. Instead, the constants are set at the plugin
|
|
194
|
-
module level. This is done to avoid polluting the namespace of
|
|
195
|
-
the application with the constants. Roda's policy is that all
|
|
196
|
-
internal constants inside the Roda namespace are prefixed with
|
|
197
|
-
Roda, so they don't pollute the user's namespace, and setting
|
|
198
|
-
these constants inside InstanceMethods in plugins violated that
|
|
199
|
-
policy.
|
|
200
|
-
|
|
201
|
-
= Backwards Compatibility
|
|
202
|
-
|
|
203
|
-
* response.write no longer sets a Content-Length header. Instead,
|
|
204
|
-
response.finish sets it. This is faster if you call
|
|
205
|
-
response.write multiple times, and more correct if you call
|
|
206
|
-
response.finish without calling response.write.
|
|
207
|
-
|
|
208
|
-
* In the render plugin, modifying render_opts directly is now
|
|
209
|
-
deprecated and will raise an error in the next major release (the
|
|
210
|
-
hash will be frozen). Instead, users should call plugin :render
|
|
211
|
-
again with a new hash, which will be merged into the existing
|
|
212
|
-
render_opts hash.
|
|
213
|
-
|
|
214
|
-
* Moving plugin's constants from InstanceMethods to the plugin level
|
|
215
|
-
can break applications where the constant was referenced directly.
|
|
216
|
-
For example, if you were doing:
|
|
217
|
-
|
|
218
|
-
Roda::SESSION_KEY
|
|
219
|
-
|
|
220
|
-
to get the constant for the session key, you would now need to use:
|
|
221
|
-
|
|
222
|
-
Roda::RodaPlugins::Base::SESSION_KEY
|
|
223
|
-
|
|
224
|
-
In general, it is recommended to not reference such constants at
|
|
225
|
-
all. If you think there should be a general reason to access them,
|
|
226
|
-
request that a method is added that returns them.
|
data/doc/release_notes/1.2.0.txt
DELETED
|
@@ -1,406 +0,0 @@
|
|
|
1
|
-
= New Plugins
|
|
2
|
-
|
|
3
|
-
* A static_path_info plugin has been added, which doesn't modify
|
|
4
|
-
SCRIPT_NAME/PATH_INFO during routing, only before dispatching
|
|
5
|
-
the request to another rack application via r.run. This is
|
|
6
|
-
faster and avoids problems caused by changing SCRIPT_NAME/PATH_INFO
|
|
7
|
-
during routing, such as methods that return paths that depend on
|
|
8
|
-
SCRIPT_NAME. This behavior will become Roda's default starting
|
|
9
|
-
in Roda 2, and it is recommended that all Roda apps use it.
|
|
10
|
-
|
|
11
|
-
* A mailer plugin has been added, which allows you to use Roda's
|
|
12
|
-
render plugin to create email bodies, and allows you to use Roda's
|
|
13
|
-
routing tree features to DRY up your mailing code similar to how it
|
|
14
|
-
DRYs up your web code.
|
|
15
|
-
|
|
16
|
-
Here is an example routing tree using the mailer plugin:
|
|
17
|
-
|
|
18
|
-
class Mailer < Roda
|
|
19
|
-
plugin :render
|
|
20
|
-
plugin :mailer
|
|
21
|
-
|
|
22
|
-
route do |r|
|
|
23
|
-
r.on "user/:d" do |user_id|
|
|
24
|
-
# DRY up code by setting shared behavior in higher level
|
|
25
|
-
# branches, instead of duplicating it inside each subtree.
|
|
26
|
-
@user = User[user_id]
|
|
27
|
-
from 'notifications@example.com'
|
|
28
|
-
to @user.email
|
|
29
|
-
|
|
30
|
-
r.mail "open_account" do
|
|
31
|
-
subject 'Welcome to example.com'
|
|
32
|
-
render(:open_account)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
r.mail "close_account" do
|
|
36
|
-
subject 'Thank you for using example.com'
|
|
37
|
-
render(:close_account)
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
With your routing tree setup, you can use the sendmail method to
|
|
44
|
-
send email:
|
|
45
|
-
|
|
46
|
-
Mailer.sendmail("/user/1/open_account")
|
|
47
|
-
|
|
48
|
-
If you want a Mail::Message object returned for further modification
|
|
49
|
-
before sending, you can use mail instead of of sendmail:
|
|
50
|
-
|
|
51
|
-
Mailer.mail("/user/2/close_account").deliver
|
|
52
|
-
|
|
53
|
-
* A delegate plugin has been added, allowing you to easily create
|
|
54
|
-
methods in the route block scope that delegate to the request or
|
|
55
|
-
response. While Roda does not pollute your namespaces by default,
|
|
56
|
-
this allows you to choose to do so yourself if you find it offers
|
|
57
|
-
a nicer API. Example:
|
|
58
|
-
|
|
59
|
-
class App < Roda
|
|
60
|
-
plugin :delegate
|
|
61
|
-
request_delegate :root, :on, :is, :get, :post, :redirect
|
|
62
|
-
|
|
63
|
-
route do |r|
|
|
64
|
-
root do
|
|
65
|
-
redirect "/hello"
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
on "hello" do
|
|
69
|
-
get "world" do
|
|
70
|
-
"Hello world!"
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
is do
|
|
74
|
-
get do
|
|
75
|
-
"Hello!"
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
post do
|
|
79
|
-
puts "Someone said hello!"
|
|
80
|
-
redirect
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
* A class_level_routing plugin has been added, allowing you to define
|
|
88
|
-
your routes at the class level if desired. The routes defined at
|
|
89
|
-
the class level can still use a routing tree for further routing.
|
|
90
|
-
Example:
|
|
91
|
-
|
|
92
|
-
class App < Roda
|
|
93
|
-
plugin :class_level_routing
|
|
94
|
-
|
|
95
|
-
root do
|
|
96
|
-
request.redirect "/hello"
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
get "hello/world" do
|
|
100
|
-
"Hello world!"
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
is "hello" do
|
|
104
|
-
request.get do
|
|
105
|
-
"Hello!"
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
request.post do
|
|
109
|
-
puts "Someone said hello!"
|
|
110
|
-
request.redirect
|
|
111
|
-
end
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
* A named_templates plugin has been added, for creating inline
|
|
116
|
-
templates associated with a given name, that are used by
|
|
117
|
-
the render plugin's render/view method in preference to
|
|
118
|
-
templates stored in the filesystem. This makes it simpler to
|
|
119
|
-
ship single-file Roda applications that use templates. Example:
|
|
120
|
-
|
|
121
|
-
class App < Roda
|
|
122
|
-
plugin :named_templates
|
|
123
|
-
|
|
124
|
-
template :layout do
|
|
125
|
-
"<html><body><%= yield %></body></html>"
|
|
126
|
-
end
|
|
127
|
-
template :index do
|
|
128
|
-
"<p>Hello <%= @user %>!</p>"
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
route do |r|
|
|
132
|
-
@user = 'You'
|
|
133
|
-
render(:index)
|
|
134
|
-
end
|
|
135
|
-
# => "<html><body><p>Hello You!</p></body></html>"
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
* A multi_run plugin has been added, for dispatching to multiple
|
|
139
|
-
rack applications based on the request path prefix. This
|
|
140
|
-
provides a similar API as the multi_route plugin, but allows
|
|
141
|
-
you to separate your applications per routing subtree, as
|
|
142
|
-
opposed to multi_route which uses the same application for
|
|
143
|
-
all routing subtrees.
|
|
144
|
-
|
|
145
|
-
With the multi_run plugin, you call the class level run method
|
|
146
|
-
with the routing prefix and the rack application to use, and
|
|
147
|
-
you call r.multi_run to dispatch to all of the applications
|
|
148
|
-
based on the prefix.
|
|
149
|
-
|
|
150
|
-
class App < Roda
|
|
151
|
-
plugin :multi_run
|
|
152
|
-
|
|
153
|
-
run "foo", Foo
|
|
154
|
-
run "bar", Bar
|
|
155
|
-
run "baz", Baz
|
|
156
|
-
|
|
157
|
-
route do |r|
|
|
158
|
-
r.multi_run
|
|
159
|
-
end
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
In this case, Foo, Bar, and Baz, can be subclasses of App, which
|
|
163
|
-
allows them to share methods that should be shared, but still
|
|
164
|
-
define methods themselves that are not shared by the other
|
|
165
|
-
applications.
|
|
166
|
-
|
|
167
|
-
* A sinatra_helpers plugin has been added, that ports over most
|
|
168
|
-
of the Sinatra::Helpers methods that haven't already been added
|
|
169
|
-
by other plugins. All of the methods are added either to the
|
|
170
|
-
request or response class as appropriate. By default, delegate
|
|
171
|
-
methods are also added to the route block scope, but you can
|
|
172
|
-
turn this off by passing a :delegate=>false option when loading
|
|
173
|
-
the plugin, which avoids polluting the route block namespace.
|
|
174
|
-
|
|
175
|
-
The sinatra_helpers plugin adds the following request methods:
|
|
176
|
-
|
|
177
|
-
* back
|
|
178
|
-
* error
|
|
179
|
-
* not_found
|
|
180
|
-
* uri
|
|
181
|
-
* send_file
|
|
182
|
-
|
|
183
|
-
And the following response methods:
|
|
184
|
-
|
|
185
|
-
* body
|
|
186
|
-
* body=
|
|
187
|
-
* status
|
|
188
|
-
* headers
|
|
189
|
-
* mime_type
|
|
190
|
-
* content_type
|
|
191
|
-
* attachment
|
|
192
|
-
* informational?
|
|
193
|
-
* success?
|
|
194
|
-
* redirect?
|
|
195
|
-
* client_error?
|
|
196
|
-
* not_found?
|
|
197
|
-
* server_error?
|
|
198
|
-
|
|
199
|
-
* A slash_path_empty plugin has been added, which changes Roda
|
|
200
|
-
so that "/" is considered an empty path when doing a
|
|
201
|
-
terminal match via r.is or r.get/r.post with a path.
|
|
202
|
-
|
|
203
|
-
class App < Roda
|
|
204
|
-
plugin :slash_path_empty
|
|
205
|
-
|
|
206
|
-
route do |r|
|
|
207
|
-
r.get "albums" do
|
|
208
|
-
# matches both GET /albums and GET /albums/
|
|
209
|
-
end
|
|
210
|
-
end
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
* An empty_root plugin has been added, which makes r.root match
|
|
214
|
-
the empty string, in addition to /. This can be useful in
|
|
215
|
-
cases where a partial match on the patch has been completed.
|
|
216
|
-
|
|
217
|
-
class App < Roda
|
|
218
|
-
plugin :empty_root
|
|
219
|
-
|
|
220
|
-
route do |r|
|
|
221
|
-
r.on "albums" do
|
|
222
|
-
r.root do
|
|
223
|
-
# matches both GET /albums and GET /albums/
|
|
224
|
-
end
|
|
225
|
-
end
|
|
226
|
-
end
|
|
227
|
-
end
|
|
228
|
-
|
|
229
|
-
* A match_affix plugin has been added, for overriding the default
|
|
230
|
-
prefix/suffix used in match patterns. For example, if you want
|
|
231
|
-
to require that a leading / be specified in your routes. and
|
|
232
|
-
you want to consume any trailing slash:
|
|
233
|
-
|
|
234
|
-
class App < Roda
|
|
235
|
-
plugin :match_affix, "", /(\/|\z)/
|
|
236
|
-
|
|
237
|
-
route do |r|
|
|
238
|
-
r.on "/albums" do |s|
|
|
239
|
-
# GET /albums # s => ""
|
|
240
|
-
# GET /albums/ # s => "/"
|
|
241
|
-
end
|
|
242
|
-
end
|
|
243
|
-
end
|
|
244
|
-
|
|
245
|
-
* An environments plugin has been added, giving some simple
|
|
246
|
-
helpers for executing code in different environments. Example:
|
|
247
|
-
|
|
248
|
-
class App < Roda
|
|
249
|
-
plugin :environments
|
|
250
|
-
|
|
251
|
-
environment # => :development
|
|
252
|
-
development? # => true
|
|
253
|
-
test? # => false
|
|
254
|
-
production? # => false
|
|
255
|
-
|
|
256
|
-
# Set the environment for the application
|
|
257
|
-
self.environment = :test
|
|
258
|
-
test? # => true
|
|
259
|
-
|
|
260
|
-
configure do
|
|
261
|
-
# called, as no environments given
|
|
262
|
-
end
|
|
263
|
-
|
|
264
|
-
configure :development, :production do
|
|
265
|
-
# not called, as no environments match
|
|
266
|
-
end
|
|
267
|
-
|
|
268
|
-
configure :test do
|
|
269
|
-
# called, as environment given matches current environment
|
|
270
|
-
end
|
|
271
|
-
end
|
|
272
|
-
|
|
273
|
-
* A drop_body plugin has been added, which automatically drops the
|
|
274
|
-
body, Content-Type header, and Content-Length header when the
|
|
275
|
-
response status indicates no body (100-102, 204, 205, 304).
|
|
276
|
-
|
|
277
|
-
* A delay_build plugin has been added, which delays building the
|
|
278
|
-
rack application until Roda.app is called, and only rebuilds the
|
|
279
|
-
rack application if build! is called. This removes O(n^2)
|
|
280
|
-
performance in the pathological case of adding a route block
|
|
281
|
-
and then calling Roda.use many times to add middlewares, though
|
|
282
|
-
you have to add a few hundred middlewares for the difference
|
|
283
|
-
to be noticeable.
|
|
284
|
-
|
|
285
|
-
= New Features
|
|
286
|
-
|
|
287
|
-
* r.remaining_path and r.matched_path have been added for returning
|
|
288
|
-
the remaining path that will be used for matching, and for
|
|
289
|
-
returning the path already matched. Currently, these just provide
|
|
290
|
-
the PATH_INFO and SCRIPT_NAME, but starting in Roda 2 PATH_INFO
|
|
291
|
-
and SCRIPT_NAME will not be modified during routing, and you'll
|
|
292
|
-
need to use these methods if you want to find out the remaining
|
|
293
|
-
or already matched paths.
|
|
294
|
-
|
|
295
|
-
* The render plugin now supports a :template option to render/view
|
|
296
|
-
to specify the template to use, instead of requiring a separate
|
|
297
|
-
argument.
|
|
298
|
-
|
|
299
|
-
* The render plugin now supports a :template_class option, allowing
|
|
300
|
-
you to override the default template class that Roda would use.
|
|
301
|
-
|
|
302
|
-
* The render plugin now supports a :template_block option, specifying
|
|
303
|
-
the block to pass when creating a template.
|
|
304
|
-
|
|
305
|
-
* The path class method added by the path plugin now accepts :name,
|
|
306
|
-
:url, :url_only, and :add_script_name options:
|
|
307
|
-
|
|
308
|
-
:name :: Specifies name for method
|
|
309
|
-
:url :: Creates a url method in addition to a path method
|
|
310
|
-
:url_only :: Only creates a url method, not a path method
|
|
311
|
-
:add_script_name :: prefixes the path with SCRIPT_NAME
|
|
312
|
-
|
|
313
|
-
Note that if you plan to use :add_script_name, you should use
|
|
314
|
-
the static_path_info plugin so that the method created does not
|
|
315
|
-
return different results depending on where you are in the
|
|
316
|
-
routing tree.
|
|
317
|
-
|
|
318
|
-
* A :user_agent hash matcher has been added to the header_matchers
|
|
319
|
-
plugin.
|
|
320
|
-
|
|
321
|
-
* An inherit_middleware class accessor has been added. This can
|
|
322
|
-
be set to false if you do not want subclasses to inherit
|
|
323
|
-
middleware from the superclass. This is useful if the
|
|
324
|
-
superclass dispatches to the subclass via r.run, as otherwise
|
|
325
|
-
it would have to run the same middleware stack twice.
|
|
326
|
-
|
|
327
|
-
* A clear_middleware! class accessor has been added, allowing
|
|
328
|
-
you to clear the current middleware stack.
|
|
329
|
-
|
|
330
|
-
* RodaRequest#default_redirect_status has been added, allowing
|
|
331
|
-
plugins to override the default status used for redirect if
|
|
332
|
-
a status is not given.
|
|
333
|
-
|
|
334
|
-
* Roda{Request,Response}#roda_class has been added, which
|
|
335
|
-
returns the Roda class related to the given request/response.
|
|
336
|
-
|
|
337
|
-
= Other Improvements
|
|
338
|
-
|
|
339
|
-
* The render plugin no longer caches templates by default if
|
|
340
|
-
RACK_ENV is development.
|
|
341
|
-
|
|
342
|
-
* When subclassing a Roda app, unfrozen Array/Hash entries in the
|
|
343
|
-
opts hash are now duped into the subclass, so the subclass
|
|
344
|
-
no longer needs to dup them manually. Note that plugins that
|
|
345
|
-
use nested arrays/hashes in the opts hash still need to dup
|
|
346
|
-
manually inside ClassMethods#inherited. For the plugins where
|
|
347
|
-
it is possible, it is recommended to store plugin options in a
|
|
348
|
-
frozen object in the opts hash, and require loading the plugin
|
|
349
|
-
again to modify the plugin options.
|
|
350
|
-
|
|
351
|
-
* Caching of templates is now fixed when the render/view :opts is
|
|
352
|
-
used to specify template options per-call.
|
|
353
|
-
|
|
354
|
-
* An explicit :default_encoding of nil in the render plugin's
|
|
355
|
-
:opts hash is no longer overwritten with
|
|
356
|
-
Encoding.default_external.
|
|
357
|
-
|
|
358
|
-
* Roda#session now returns the same object as RodaRequest#session.
|
|
359
|
-
|
|
360
|
-
* The view_subdirs, content_for, and render_each plugins now all
|
|
361
|
-
depend on the render plugin.
|
|
362
|
-
|
|
363
|
-
* The not_allowed plugin now depends on the all_verbs plugin.
|
|
364
|
-
|
|
365
|
-
* Local/instance variables are now used in more places instead of
|
|
366
|
-
method calls, improving performance.
|
|
367
|
-
|
|
368
|
-
= Backwards Compatibility
|
|
369
|
-
|
|
370
|
-
* The render plugin's render/view methods no longer pass the given
|
|
371
|
-
hash directly to the underlying template. To pass options to the
|
|
372
|
-
template engine, use a separate hash under the :opts key:
|
|
373
|
-
|
|
374
|
-
render :file, :opts=>{:foo=>'bar'}
|
|
375
|
-
|
|
376
|
-
This is more consistent with the class-level render plugin options,
|
|
377
|
-
which also uses :opts to pass options to the template engine.
|
|
378
|
-
|
|
379
|
-
The :js_opts and :css_opts options to the assets plugin are now
|
|
380
|
-
passed as the :opts hash, so they continue to affect the template
|
|
381
|
-
engine, so they no longer specify general render method options.
|
|
382
|
-
|
|
383
|
-
* Modifying render_opts :layout after loading the render plugin
|
|
384
|
-
now has no effect. You need to use plugin :render, :layout=>'...'
|
|
385
|
-
to set the layout to use now.
|
|
386
|
-
|
|
387
|
-
* Default headers are not set on a response until the response is
|
|
388
|
-
finished. This allows you to check for header presence during
|
|
389
|
-
routing to detect whether the header was specifically set for the
|
|
390
|
-
current request.
|
|
391
|
-
|
|
392
|
-
* RodaRequest.consume_pattern no longer captures anything by default.
|
|
393
|
-
Previously, it did so in order to update SCRIPT_NAME, but that is
|
|
394
|
-
now handled differently. This should only affect external plugins
|
|
395
|
-
that attempt to override RodaRequest#consume.
|
|
396
|
-
|
|
397
|
-
* RodaRequest.def_verb_method has been removed.
|
|
398
|
-
|
|
399
|
-
* The hooks, default_headers, json, and multi_route plugins all store
|
|
400
|
-
their class-level metadata in the opts hash instead of separate
|
|
401
|
-
class instance variables. This should have no affect unless you
|
|
402
|
-
were accessing the class instance variables directly.
|
|
403
|
-
|
|
404
|
-
* The render plugin internals changed significantly, it now passes
|
|
405
|
-
internal data using a hash. This should only affect users that
|
|
406
|
-
were overriding render plugin methods.
|