roda 1.0.0 → 1.1.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 +34 -0
- data/README.rdoc +18 -13
- data/Rakefile +8 -0
- data/doc/conventions.rdoc +163 -0
- data/doc/release_notes/1.1.0.txt +226 -0
- data/lib/roda.rb +51 -22
- data/lib/roda/plugins/assets.rb +613 -0
- data/lib/roda/plugins/caching.rb +215 -0
- data/lib/roda/plugins/chunked.rb +278 -0
- data/lib/roda/plugins/error_email.rb +112 -0
- data/lib/roda/plugins/flash.rb +3 -3
- data/lib/roda/plugins/hooks.rb +1 -1
- data/lib/roda/plugins/indifferent_params.rb +3 -3
- data/lib/roda/plugins/middleware.rb +3 -8
- data/lib/roda/plugins/multi_route.rb +110 -18
- data/lib/roda/plugins/not_allowed.rb +3 -3
- data/lib/roda/plugins/path.rb +38 -0
- data/lib/roda/plugins/render.rb +18 -16
- data/lib/roda/plugins/render_each.rb +0 -2
- data/lib/roda/plugins/streaming.rb +1 -2
- data/lib/roda/plugins/view_subdirs.rb +7 -1
- data/lib/roda/version.rb +1 -1
- data/spec/assets/css/app.scss +1 -0
- data/spec/assets/css/no_access.css +1 -0
- data/spec/assets/css/raw.css +1 -0
- data/spec/assets/js/head/app.js +1 -0
- data/spec/integration_spec.rb +95 -3
- data/spec/matchers_spec.rb +2 -2
- data/spec/plugin/assets_spec.rb +413 -0
- data/spec/plugin/caching_spec.rb +335 -0
- data/spec/plugin/chunked_spec.rb +182 -0
- data/spec/plugin/default_headers_spec.rb +6 -5
- data/spec/plugin/error_email_spec.rb +76 -0
- data/spec/plugin/multi_route_spec.rb +120 -0
- data/spec/plugin/not_allowed_spec.rb +14 -3
- data/spec/plugin/path_spec.rb +29 -0
- data/spec/plugin/render_each_spec.rb +6 -1
- data/spec/plugin/symbol_matchers_spec.rb +7 -2
- data/spec/request_spec.rb +10 -0
- data/spec/response_spec.rb +47 -0
- data/spec/views/about.erb +1 -0
- data/spec/views/about.str +1 -0
- data/spec/views/content-yield.erb +1 -0
- data/spec/views/home.erb +2 -0
- data/spec/views/home.str +2 -0
- data/spec/views/layout-alternative.erb +2 -0
- data/spec/views/layout-yield.erb +3 -0
- data/spec/views/layout.erb +2 -0
- data/spec/views/layout.str +2 -0
- metadata +57 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 75b82517a1e80d73d99ea7d25a8bd543ba958e7c
|
4
|
+
data.tar.gz: 4bcb31a61b7f2658092fe80fb339a8651b718edd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a8d8776bd1e9c282dc6d5df795a790a2272103421125233ffe5f6112c77c99d00f37f364c7879b73eb03aafd2c946e45e123c0e261f3ff7f1b576936a986e1ee
|
7
|
+
data.tar.gz: f8b85158682a132cd00d2a929532bb466a15c502f94abd54afcdaad35dde2fab96a2e2ff6d5b180b62220a6e0944de5ac824c0c25285bd04a8e8d39f959ad171
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,37 @@
|
|
1
|
+
= 1.1.0 (2014-11-11)
|
2
|
+
|
3
|
+
* Add assets plugin, for rendering assets on the fly, or compiling them to a single compressed file (cj, jeremyevans) (#5)
|
4
|
+
|
5
|
+
* Make InstanceMethods in plugins not include constants, as they would pollute the constant namespace (jeremyevans)
|
6
|
+
|
7
|
+
* Make response.finish add the Content-Length header, not response.write (jeremyevans)
|
8
|
+
|
9
|
+
* Add response.finish_with_body to override response body used (jeremyevans)
|
10
|
+
|
11
|
+
* Use allocate instead of new in rack app (jeremyevans)
|
12
|
+
|
13
|
+
* Add chunked plugin, for easy streaming of template responses using Transfer-Encoding: chunked (jeremyevans)
|
14
|
+
|
15
|
+
* Add namespace support to the multi_route plugin, to support more complex applications (jeremyevans)
|
16
|
+
|
17
|
+
* Make r.multi_route use named route return value if not passed a block (jeremyevans)
|
18
|
+
|
19
|
+
* Make r.multi_route prefer longer route if multiple routes have the same prefix (jeremyevans)
|
20
|
+
|
21
|
+
* Add caching plugin, for handling http caching (jeremyevans)
|
22
|
+
|
23
|
+
* Support adding middleware after the route block has been added (jeremyevans)
|
24
|
+
|
25
|
+
* Allow Roda subclasses to use route block from superclass (jeremyevans)
|
26
|
+
|
27
|
+
* Have r.multi_route ignore non-String named routes (jeremyevans)
|
28
|
+
|
29
|
+
* Pick up newly added named routes while running in the multi_route plugin, useful for development (jeremyevans)
|
30
|
+
|
31
|
+
* Add path plugin, for named path support (jeremyevans) (#4)
|
32
|
+
|
33
|
+
* Add error_email plugin, for easily emailing an error notification for an exception (jeremyevans)
|
34
|
+
|
1
35
|
= 1.0.0 (2014-08-19)
|
2
36
|
|
3
37
|
* Don't have :extension hash matcher force a terminal match (jeremyevans)
|
data/README.rdoc
CHANGED
@@ -691,17 +691,17 @@ attempt to render the template inside the default layout template, where
|
|
691
691
|
end
|
692
692
|
end
|
693
693
|
|
694
|
-
You can override the default rendering options by passing a hash to the plugin
|
695
|
-
or modifying the +render_opts+ hash after loading the plugin:
|
694
|
+
You can override the default rendering options by passing a hash to the plugin:
|
696
695
|
|
697
696
|
class App < Roda
|
698
|
-
plugin :render,
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
697
|
+
plugin :render,
|
698
|
+
:cache => false, # Disable template caching, useful in development
|
699
|
+
:engine => 'erb', # Tilt engine/template file extension to use
|
700
|
+
:escape => true, # Automatically escape output in erb templates
|
701
|
+
:layout => "admin_layout", # Default layout template
|
702
|
+
:layout_opts => {:ext=>'html.erb'}, # Default layout template options
|
703
|
+
:opts => {:default_encoding=>'UTF-8'}, # Default template options
|
704
|
+
:views => 'admin_views' # Default views directory
|
705
705
|
end
|
706
706
|
|
707
707
|
== Sessions
|
@@ -755,10 +755,6 @@ default, so that in your templates:
|
|
755
755
|
<%= '<>' %> # outputs <>
|
756
756
|
<%== '<>' %> # outputs <>
|
757
757
|
|
758
|
-
Note that unlike most other render options, the :escape option
|
759
|
-
must be passed to the <tt>plugin :render</tt> call, it won't be
|
760
|
-
respected if added later.
|
761
|
-
|
762
758
|
This support requires {Erubis}[http://www.kuwata-lab.com/erubis/].
|
763
759
|
|
764
760
|
=== Other
|
@@ -785,13 +781,21 @@ override any Roda method and call +super+ to get the default behavior.
|
|
785
781
|
These plugins ship with roda:
|
786
782
|
|
787
783
|
all_verbs :: Adds routing methods to the request for all http verbs.
|
784
|
+
assets :: Adds support for rendering CSS/JS javascript assets on the fly
|
785
|
+
in development, or compiling them into a single compressed file
|
786
|
+
in production.
|
788
787
|
backtracking_array :: Allows array matchers to backtrack if later matchers
|
789
788
|
do not match.
|
789
|
+
caching :: Adds request and response methods related to http caching.
|
790
|
+
chunked :: Adds support for streaming template responses using
|
791
|
+
Transfer-Encoding: chunked.
|
790
792
|
content_for :: Allows storage of content in one template and retrieval of
|
791
793
|
that content in a different template.
|
792
794
|
csrf :: Adds CSRF protection and helper methods using
|
793
795
|
{rack_csrf}[https://github.com/baldowl/rack_csrf].
|
794
796
|
default_headers :: Override the default response headers used.
|
797
|
+
error_email :: Adds an +error_email+ method that can be used to email when
|
798
|
+
an exception is raised.
|
795
799
|
error_handler :: Adds a +error+ block that is called for all responses that
|
796
800
|
raise exceptions.
|
797
801
|
flash :: Adds a flash handler.
|
@@ -815,6 +819,7 @@ not_found :: Adds a +not_found+ block that is called for all 404 responses
|
|
815
819
|
without bodies.
|
816
820
|
pass :: Adds a pass method allowing you to skip the current +r.on+ block as if
|
817
821
|
it did not match.
|
822
|
+
path :: Adds support for named paths.
|
818
823
|
per_thread_caching :: Switches the thread-safe cache from a shared cache to a
|
819
824
|
per-thread cache.
|
820
825
|
render :: Adds support for rendering templates via tilt, as described above.
|
data/Rakefile
CHANGED
@@ -82,6 +82,14 @@ begin
|
|
82
82
|
spec = lambda do |name, files, d|
|
83
83
|
lib_dir = File.join(File.dirname(File.expand_path(__FILE__)), 'lib')
|
84
84
|
ENV['RUBYLIB'] ? (ENV['RUBYLIB'] += ":#{lib_dir}") : (ENV['RUBYLIB'] = lib_dir)
|
85
|
+
|
86
|
+
desc "#{d} with -w, some warnings filtered"
|
87
|
+
task "#{name}_w" do
|
88
|
+
ENV['RUBYOPT'] ? (ENV['RUBYOPT'] += " -w") : (ENV['RUBYOPT'] = '-w')
|
89
|
+
rake = ENV['RAKE'] || "#{FileUtils::RUBY} -S rake"
|
90
|
+
sh "#{rake} #{name} 2>&1 | egrep -v \"(spec/.*: warning: (possibly )?useless use of == in void context|: warning: instance variable @.* not initialized|: warning: method redefined; discarding old|: warning: previous definition of)|rspec\""
|
91
|
+
end
|
92
|
+
|
85
93
|
desc d
|
86
94
|
spec_class.new(name) do |t|
|
87
95
|
t.send spec_files_meth, files
|
@@ -0,0 +1,163 @@
|
|
1
|
+
= Conventions
|
2
|
+
|
3
|
+
This guide goes over conventions for directory layout and file layout for Roda applications.
|
4
|
+
You are free to ignore these conventions, but following them will make your code similar
|
5
|
+
to other Roda applications.
|
6
|
+
|
7
|
+
== Directory Layout
|
8
|
+
|
9
|
+
Which directory layout to use should reflect the size of your application.
|
10
|
+
|
11
|
+
=== Small Applications
|
12
|
+
|
13
|
+
For a small application, the following directory layout is recommended:
|
14
|
+
|
15
|
+
Rakefile
|
16
|
+
app_name.rb
|
17
|
+
assets/
|
18
|
+
migrate/
|
19
|
+
models.rb
|
20
|
+
models/
|
21
|
+
public/
|
22
|
+
spec/
|
23
|
+
views/
|
24
|
+
|
25
|
+
+app_name.rb+ should contain the Roda application, and should reflect the name of your application.
|
26
|
+
So if your application is named +FooBar+, you should use +foo_bar.rb+.
|
27
|
+
|
28
|
+
+views/+ should contain your template files. This assumes you are using the +render+ plugin
|
29
|
+
and server-side rendering. If you are creating a single page application and just serving
|
30
|
+
JSON, then you won't need a +views+ directory. For small applications, all view files should
|
31
|
+
in the +views+ directory.
|
32
|
+
|
33
|
+
+public/+ should contain any static files that should be served directly by the webserver.
|
34
|
+
Again, for pure JSON applications, you won't need a +public+ directory.
|
35
|
+
|
36
|
+
+assets/+ should contain the source files for your CSS and javascript assets. If you are
|
37
|
+
not using the +assets+ plugin, you won't need an +assets+ directory.
|
38
|
+
|
39
|
+
+models.rb+ should contain all code related to your database/ORM. This file should be required
|
40
|
+
by +app_name.rb+. This keeps your model code separate from your web code, making it easier
|
41
|
+
to use outside of your web code. It allows you to get an IRB shell for accessing your models
|
42
|
+
via <tt>irb -r ./models</tt>, without loading the Roda application.
|
43
|
+
|
44
|
+
+models/+ should contain your ORM models, with a separate file per model class.
|
45
|
+
|
46
|
+
+migrate/+ should create your database migration files, if you are using an ORM that uses
|
47
|
+
migrations.
|
48
|
+
|
49
|
+
+spec/+ should contain your specifications/tests. For a small application, it's recommended
|
50
|
+
to a have a single file for your model tests, and a single file for your web/integration tests.
|
51
|
+
|
52
|
+
+Rakefile+ should contain the rake tasks for the application. The convention is that the
|
53
|
+
default rake task will run all specs/tests related to the application. If you are using
|
54
|
+
the +assets+ plugin, you should have an <tt>assets:precompile</tt> task for precompiling
|
55
|
+
assets.
|
56
|
+
|
57
|
+
=== Large Applications
|
58
|
+
|
59
|
+
Large applications generally need more structure:
|
60
|
+
|
61
|
+
Rakefile
|
62
|
+
app_name.rb
|
63
|
+
assets/
|
64
|
+
helpers/
|
65
|
+
migrate/
|
66
|
+
models.rb
|
67
|
+
models/
|
68
|
+
public/
|
69
|
+
routes/
|
70
|
+
prefix1.rb
|
71
|
+
prefix2.rb
|
72
|
+
spec/
|
73
|
+
models/
|
74
|
+
web/
|
75
|
+
views/
|
76
|
+
prefix1/
|
77
|
+
prefix2/
|
78
|
+
|
79
|
+
For larger apps, the +Rakefile+, +assets/+, +migrate+, +models.rb+, +models/+, +public/+, remain the same.
|
80
|
+
|
81
|
+
+app_name.rb+ should use the +multi_route+ and +view_subdirs+ plugins. The routes used by the +multi_route+
|
82
|
+
plugin should be stored in routing files in the +routes/+ directory, with one file per prefix.
|
83
|
+
|
84
|
+
For specs/tests, you should have +spec/models/+ and +spec/web/+, with one file per model in +spec/models/+
|
85
|
+
and one file per prefix in +spec/web/+.
|
86
|
+
|
87
|
+
You should have a separate view subdirectory per prefix, and use +set_view_subdir+ in your routing files
|
88
|
+
to specify the subdirectory to use, so it doesn't need to be specified on every call to view.
|
89
|
+
|
90
|
+
+helpers/+ should be used to store helper methods for your application, that you call in your routing files
|
91
|
+
and views. In a small application, these methods should just be specified in +app_name.rb+
|
92
|
+
|
93
|
+
=== Really Large Applications
|
94
|
+
|
95
|
+
For very large applications, it's expected that there will be deviations from these conventions. However,
|
96
|
+
it is recommended to use namespaces in the +multi_route+ plugin, and have subdirectories in the +routes/+
|
97
|
+
directory, and nested subdirectories in the +views/+ directory.
|
98
|
+
|
99
|
+
== Roda Application File Layout
|
100
|
+
|
101
|
+
=== Small Applications
|
102
|
+
|
103
|
+
For a small application, the convention in Roda is to layout your Roda application file (+app_name.rb+) like this:
|
104
|
+
|
105
|
+
require 'roda'
|
106
|
+
require './models'
|
107
|
+
|
108
|
+
class AppName < Roda
|
109
|
+
SOME_CONSTANT = 1
|
110
|
+
|
111
|
+
use SomeMiddleware
|
112
|
+
|
113
|
+
plugin :render
|
114
|
+
plugin :assets
|
115
|
+
|
116
|
+
route do |r|
|
117
|
+
# ...
|
118
|
+
end
|
119
|
+
|
120
|
+
def view_method
|
121
|
+
'foo'
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
You should first require +roda+ and +./models+, followed by any other libraries needed by the
|
126
|
+
application.
|
127
|
+
|
128
|
+
You should subclass Roda and make the application's name the name of the Roda subclass.
|
129
|
+
Inside the subclass, you first define the constants used by the application. Then you add
|
130
|
+
any middleware used by the application, followed by loading any plugins used by the application.
|
131
|
+
Then you add the route block for the application. After the route block, define the instance methods
|
132
|
+
used in your route block or views.
|
133
|
+
|
134
|
+
=== Large Applications
|
135
|
+
|
136
|
+
For larger applications, there are some slight changes to the Roda application file layout:
|
137
|
+
|
138
|
+
require 'roda'
|
139
|
+
require './models'
|
140
|
+
|
141
|
+
class AppName < Roda
|
142
|
+
SOME_CONSTANT = 1
|
143
|
+
|
144
|
+
use SomeMiddleware
|
145
|
+
|
146
|
+
plugin :render
|
147
|
+
plugin :assets
|
148
|
+
plugin :view_subdirs
|
149
|
+
plugin :multi_route
|
150
|
+
Dir['./routes/*.rb'].each{|f| require f}
|
151
|
+
|
152
|
+
route do |r|
|
153
|
+
r.multi_route
|
154
|
+
end
|
155
|
+
|
156
|
+
Dir['./helpers/*.rb'].each{|f| require f}
|
157
|
+
end
|
158
|
+
|
159
|
+
After loading the +view_subdirs+ and +multi_route+ plugin, you require all of your
|
160
|
+
routing files. Inside your route block, instead of defining your routes, you just call
|
161
|
+
+r.multi_route+, which will dispatch to all of your routing files. After your route
|
162
|
+
block, you require all of your helper files containing the instance methods for your
|
163
|
+
route block or views, instead of defining the methods directly.
|
@@ -0,0 +1,226 @@
|
|
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.
|