roda 1.2.0 → 1.3.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 +42 -0
- data/README.rdoc +73 -144
- data/doc/conventions.rdoc +10 -8
- data/doc/release_notes/1.3.0.txt +109 -0
- data/lib/roda.rb +67 -100
- data/lib/roda/plugins/assets.rb +4 -4
- data/lib/roda/plugins/chunked.rb +4 -1
- data/lib/roda/plugins/class_level_routing.rb +7 -1
- data/lib/roda/plugins/cookies.rb +34 -0
- data/lib/roda/plugins/default_headers.rb +7 -6
- data/lib/roda/plugins/delegate.rb +8 -1
- data/lib/roda/plugins/delete_empty_headers.rb +33 -0
- data/lib/roda/plugins/delete_nil_headers.rb +34 -0
- data/lib/roda/plugins/environments.rb +12 -4
- data/lib/roda/plugins/error_email.rb +6 -1
- data/lib/roda/plugins/error_handler.rb +7 -4
- data/lib/roda/plugins/hash_matcher.rb +32 -0
- data/lib/roda/plugins/header_matchers.rb +12 -2
- data/lib/roda/plugins/json.rb +9 -6
- data/lib/roda/plugins/module_include.rb +92 -0
- data/lib/roda/plugins/multi_route.rb +7 -0
- data/lib/roda/plugins/multi_run.rb +11 -5
- data/lib/roda/plugins/named_templates.rb +7 -1
- data/lib/roda/plugins/not_found.rb +6 -0
- data/lib/roda/plugins/param_matchers.rb +43 -0
- data/lib/roda/plugins/path_matchers.rb +51 -0
- data/lib/roda/plugins/render.rb +32 -14
- data/lib/roda/plugins/static_path_info.rb +10 -3
- data/lib/roda/plugins/symbol_matchers.rb +1 -1
- data/lib/roda/version.rb +13 -1
- data/spec/freeze_spec.rb +28 -0
- data/spec/plugin/class_level_routing_spec.rb +26 -0
- data/spec/plugin/content_for_spec.rb +1 -2
- data/spec/plugin/cookies_spec.rb +25 -0
- data/spec/plugin/default_headers_spec.rb +4 -7
- data/spec/plugin/delegate_spec.rb +4 -1
- data/spec/plugin/delete_empty_headers_spec.rb +15 -0
- data/spec/plugin/error_handler_spec.rb +31 -0
- data/spec/plugin/hash_matcher_spec.rb +27 -0
- data/spec/plugin/header_matchers_spec.rb +15 -0
- data/spec/plugin/json_spec.rb +1 -2
- data/spec/plugin/mailer_spec.rb +2 -2
- data/spec/plugin/module_include_spec.rb +31 -0
- data/spec/plugin/multi_route_spec.rb +14 -0
- data/spec/plugin/multi_run_spec.rb +41 -0
- data/spec/plugin/named_templates_spec.rb +25 -0
- data/spec/plugin/not_found_spec.rb +29 -0
- data/spec/plugin/param_matchers_spec.rb +37 -0
- data/spec/plugin/path_matchers_spec.rb +42 -0
- data/spec/plugin/render_spec.rb +33 -8
- data/spec/plugin/static_path_info_spec.rb +6 -0
- data/spec/plugin/view_subdirs_spec.rb +1 -2
- data/spec/response_spec.rb +12 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/version_spec.rb +8 -2
- metadata +19 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1ec447de1d1c9201190d3e05cddc9ca3aca957e4
|
4
|
+
data.tar.gz: fc6e061b744a3ed47259369907bb82e222d12515
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a5d0a587873870952a81b8df6a0828c76d68e2de2ff6d388f1ccbf82da5b45815722460ba51a540d1cf74f11fa7911b45d6e7928515901095eb08a8d76754ade
|
7
|
+
data.tar.gz: 33f7d3837fdf5b846169597868531493e00cf1089b2d68771e2b9ea1345603adb3462ca8283735ab393721ddb461467a0813cb9b05d13cdda869d8d62aaf143f
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,45 @@
|
|
1
|
+
= 1.3.0 (2015-01-13)
|
2
|
+
|
3
|
+
* Make static_path_info plugin restore original SCRIPT_NAME/PATH_INFO before returning from r.run (jeremyevans)
|
4
|
+
|
5
|
+
* Add RodaMajorVersion, RodaMinorVersion, and RodaPatchVersion (jeremyevans)
|
6
|
+
|
7
|
+
* Add delete_empty_headers plugin for deleting response headers that are empty before return response (jeremyevans)
|
8
|
+
|
9
|
+
* Make freeze class method freeze internal data structures to avoid thread safety issues (jeremyevans)
|
10
|
+
|
11
|
+
* Deprecate mutating plugin option hashes for chunked, default_headers, error_email, json, and render plugins (jeremyevans)
|
12
|
+
|
13
|
+
* Fix subclassing app and using r.multi_run in subclass in multi_run plugin (jeremyevans)
|
14
|
+
|
15
|
+
* Support :classes option in json plugin to set the classes to use (jeremyevans)
|
16
|
+
|
17
|
+
* Improve performance in default_headers plugin by not duping the headers (jeremyevans)
|
18
|
+
|
19
|
+
* Use :template_opts instead of :opts for providing options to the template in the render plugin (jeremyevans)
|
20
|
+
|
21
|
+
* Support :match_header_yield Roda option in the header_matchers plugin, causing the :header match to yield the value (jeremyevans)
|
22
|
+
|
23
|
+
* Move :param and :param! hash matchers to the param_matchers plugin (jeremyevans)
|
24
|
+
|
25
|
+
* Add path_matchers plugin, for :extension, :prefix, and :suffix hash matchers (jeremyevans)
|
26
|
+
|
27
|
+
* Move Roda.hash_matcher to hash_matcher plugin (jeremyevans)
|
28
|
+
|
29
|
+
* Move Roda.request_module and .response_module to module_include plugin (jeremyevans)
|
30
|
+
|
31
|
+
* Move RodaResponse#set_cookie and #delete_cookie to cookies plugin (jeremyevans)
|
32
|
+
|
33
|
+
* Deprecate RodaRequest#full_path_info, use #path instead (jeremyevans)
|
34
|
+
|
35
|
+
* Add class_delegate to the delegate plugin (jeremyevans)
|
36
|
+
|
37
|
+
* Make not_found plugin clear headers for response if it is not found (jeremyevans)
|
38
|
+
|
39
|
+
* Make error_handler plugin use a new response instead of reusing existing response (jeremyevans)
|
40
|
+
|
41
|
+
* Make RodaResponse a subclass of Object instead of Rack::Response (jeremyevans)
|
42
|
+
|
1
43
|
= 1.2.0 (2014-12-17)
|
2
44
|
|
3
45
|
* Don't override explicit nil :default_encoding template option in the render plugin (jeremyevans)
|
data/README.rdoc
CHANGED
@@ -66,7 +66,7 @@ Here's a simple application, showing how the routing tree works:
|
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
-
run App.app
|
69
|
+
run App.freeze.app
|
70
70
|
|
71
71
|
Here's a breakdown of what is going on in the block above:
|
72
72
|
|
@@ -111,8 +111,10 @@ allowing for code such as <tt>r.redirect(path) if some_condition</tt>.
|
|
111
111
|
If +r.redirect+ is called without arguments
|
112
112
|
and the current request method is not +GET+, it redirects to the current path.
|
113
113
|
|
114
|
-
The +.app+ at the end is
|
115
|
-
|
114
|
+
The +.freeze.app+ at the end is optional. Freezing the app avoids any possible
|
115
|
+
thread safety issues inside the application at runtime, which shouldn't be possible
|
116
|
+
anyway. This generally should only be done in production mode.
|
117
|
+
The +.app+ is an optimization, which saves a few method calls for every request.
|
116
118
|
|
117
119
|
== The Routing Tree
|
118
120
|
|
@@ -195,63 +197,51 @@ Here's an example showcasing how different matchers work:
|
|
195
197
|
|
196
198
|
class App < Roda
|
197
199
|
route do |r|
|
198
|
-
#
|
199
|
-
r.
|
200
|
-
|
201
|
-
|
202
|
-
r.root do
|
203
|
-
"Home"
|
204
|
-
end
|
205
|
-
|
206
|
-
# /about
|
207
|
-
r.is "about" do
|
208
|
-
"About"
|
209
|
-
end
|
210
|
-
|
211
|
-
# /styles/basic.css
|
212
|
-
r.is "styles", :extension => "css" do |file|
|
213
|
-
"Filename: #{file}" #=> "Filename: basic"
|
214
|
-
end
|
200
|
+
# GET /
|
201
|
+
r.root do
|
202
|
+
"Home"
|
203
|
+
end
|
215
204
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
205
|
+
# GET /about
|
206
|
+
r.get "about" do
|
207
|
+
"About"
|
208
|
+
end
|
220
209
|
|
221
|
-
|
222
|
-
|
223
|
-
|
210
|
+
# GET /post/2011/02/16/hello
|
211
|
+
r.get "post/:y/:m/:d/:slug" do |y, m, d, slug|
|
212
|
+
"#{y}-#{m}-#{d} #{slug}" #=> "2011-02-16 hello"
|
213
|
+
end
|
224
214
|
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
"Total Posts: #{user.posts.size}" #=> "Total Posts: 6"
|
229
|
-
end
|
215
|
+
# GET /username/foobar branch
|
216
|
+
r.on "username/:username", :method=>:get do |username|
|
217
|
+
user = User.find_by_username(username)
|
230
218
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
219
|
+
# GET /username/foobar/posts
|
220
|
+
r.is "posts" do
|
221
|
+
# You can access user here, because the blocks are closures.
|
222
|
+
"Total Posts: #{user.posts.size}" #=> "Total Posts: 6"
|
235
223
|
end
|
236
224
|
|
237
|
-
# /
|
238
|
-
r.is "
|
239
|
-
|
225
|
+
# GET /username/foobar/following
|
226
|
+
r.is "following" do
|
227
|
+
user.following.size.to_s #=> "1301"
|
240
228
|
end
|
241
229
|
end
|
242
230
|
|
243
|
-
#
|
244
|
-
r.
|
245
|
-
r
|
231
|
+
# /search?q=barbaz
|
232
|
+
r.get "search" do
|
233
|
+
"Searched for #{r['q']}" #=> "Searched for barbaz"
|
234
|
+
end
|
246
235
|
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
236
|
+
r.is "login" do
|
237
|
+
# GET /login
|
238
|
+
r.get do
|
239
|
+
"Login"
|
240
|
+
end
|
251
241
|
|
252
|
-
|
253
|
-
|
254
|
-
"
|
242
|
+
# POST /login?user=foo&password=baz
|
243
|
+
r.post do
|
244
|
+
"#{r['user']}:#{r['password']}" #=> "foo:baz"
|
255
245
|
end
|
256
246
|
end
|
257
247
|
end
|
@@ -355,11 +345,12 @@ This makes it easy to handle multiple strings without a Regexp:
|
|
355
345
|
|
356
346
|
Hashes allow easily calling specialized match methods on the request.
|
357
347
|
The default registered matchers included with Roda are documented below.
|
358
|
-
|
359
|
-
|
360
|
-
block will be called with the value of the hash.
|
348
|
+
Some plugins add additional hash matchers, and the hash_matcher plugin
|
349
|
+
allows for easily defining your own:
|
361
350
|
|
362
351
|
class App < Roda
|
352
|
+
plugin :hash_matcher
|
353
|
+
|
363
354
|
hash_matcher(:foo) do |v|
|
364
355
|
# ...
|
365
356
|
end
|
@@ -393,15 +384,6 @@ is so you can use it inside an array matcher, so:
|
|
393
384
|
|
394
385
|
would match +/foo+ and +/foos/10+, but not +/foos+.
|
395
386
|
|
396
|
-
==== :extension
|
397
|
-
|
398
|
-
The +:extension+ matcher matches any nonempty path ending with the given extension:
|
399
|
-
|
400
|
-
{:extension => "css"} # matches "/foo.css", "/bar.css"
|
401
|
-
{:extension => "css"} # does not match "/foo.css/x", "/foo.bar", "/.css"
|
402
|
-
|
403
|
-
This matcher yields the part found before the period and extension (e.g., +foo+).
|
404
|
-
|
405
387
|
==== :method
|
406
388
|
|
407
389
|
The +:method+ matcher matches the method of the request.
|
@@ -410,20 +392,6 @@ You can provide an array to specify multiple request methods and match on any of
|
|
410
392
|
{:method => :post} # matches POST
|
411
393
|
{:method => ['post', 'patch']} # matches POST and PATCH
|
412
394
|
|
413
|
-
==== :param
|
414
|
-
|
415
|
-
The +:param+ matcher matches if the given parameter is present (even if it is empty).
|
416
|
-
|
417
|
-
{:param => "user"} # matches "/foo?user=bar", "/foo?user="
|
418
|
-
{:param => "user"} # does not matches "/foo"
|
419
|
-
|
420
|
-
==== :param!
|
421
|
-
|
422
|
-
The +:param!+ matcher matches if the given parameter is present and not empty.
|
423
|
-
|
424
|
-
{:param! => "user"} # matches "/foo?user=bar"
|
425
|
-
{:param! => "user"} # does not matches "/foo", "/foo?user="
|
426
|
-
|
427
395
|
=== false, nil
|
428
396
|
|
429
397
|
If +false+ or +nil+ is given directly as a matcher, it doesn't match anything.
|
@@ -452,8 +420,11 @@ via the +status+ attribute for the response.
|
|
452
420
|
|
453
421
|
== Verb Methods
|
454
422
|
|
455
|
-
|
456
|
-
|
423
|
+
As displayed above, Roda has +r.get+ and +r.post+ methods
|
424
|
+
for matching based on the HTTP request method. If you want
|
425
|
+
to match on other HTTP request methods, use the all_verbs
|
426
|
+
plugin.
|
427
|
+
|
457
428
|
When called without any arguments, these match as long
|
458
429
|
as the request has the appropriate method, so:
|
459
430
|
|
@@ -467,7 +438,7 @@ matches any +POST+ request
|
|
467
438
|
|
468
439
|
If any arguments are given to the method, these match only
|
469
440
|
if the request method matches, all arguments match, and
|
470
|
-
|
441
|
+
the path has been fully matched by the arguments, so:
|
471
442
|
|
472
443
|
r.post "" do end
|
473
444
|
|
@@ -506,7 +477,8 @@ Unlike the other matching methods, +r.root+ takes no arguments.
|
|
506
477
|
Note that +r.root+ does not match if the path is empty;
|
507
478
|
you should use <tt>r.get true</tt> for that.
|
508
479
|
If you want to match either the the empty path or +/+,
|
509
|
-
you can use <tt>r.get ["", true]</tt
|
480
|
+
you can use <tt>r.get ["", true]</tt>, or use the slash_path_empty
|
481
|
+
plugin.
|
510
482
|
|
511
483
|
Note that +r.root+ only matches +GET+ requests.
|
512
484
|
So, to handle <tt>POST /</tt> requests, use <tt>r.post ''</tt>.
|
@@ -519,17 +491,15 @@ Likewise, the response object is available via the +response+ method.
|
|
519
491
|
|
520
492
|
The request object is an instance of a subclass of <tt>Rack::Request</tt>,
|
521
493
|
with some additional methods.
|
522
|
-
The response object is an instance of a subclass of <tt>Rack::Response</tt>,
|
523
|
-
with some additional methods.
|
524
494
|
|
525
495
|
If you want to extend the request and response objects with additional modules,
|
526
|
-
you can
|
496
|
+
you can use the module_include plugin.
|
527
497
|
|
528
498
|
== Pollution
|
529
499
|
|
530
500
|
Roda tries very hard to avoid polluting the scope of the +route+ block.
|
531
501
|
This should make it unlikely that Roda will cause namespace issues
|
532
|
-
with your application code
|
502
|
+
with your application code. Some of the things Roda does
|
533
503
|
|
534
504
|
- The only instance variables defined by default in the scope of the +route+ block
|
535
505
|
are <tt>@_request</tt> and <tt>@_response</tt>.
|
@@ -538,40 +508,12 @@ with your application code:
|
|
538
508
|
- Constants inside the Roda namespace are all prefixed with +Roda+
|
539
509
|
(e.g., <tt>Roda::RodaRequest</tt>).
|
540
510
|
|
541
|
-
== Captures
|
542
|
-
|
543
|
-
You may have noticed that some matchers yield a value to the block.
|
544
|
-
The rules for determining if a matcher will yield a value are simple:
|
545
|
-
|
546
|
-
1. Regexp captures: <tt>/posts\/(\d+)-(.*)/</tt> will yield two values, corresponding to each capture.
|
547
|
-
2. String placeholders: <tt>"users/:id"</tt> will yield the value in the position of +:id+.
|
548
|
-
3. Symbols: +:foobar+ will yield if a segment is available.
|
549
|
-
4. File extensions: <tt>:extension=>"css"</tt> will yield the basename of the matched file.
|
550
|
-
5. Parameters: <tt>:param=>"user"</tt> will yield the value of the parameter +user+, if present.
|
551
|
-
|
552
|
-
The first case is important because it shows the underlying effect of Regexp captures.
|
553
|
-
|
554
|
-
In the second case, the substring +:id+ gets replaced by <tt>([^\\/]+)</tt>
|
555
|
-
and the Regexp becomes <tt>/users\/([^\/]+)/</tt> before performing the match.
|
556
|
-
Thus, it reverts to the first form we saw.
|
557
|
-
|
558
|
-
In the third case, the symbol, no matter what it says,
|
559
|
-
gets replaced by <tt>/([^\\/]+)/</tt>, and again we are in presence of case 1.
|
560
|
-
|
561
|
-
The fourth case, again, reverts to the basic matcher: it generates the string
|
562
|
-
<tt>/([^\/]+?)\.#{ext}\z/</tt> before performing the match.
|
563
|
-
|
564
|
-
The fifth case is different: it checks if the parameter supplied is present
|
565
|
-
in the request (via POST or QUERY_STRING) and it pushes the value as a capture.
|
566
|
-
|
567
511
|
== Composition
|
568
512
|
|
569
513
|
You can mount any Rack app (including another Roda app), with its own middlewares,
|
570
514
|
inside a Roda app, using +r.run+:
|
571
515
|
|
572
516
|
class API < Roda
|
573
|
-
use SomeMiddleware
|
574
|
-
|
575
517
|
route do |r|
|
576
518
|
r.is do
|
577
519
|
# ...
|
@@ -597,6 +539,10 @@ When you use +r.run+, Roda calls the given Rack app (+API+ in this case);
|
|
597
539
|
whatever the Rack app returns will be returned
|
598
540
|
as the response for the current application.
|
599
541
|
|
542
|
+
If you have a lot of rack applications that you want to dispatch to, and
|
543
|
+
which one to dispatch to is based on the request path prefix, look into the
|
544
|
+
+multi_run+ plugin.
|
545
|
+
|
600
546
|
=== multi_route plugin
|
601
547
|
|
602
548
|
If you are just looking to split up the main route block up by branches,
|
@@ -651,10 +597,15 @@ Note that when subclassing, Roda only does a shallow clone of the settings.
|
|
651
597
|
If you store nested structures and plan to mutate them in subclasses,
|
652
598
|
it is your responsibility to dup the nested structures inside +Roda.inherited+
|
653
599
|
(making sure to call +super+).
|
600
|
+
|
654
601
|
The plugins that ship with Roda all handle this.
|
655
602
|
Also, note that this means that modifications to the parent class
|
656
603
|
made after subclassing do _not_ affect the subclass.
|
657
604
|
|
605
|
+
The plugins that ship with Roda freeze their settings and only allow modification
|
606
|
+
to their settings by reloading the plugin, and external plugins are encouraged
|
607
|
+
to follow this approach.
|
608
|
+
|
658
609
|
== Rendering
|
659
610
|
|
660
611
|
Roda ships with a +render+ plugin that provides helpers for rendering templates.
|
@@ -675,13 +626,13 @@ By default, +view+ will render the template inside the default layout template;
|
|
675
626
|
route do |r|
|
676
627
|
@var = '1'
|
677
628
|
|
678
|
-
r.
|
629
|
+
r.get "render" do
|
679
630
|
# Renders the views/home.erb template, which will have access to
|
680
631
|
# the instance variable @var, as well as local variable content.
|
681
632
|
render("home", :locals=>{:content => "hello, world"})
|
682
633
|
end
|
683
634
|
|
684
|
-
r.
|
635
|
+
r.get "view" do
|
685
636
|
@var2 = '1'
|
686
637
|
|
687
638
|
# Renders the views/home.erb template, which will have access to the
|
@@ -697,13 +648,11 @@ You can override the default rendering options by passing a hash to the plugin:
|
|
697
648
|
|
698
649
|
class App < Roda
|
699
650
|
plugin :render,
|
700
|
-
:
|
701
|
-
:
|
702
|
-
:
|
703
|
-
|
704
|
-
:
|
705
|
-
:opts => {:default_encoding=>'UTF-8'}, # Default template options
|
706
|
-
:views => 'admin_views' # Default views directory
|
651
|
+
:escape => true, # Automatically escape output in erb templates
|
652
|
+
:views => 'admin_views' # Default views directory
|
653
|
+
:layout_opts => {:template=>'admin_layout',
|
654
|
+
:ext=>'html.erb'}, # Default layout template options
|
655
|
+
:template_opts => {:default_encoding=>'UTF-8'}, # Default template options
|
707
656
|
end
|
708
657
|
|
709
658
|
== Sessions
|
@@ -760,27 +709,13 @@ to escape by default, so that in your templates:
|
|
760
709
|
|
761
710
|
This support requires {Erubis}[http://www.kuwata-lab.com/erubis/].
|
762
711
|
|
763
|
-
=== Other
|
764
|
-
|
765
|
-
For prevention of some other vulnerabilities,
|
766
|
-
such as click-jacking, directory traversal, session hijacking, and IP spoofing,
|
767
|
-
consider using {Rack::Protection}[https://github.com/rkh/rack-protection].
|
768
|
-
This is a Rack middleware that can be added in the usual way:
|
769
|
-
|
770
|
-
require 'roda'
|
771
|
-
require 'rack/protection'
|
772
|
-
|
773
|
-
class App < Roda
|
774
|
-
use Rack::Protection
|
775
|
-
end
|
776
|
-
|
777
712
|
== Plugins
|
778
713
|
|
779
714
|
By design, Roda has a very small core, providing only the essentials.
|
780
715
|
All nonessential features are added via plugins.
|
781
716
|
This is why Roda is referred to as a routing tree web framework toolkit.
|
782
717
|
Using a combination of Roda plugins,
|
783
|
-
you can build the routing tree web framework that
|
718
|
+
you can build the routing tree web framework that suits your needs.
|
784
719
|
|
785
720
|
Roda's plugins can override any Roda method and call +super+
|
786
721
|
to get the default behavior, which makes Roda very extensible.
|
@@ -788,14 +723,6 @@ to get the default behavior, which makes Roda very extensible.
|
|
788
723
|
{Roda ships with a large number of plugins}[http://roda.jeremyevans.net/documentation.html#included-plugins],
|
789
724
|
and {some other libraries ship with support for Roda}[http://roda.jeremyevans.net/documentation.html#external].
|
790
725
|
|
791
|
-
=== External Plugins
|
792
|
-
|
793
|
-
The following libraries include Roda plugins:
|
794
|
-
|
795
|
-
forme :: Adds support for easy HTML form creation in erb templates.
|
796
|
-
autoforme :: Adds support for easily creating a simple administrative front
|
797
|
-
end for Sequel models.
|
798
|
-
|
799
726
|
=== How to create plugins
|
800
727
|
|
801
728
|
Authoring your own plugins is pretty straightforward.
|
@@ -857,7 +784,9 @@ To avoid namespace pollution,
|
|
857
784
|
you should avoid creating your module directly in the +Roda+ namespace.
|
858
785
|
Additionally, any instance variables created inside +InstanceMethods+
|
859
786
|
should be prefixed with an underscore (e.g., <tt>@_variable</tt>)
|
860
|
-
to avoid polluting the scope.
|
787
|
+
to avoid polluting the scope. Finally, do not add any constants inside
|
788
|
+
the InstanceMethods module, add constants to the plugin module itself
|
789
|
+
(+Markdown+ in the above example).
|
861
790
|
|
862
791
|
== License
|
863
792
|
|
data/doc/conventions.rdoc
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
= Conventions
|
2
2
|
|
3
3
|
This guide goes over conventions for directory layout and file layout for Roda applications.
|
4
|
-
You are free to ignore these conventions,
|
5
|
-
to
|
4
|
+
You are free to ignore these conventions, they mostly exist to help users who are unsure how
|
5
|
+
to structure their Roda applications.
|
6
6
|
|
7
7
|
== Directory Layout
|
8
8
|
|
@@ -78,14 +78,16 @@ Large applications generally need more structure:
|
|
78
78
|
|
79
79
|
For larger apps, the +Rakefile+, +assets/+, +migrate+, +models.rb+, +models/+, +public/+, remain the same.
|
80
80
|
|
81
|
-
+app_name.rb+ should use the +multi_route+ and +view_subdirs+
|
82
|
-
|
81
|
+
+app_name.rb+ should use the +multi_route+ and +view_subdirs+ plugin, or the +multi_run+ plugin.
|
82
|
+
The routes used by the +multi_route+ or +multi_run+ should be stored in routing files in the +routes/+
|
83
|
+
directory, with one file per prefix.
|
83
84
|
|
84
85
|
For specs/tests, you should have +spec/models/+ and +spec/web/+, with one file per model in +spec/models/+
|
85
86
|
and one file per prefix in +spec/web/+.
|
86
87
|
|
87
|
-
You should have a separate view subdirectory per prefix
|
88
|
-
to specify the subdirectory to use, so it doesn't need to be
|
88
|
+
You should have a separate view subdirectory per prefix. If you are using +multi_route+ and +view_subdirs+,
|
89
|
+
use +set_view_subdir+ in your routing files to specify the subdirectory to use, so it doesn't need to be
|
90
|
+
specified on every call to view.
|
89
91
|
|
90
92
|
+helpers/+ should be used to store helper methods for your application, that you call in your routing files
|
91
93
|
and views. In a small application, these methods should just be specified in +app_name.rb+
|
@@ -93,8 +95,8 @@ and views. In a small application, these methods should just be specified in +a
|
|
93
95
|
=== Really Large Applications
|
94
96
|
|
95
97
|
For very large applications, it's expected that there will be deviations from these conventions. However,
|
96
|
-
it is recommended to use
|
97
|
-
directory, and nested subdirectories in the +views/+ directory.
|
98
|
+
it is recommended to use the +multi_route+ or +multi_run+ plugins to organize your application, and have
|
99
|
+
subdirectories in the +routes/+ directory, and nested subdirectories in the +views/+ directory.
|
98
100
|
|
99
101
|
== Roda Application File Layout
|
100
102
|
|