roda 1.1.0 → 1.2.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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +70 -0
  3. data/README.rdoc +261 -302
  4. data/Rakefile +1 -1
  5. data/doc/release_notes/1.2.0.txt +406 -0
  6. data/lib/roda.rb +206 -124
  7. data/lib/roda/plugins/all_verbs.rb +11 -10
  8. data/lib/roda/plugins/assets.rb +5 -5
  9. data/lib/roda/plugins/backtracking_array.rb +12 -5
  10. data/lib/roda/plugins/caching.rb +10 -8
  11. data/lib/roda/plugins/class_level_routing.rb +94 -0
  12. data/lib/roda/plugins/content_for.rb +6 -0
  13. data/lib/roda/plugins/default_headers.rb +4 -11
  14. data/lib/roda/plugins/delay_build.rb +42 -0
  15. data/lib/roda/plugins/delegate.rb +64 -0
  16. data/lib/roda/plugins/drop_body.rb +33 -0
  17. data/lib/roda/plugins/empty_root.rb +48 -0
  18. data/lib/roda/plugins/environments.rb +68 -0
  19. data/lib/roda/plugins/error_email.rb +1 -2
  20. data/lib/roda/plugins/error_handler.rb +1 -1
  21. data/lib/roda/plugins/halt.rb +7 -5
  22. data/lib/roda/plugins/head.rb +4 -2
  23. data/lib/roda/plugins/header_matchers.rb +17 -9
  24. data/lib/roda/plugins/hooks.rb +16 -32
  25. data/lib/roda/plugins/json.rb +4 -10
  26. data/lib/roda/plugins/mailer.rb +233 -0
  27. data/lib/roda/plugins/match_affix.rb +48 -0
  28. data/lib/roda/plugins/multi_route.rb +9 -11
  29. data/lib/roda/plugins/multi_run.rb +81 -0
  30. data/lib/roda/plugins/named_templates.rb +93 -0
  31. data/lib/roda/plugins/not_allowed.rb +43 -48
  32. data/lib/roda/plugins/path.rb +63 -2
  33. data/lib/roda/plugins/render.rb +79 -48
  34. data/lib/roda/plugins/render_each.rb +6 -0
  35. data/lib/roda/plugins/sinatra_helpers.rb +523 -0
  36. data/lib/roda/plugins/slash_path_empty.rb +25 -0
  37. data/lib/roda/plugins/static_path_info.rb +64 -0
  38. data/lib/roda/plugins/streaming.rb +1 -1
  39. data/lib/roda/plugins/view_subdirs.rb +12 -8
  40. data/lib/roda/version.rb +1 -1
  41. data/spec/integration_spec.rb +33 -0
  42. data/spec/plugin/backtracking_array_spec.rb +24 -18
  43. data/spec/plugin/class_level_routing_spec.rb +138 -0
  44. data/spec/plugin/delay_build_spec.rb +23 -0
  45. data/spec/plugin/delegate_spec.rb +20 -0
  46. data/spec/plugin/drop_body_spec.rb +20 -0
  47. data/spec/plugin/empty_root_spec.rb +14 -0
  48. data/spec/plugin/environments_spec.rb +31 -0
  49. data/spec/plugin/h_spec.rb +1 -3
  50. data/spec/plugin/header_matchers_spec.rb +14 -0
  51. data/spec/plugin/hooks_spec.rb +3 -5
  52. data/spec/plugin/mailer_spec.rb +191 -0
  53. data/spec/plugin/match_affix_spec.rb +22 -0
  54. data/spec/plugin/multi_run_spec.rb +31 -0
  55. data/spec/plugin/named_templates_spec.rb +65 -0
  56. data/spec/plugin/path_spec.rb +66 -2
  57. data/spec/plugin/render_spec.rb +46 -1
  58. data/spec/plugin/sinatra_helpers_spec.rb +534 -0
  59. data/spec/plugin/slash_path_empty_spec.rb +22 -0
  60. data/spec/plugin/static_path_info_spec.rb +50 -0
  61. data/spec/request_spec.rb +23 -0
  62. data/spec/response_spec.rb +12 -1
  63. metadata +48 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 75b82517a1e80d73d99ea7d25a8bd543ba958e7c
4
- data.tar.gz: 4bcb31a61b7f2658092fe80fb339a8651b718edd
3
+ metadata.gz: 3d246589728bb46404806737bb7e67819956f167
4
+ data.tar.gz: e57198e8df759bd70039ff42f94d86583c75c2f8
5
5
  SHA512:
6
- metadata.gz: a8d8776bd1e9c282dc6d5df795a790a2272103421125233ffe5f6112c77c99d00f37f364c7879b73eb03aafd2c946e45e123c0e261f3ff7f1b576936a986e1ee
7
- data.tar.gz: f8b85158682a132cd00d2a929532bb466a15c502f94abd54afcdaad35dde2fab96a2e2ff6d5b180b62220a6e0944de5ac824c0c25285bd04a8e8d39f959ad171
6
+ metadata.gz: 3127e9f7b7525780556555366e82b0e9f565216e62dacdd5e3e7a69e3440a47771ddad5472b94f7c09d15cf6acb49c7bcdb54fb1d469f68569eb5cf77e589dca
7
+ data.tar.gz: f6dd7cda1372931ce0bf92934d584e084f8b1b84d5a181ce1b28bcf951983adce7c477e6b4bdabdad9a8f0038cacafa49ba87948b46a38de0ad23b0b1330d86c
data/CHANGELOG CHANGED
@@ -1,3 +1,73 @@
1
+ = 1.2.0 (2014-12-17)
2
+
3
+ * Don't override explicit nil :default_encoding template option in the render plugin (jeremyevans)
4
+
5
+ * Add remaining_path and matched_path request methods (jeremyevans)
6
+
7
+ * Add slash_path_emty plugin, for considering a path of "/" as empty when doing a terminal match (jeremyevans)
8
+
9
+ * Remove def_verb_method request class method (jeremyevans)
10
+
11
+ * Support :add_script_name, :name, :url, and :url_only options when creating named paths in the path plugin (jeremyevans)
12
+
13
+ * Add match_affix plugin, for overriding default prefix/suffix used in match patterns (jeremyevans)
14
+
15
+ * Add empty_root plugin, for making root matcher also match empty string (jeremyevans)
16
+
17
+ * Add roda_class instance methods to RodaRequest and RodaResponse, to DRY up plugin code (jeremyevans)
18
+
19
+ * Add sinatra_helpers plugin, porting Sinatra::Helpers methods not covered by other plugins (jeremyevans)
20
+
21
+ * Don't set the default headers until the response is finished (jeremyevans)
22
+
23
+ * Add RodaRequest#default_redirect_status, so plugins can override the default status used for redirects (jeremyevans)
24
+
25
+ * Add drop_body plugin, for automatically dropping body and Content-{Length,Type} headers based on response status (jeremyevans)
26
+
27
+ * Add clear_middleware! class method, for clearing the current middleware (jeremyevans)
28
+
29
+ * Add inherit_middleware class accessor, allowing users to turn off middleware inheritance (jeremyevans)
30
+
31
+ * Add multi_run plugin, for dispatching to multiple rack applications based on the request path prefix (jeremyevans)
32
+
33
+ * Add environments plugin, for handling development/test/production environments (jeremyevans)
34
+
35
+ * Do not cache templates by default if RACK_ENV is development (jeremyevans)
36
+
37
+ * Add delay_build plugin, to delay building the rack app until Roda.app is called (jeremyevans)
38
+
39
+ * Add :user_agent hash matcher to the header_matchers plugin (jeremyevans)
40
+
41
+ * Fix caching of templates in the render plugin when :opts or :template_class is used (jeremyevans)
42
+
43
+ * Require loading the render plugin again if you want to change the default layout (jeremyevans)
44
+
45
+ * Pass :css_opts and :js_opts as template options (via :opts) instead of render options when rendering (jeremyevans)
46
+
47
+ * Only pass :opts hash to template class during rendering, instead of all render/view options (jeremyevans)
48
+
49
+ * Support :template_class option in the render plugin for overriding template class to use (jeremyevans)
50
+
51
+ * Automatically dup unfrozen Array/Hash opts values when subclassing (jeremyevans)
52
+
53
+ * Add named_templates plugin, for creating inline templates by name, instead of storing them in the file system (jeremyevans)
54
+
55
+ * Support :template option in for render/view to specify template to use, instead of requiring separate argument (jeremyevans)
56
+
57
+ * Add class_level_routing plugin, for a DSL similar to Sinatra (jeremyevans)
58
+
59
+ * Make RodaRequest.consume_pattern not capture pattern by default (jeremyevans)
60
+
61
+ * Add static_path_info plugin, making Roda not modify PATH_INFO or SCRIPT_NAME during routing (jeremyevans)
62
+
63
+ * Use local/instance variable lookups instead of method calls to improve performance (jeremyevans)
64
+
65
+ * Add RodaRequest#session, and have #session delegate to that (jeremyevans)
66
+
67
+ * Add delegate plugin, for easily creating methods that delegate to request or response (jeremyevans)
68
+
69
+ * Add mailer plugin, allowing use of a routing tree for email instead of web responses (jeremyevans)
70
+
1
71
  = 1.1.0 (2014-11-11)
2
72
 
3
73
  * Add assets plugin, for rendering assets on the fly, or compiling them to a single compressed file (cj, jeremyevans) (#5)
@@ -1,6 +1,6 @@
1
1
  = Roda
2
2
 
3
- Roda is a routing tree web framework.
3
+ Roda is a routing tree web framework toolkit.
4
4
 
5
5
  = Installation
6
6
 
@@ -17,10 +17,11 @@ IRC :: irc://chat.freenode.net/#roda
17
17
  == Inspiration
18
18
 
19
19
  Roda was inspired by {Sinatra}[http://www.sinatrarb.com] and {Cuba}[http://cuba.is],
20
- two other Ruby web frameworks. It started out as a fork of Cuba, from which it borrows
21
- the idea of using a routing tree (which Cuba in turn took from
22
- {Rum}[https://github.com/chneukirchen/rum]). From Sinatra it takes the ideas that
23
- route blocks should return the request bodies and that routes should be canonical.
20
+ two other Ruby web frameworks.
21
+ It started out as a fork of Cuba, from which it borrows the idea of using a routing tree
22
+ (which Cuba in turn took from {Rum}[https://github.com/chneukirchen/rum]).
23
+ From Sinatra, it takes the ideas that route blocks should return the request bodies
24
+ and that routes should be canonical.
24
25
  It pilfers the idea for an extensible plugin system from the Ruby database library
25
26
  {Sequel}[http://sequel.jeremyevans.net].
26
27
 
@@ -67,77 +68,77 @@ Here's a simple application, showing how the routing tree works:
67
68
 
68
69
  run App.app
69
70
 
70
- Here's a breakdown of what is going on in the above block:
71
+ Here's a breakdown of what is going on in the block above:
71
72
 
72
- After requiring the library and subclassing Roda, the +use+ method
73
- is called, which loads a rack middleware into the current
74
- application.
73
+ After requiring the library and subclassing Roda, the +use+ method is called.
74
+ This loads a Rack middleware into the current application.
75
75
 
76
- The +route+ block is called whenever a new request comes in,
77
- and it is yielded an instance of a subclass of <tt>Rack::Request</tt>
78
- with some additional methods for matching routes. By
79
- convention, this argument should be named +r+.
76
+ The +route+ block is called whenever a new request comes in.
77
+ It is yielded an instance of a subclass of <tt>Rack::Request</tt>
78
+ with some additional methods for matching routes.
79
+ By convention, this argument should be named +r+.
80
80
 
81
81
  The primary way routes are matched in Roda is by calling
82
- +r.on+, +r.is+, +r.root+, +r.get+, or +r.post+. These methods are
83
- calling the routing methods, and each of them takes a block. The
84
- block is referred to as a match block.
82
+ +r.on+, +r.is+, +r.root+, +r.get+, or +r.post+.
83
+ Each of these "routing methods" takes a "match block".
85
84
 
86
85
  Each routing method takes each of the arguments (called matchers)
87
- given and tries to match them to the current request. If it is
88
- able to match all of the arguments, it yields to the match block,
89
- otherwise the block is skipped and execution continues.
90
-
91
- +r.on+ matches if all of the arguments match.
92
- +r.is+ matches if all of the arguments match, and there are no
93
- further entries in the path after matching.
94
- +r.get+ when called without arguments matches any +GET+ request.
95
- +r.get+ when called with any arguments matches only if the
96
- current request is a +GET+ request and there are no further entries
97
- in the path after matching.
98
- +r.root+ only matches a +GET+ request where the current path is +/+.
99
-
100
- If a routing method matches and control is yielded to the match
101
- block, whenever the match block returns, Roda will return the
102
- rack response array of status, headers, and body, to the caller.
103
-
104
- If the match block returns a string and the response body hasn't
105
- already been written to, the block return value will interpreted
106
- as the body for the response. If none of the routing methods match
107
- and the route block returns a string, it will be interpreted as the
108
- body for the response.
109
-
110
- +r.redirect+ immediately returns the response, allowing for
111
- code such as <tt>r.redirect(path) if some_condition</tt>. If
112
- called without arguments, it redirects to the current path if
113
- the current request method is not +GET+.
114
-
115
- The +.app+ at the end is an optimization, which you can leave
116
- off, but which saves a few methods call for every response.
86
+ that is given and tries to match it to the current request.
87
+ If the method is able to match all of the arguments, it yields to the match block;
88
+ otherwise, the block is skipped and execution continues.
89
+
90
+ - +r.on+ matches if all of the arguments match.
91
+ - +r.is+ matches if all of the arguments match and there are no
92
+ further entries in the path after matching.
93
+ - +r.get+ matches any +GET+ request when called without arguments.
94
+ - +r.get+ (when called with any arguments) matches only if the
95
+ current request is a +GET+ request and there are no further entries
96
+ in the path after matching.
97
+ - +r.root+ only matches a +GET+ request where the current path is +/+.
98
+
99
+ If a routing method matches and control is yielded to the match block,
100
+ whenever the match block returns, Roda will return the Rack response array
101
+ (containing status, headers, and body) to the caller.
102
+
103
+ If the match block returns a string
104
+ and the response body hasn't already been written to,
105
+ the block return value will be interpreted as the body for the response.
106
+ If none of the routing methods match and the route block returns a string,
107
+ it will be interpreted as the body for the response.
108
+
109
+ +r.redirect+ immediately returns the response,
110
+ allowing for code such as <tt>r.redirect(path) if some_condition</tt>.
111
+ If +r.redirect+ is called without arguments
112
+ and the current request method is not +GET+, it redirects to the current path.
113
+
114
+ The +.app+ at the end is an (optional) optimization.
115
+ It saves a few method calls for every response.
117
116
 
118
117
  == The Routing Tree
119
118
 
120
- Roda is called a routing tree web framework because the way most
121
- sites are structured, routing takes the form of a tree based on the
122
- URL structure of the site. In general, +r.on+ is used to split the
123
- tree into different branches, and +r.is+ is finalizes the routing,
124
- where the request is actually handled.
119
+ Roda is called a routing tree web framework because the way most sites are structured,
120
+ routing takes the form of a tree (based on the URL structure of the site).
121
+ In general:
125
122
 
126
- So a simple routing tree may look something like this:
123
+ - +r.on+ is used to split the tree into different branches.
124
+ - +r.is+ finalizes the routing path.
125
+ - +r.get+ and +r.post+ handle specific request methods.
126
+
127
+ So, a simple routing tree might look something like this:
127
128
 
128
129
  r.on "a" do # /a branch
129
130
  r.on "b" do # /a/b branch
130
131
  r.is "c" do # /a/b/c request
131
- r.get do end # GET /a/b/c request
132
+ r.get do end # GET /a/b/c request
132
133
  r.post do end # POST /a/b/c request
133
134
  end
134
- r.get "d" do end # GET /a/b/d request
135
+ r.get "d" do end # GET /a/b/d request
135
136
  r.post "e" do end # POST /a/b/e request
136
137
  end
137
138
  end
138
139
 
139
- It's also possible to handle the same requests, but structure the
140
- routing tree by first branching on the request method:
140
+ It's also possible to handle the same requests,
141
+ but structure the routing tree by first branching on the request method:
141
142
 
142
143
  r.get do # GET
143
144
  r.on "a" do # GET /a branch
@@ -157,42 +158,40 @@ routing tree by first branching on the request method:
157
158
  end
158
159
  end
159
160
 
160
- This allows you to easily separate your +GET+ request handling from
161
- your +POST+ request handling. If you only have a small number of
162
- +POST+ request URLs and a large number of +GET+ request URLs, this
163
- may make things easier.
161
+ This allows you to easily separate your +GET+ request handling
162
+ from your +POST+ request handling.
163
+ If you only have a small number of +POST+ request URLs
164
+ and a large number of +GET+ request URLs, this may make things easier.
164
165
 
165
- However, in general routing first by the path and last by the
166
- request method is likely to lead to simpler and DRYer code. This
167
- is because at any point during the routing, you can act on the
168
- request. For example, if all requests in the +/a+ branch need
169
- need access permission +A+ and all requests in the +/a/b+ branch
170
- need access permission +B+, you can easily handle this in the
171
- routing tree:
166
+ However, routing first by the path and last by the request method
167
+ is likely to lead to simpler and DRYer code.
168
+ This is because you can act on the request at any point during the routing.
169
+ For example, if all requests in the +/a+ branch need access permission +A+
170
+ and all requests in the +/a/b+ branch need access permission +B+,
171
+ you can easily handle this in the routing tree:
172
172
 
173
173
  r.on "a" do # /a branch
174
174
  check_perm(:A)
175
175
  r.on "b" do # /a/b branch
176
176
  check_perm(:B)
177
177
  r.is "c" do # /a/b/c request
178
- r.get do end # GET /a/b/c request
178
+ r.get do end # GET /a/b/c request
179
179
  r.post do end # POST /a/b/c request
180
180
  end
181
- r.get "d" do end # GET /a/b/d request
181
+ r.get "d" do end # GET /a/b/d request
182
182
  r.post "e" do end # POST /a/b/e request
183
183
  end
184
184
  end
185
185
 
186
- Being able to operate on the request at any point during the
187
- the routing is one of the major advantages of Roda compared
188
- to other web frameworks that do not use a routing tree.
186
+ Being able to operate on the request at any point during the routing
187
+ is one of the major advantages of Roda, as compared to frameworks
188
+ that do not use a routing tree.
189
189
 
190
190
  == Matchers
191
191
 
192
- Other than +r.root+, the routing methods all take arguments called
193
- matchers. If all of the matchers match, the routing method yields to
194
- the match block. Here's an example showcasing how different
195
- matchers work:
192
+ Other than +r.root+, the routing methods all take arguments called matchers.
193
+ If all of the matchers match, the routing method yields to the match block.
194
+ Here's an example showcasing how different matchers work:
196
195
 
197
196
  class App < Roda
198
197
  route do |r|
@@ -258,29 +257,28 @@ matchers work:
258
257
  end
259
258
  end
260
259
 
261
- Here's a description of the matchers. Note that segment as used
262
- here means one part of the path preceeded by a +/+. So a path such
263
- as +/foo/bar//baz+ has 4 segments, +/foo+, +/bar+, +/+ and +/baz+.
260
+ Here's a description of the matchers.
261
+ Note that "segment", as used here, means one part of the path preceded by a +/+.
262
+ So, a path such as +/foo/bar//baz+ has four segments: +/foo+, +/bar+, +/+, and +/baz+.
264
263
  The +/+ here is considered the empty segment.
265
264
 
266
265
  === String
267
266
 
268
- If it does not contain a colon or slash, it matches single segment
269
- with the text of the string, preceeded by a slash.
267
+ If a string does not contain a colon or slash, it matches a single segment
268
+ containing the text of the string, preceded by a slash.
270
269
 
271
270
  "" # matches "/"
272
271
  "foo" # matches "/foo"
273
272
  "foo" # does not match "/food"
274
273
 
275
- If it contains any slashes, it matches one additional segment for
276
- each slash:
274
+ If a string contains any slashes, it matches one additional segment for each slash:
277
275
 
278
276
  "foo/bar" # matches "/foo/bar"
279
277
  "foo/bar" # does not match "/foo/bard"
280
278
 
281
- If it contains a colon followed by any <tt>\\w</tt> characters, the colon and
282
- remaing <tt>\\w</tt> characters matches any nonempty segment that contains at
283
- least one character:
279
+ If a string contains a colon followed by any <tt>\\w</tt> characters,
280
+ the colon and remaining <tt>\\w</tt> characters match any nonempty segment
281
+ that contains at least one character:
284
282
 
285
283
  "foo/:id" # matches "/foo/bar", "/foo/baz", etc.
286
284
  "foo/:id" # does not match "/fo/bar"
@@ -295,8 +293,8 @@ You can prefix colons:
295
293
  "foo:x/bar:y" # matches "/food/bard", "/fool/bart", etc.
296
294
  "foo:x/bar:y" # does not match "/foo/bart", "/fool/bar", etc.
297
295
 
298
- If any colons are used, the block will yield one argument for
299
- each segment matched containing the matched text. So:
296
+ If any colons are used, the block will yield one argument
297
+ for each segment matched containing the matched text, so:
300
298
 
301
299
  "foo:x/:y" # matching "/fool/bar" yields "l", "bar"
302
300
 
@@ -304,29 +302,28 @@ Colons that are not followed by a <tt>\\w</tt> character are matched literally:
304
302
 
305
303
  ":/a" # matches "/:/a"
306
304
 
307
- Note that strings are regexp escaped before being used in a regular
308
- expression, so:
305
+ Note that strings must be escaped before being used in a regular expression, so:
309
306
 
310
307
  "\\d+(/\\w+)?" # matches "/\d+(/\w+)?"
311
308
  "\\d+(/\\w+)?" # does not match "/123/abc"
312
309
 
313
310
  === Regexp
314
311
 
315
- Regexps match one or more segments by looking for the pattern preceeded by a
316
- slash:
312
+ Regexps match one or more segments by looking for the pattern,
313
+ preceded by a slash:
317
314
 
318
315
  /foo\w+/ # matches "/foobar"
319
316
  /foo\w+/ # does not match "/foo/bar"
320
317
 
321
- If any patterns are captured by the regexp, they are yielded:
318
+ If any patterns are captured by the Regexp, they are yielded:
322
319
 
323
320
  /foo\w+/ # matches "/foobar", yields nothing
324
321
  /foo(\w+)/ # matches "/foobar", yields "bar"
325
322
 
326
323
  === Symbol
327
324
 
328
- Symbols match any nonempty segment, yielding the segment except for the
329
- preceeding slash:
325
+ Symbols match any nonempty segment,
326
+ yielding the segment except for the preceding slash:
330
327
 
331
328
  :id # matches "/foo" yields "foo"
332
329
  :id # does not match "/"
@@ -338,15 +335,15 @@ Procs match unless they return false or nil:
338
335
  proc{true} # matches anything
339
336
  proc{false} # does not match anything
340
337
 
341
- Procs don't capture anything by default, but they can if you add
342
- the captured text to +r.captures+.
338
+ Procs don't capture anything by default,
339
+ but they can do so if you add the captured text to +r.captures+.
343
340
 
344
341
  === Arrays
345
342
 
346
- Arrays match when any of their elements matches. If multiple matchers
347
- are given to +r.on+, they all must match (an AND condition), while
348
- if an array of matchers is given, only one needs to match (an OR
349
- condition). Evaluation stops at the first matcher that matches.
343
+ Arrays match when any of their elements match.
344
+ If multiple matchers are given to +r.on+, they all must match (an AND condition).
345
+ If an array of matchers is given, only one needs to match (an OR condition).
346
+ Evaluation stops at the first matcher that matches.
350
347
 
351
348
  Additionally, if the matched object is a String, the string is yielded.
352
349
  This makes it easy to handle multiple strings without a Regexp:
@@ -376,7 +373,7 @@ block will be called with the value of the hash.
376
373
 
377
374
  ==== :all
378
375
 
379
- The :all matcher matches if all of the entries in the given array matches. So
376
+ The +:all+ matcher matches if all of the entries in the given array match, so
380
377
 
381
378
  r.on :all=>[:a, :b] do
382
379
  # ...
@@ -388,48 +385,48 @@ is the same as:
388
385
  # ...
389
386
  end
390
387
 
391
- The reason it also exists as a separate hash matcher is so you can use it inside
392
- an array matcher. so:
388
+ The reason it also exists as a separate hash matcher
389
+ is so you can use it inside an array matcher, so:
393
390
 
394
391
  r.on ['foo', {:all=>['foos', :id]}] do
395
392
  end
396
393
 
397
- Would match +/foo+ and +/foos/10+, but not +/foos+.
394
+ would match +/foo+ and +/foos/10+, but not +/foos+.
398
395
 
399
396
  ==== :extension
400
397
 
401
- The :extension matcher matches any nonempty path ending with the given extension:
398
+ The +:extension+ matcher matches any nonempty path ending with the given extension:
402
399
 
403
400
  {:extension => "css"} # matches "/foo.css", "/bar.css"
404
401
  {:extension => "css"} # does not match "/foo.css/x", "/foo.bar", "/.css"
405
402
 
406
- This matcher yields the part before the extension.
403
+ This matcher yields the part found before the period and extension (e.g., +foo+).
407
404
 
408
405
  ==== :method
409
406
 
410
- This matches the method of the request. You can provide an array to specify multiple
411
- request methods and match on any of them:
407
+ The +:method+ matcher matches the method of the request.
408
+ You can provide an array to specify multiple request methods and match on any of them:
412
409
 
413
410
  {:method => :post} # matches POST
414
411
  {:method => ['post', 'patch']} # matches POST and PATCH
415
412
 
416
413
  ==== :param
417
414
 
418
- The :param matcher matches if the given parameter is present, even if empty.
415
+ The +:param+ matcher matches if the given parameter is present (even if it is empty).
419
416
 
420
417
  {:param => "user"} # matches "/foo?user=bar", "/foo?user="
421
418
  {:param => "user"} # does not matches "/foo"
422
419
 
423
420
  ==== :param!
424
421
 
425
- The :param! matcher matches if the given parameter is present and not empty.
422
+ The +:param!+ matcher matches if the given parameter is present and not empty.
426
423
 
427
424
  {:param! => "user"} # matches "/foo?user=bar"
428
425
  {:param! => "user"} # does not matches "/foo", "/foo?user="
429
426
 
430
427
  === false, nil
431
428
 
432
- If false or nil is given directly as a matcher, it doesn't match anything.
429
+ If +false+ or +nil+ is given directly as a matcher, it doesn't match anything.
433
430
 
434
431
  === Everything else
435
432
 
@@ -437,14 +434,15 @@ Everything else matches anything.
437
434
 
438
435
  == Status codes
439
436
 
440
- When it comes time to finalize a response, if a status code has not
441
- been set manually, it will use a 200 status code if anything has been
442
- written to the response, otherwise it will use a 404 status code.
443
- This enables the principle of least surprise to work, where if you
444
- don't handle an action, a 404 response is assumed.
437
+ When it comes time to finalize a response,
438
+ if a status code has not been set manually and anything has been written to the response,
439
+ the response will use a 200 status code.
440
+ Otherwise, it will use a 404 status code.
441
+ This enables the principle of least surprise to work:
442
+ if you don't handle an action, a 404 response is assumed.
445
443
 
446
- You can always set the status code manually via the status attribute
447
- for the response.
444
+ You can always set the status code manually,
445
+ via the +status+ attribute for the response.
448
446
 
449
447
  route do |r|
450
448
  r.get "hello" do
@@ -454,9 +452,10 @@ for the response.
454
452
 
455
453
  == Verb Methods
456
454
 
457
- The main match method is +r.on+, but as displayed above, you can also
458
- use +r.get+ or +r.post+. When called without any arguments, these
459
- match as long as the request has the appropriate method, so:
455
+ The main match method is +r.on+, but as displayed above,
456
+ you can also use +r.get+ or +r.post+.
457
+ When called without any arguments, these match as long
458
+ as the request has the appropriate method, so:
460
459
 
461
460
  r.get do end
462
461
 
@@ -468,7 +467,7 @@ matches any +POST+ request
468
467
 
469
468
  If any arguments are given to the method, these match only
470
469
  if the request method matches, all arguments match, and
471
- only the path has been fully matched by the arguments. So:
470
+ only the path has been fully matched by the arguments, so:
472
471
 
473
472
  r.post "" do end
474
473
 
@@ -478,89 +477,91 @@ matches only +POST+ requests where the current path is +/+.
478
477
 
479
478
  matches only +GET+ requests where the current path is +/a/b+.
480
479
 
481
- The reason for this difference in behavior is that if you are not
482
- providing any arguments, you probably don't want to to also test
483
- for an exact match with the current path. If that is something
484
- you do want, you can provide true as an argument:
480
+ The reason for this difference in behavior is that
481
+ if you are not providing any arguments, you probably don't want
482
+ to also test for an exact match with the current path.
483
+ If that is something you do want, you can provide +true+ as an argument:
485
484
 
486
485
  r.on "foo" do
487
486
  r.get true do # Matches GET /foo, not GET /foo/.*
488
487
  end
489
488
  end
490
489
 
491
- If you want to match the request method and do a partial match
492
- on the request path instead of a full match, you need to use
493
- +r.on+ with the <tt>:method</tt> hash matcher:
490
+ If you want to match the request method
491
+ and do only a partial match on the request path,
492
+ you need to use +r.on+ with the <tt>:method</tt> hash matcher:
494
493
 
495
494
  r.on "foo", :method=>:get do # Matches GET /foo(/.*)?
496
495
  end
497
496
 
498
497
  == Root Method
499
498
 
500
- As displayed above, you can also use +r.root+ as a match method. This
501
- method matches +GET+ requests where the current path +/+. +r.root+ is
502
- similar to <tt>r.get ""</tt>, except that it does not consume the +/+ from the path.
499
+ As displayed above, you can also use +r.root+ as a match method.
500
+ This method matches +GET+ requests where the current path is +/+.
501
+ +r.root+ is similar to <tt>r.get ""</tt>,
502
+ except that it does not consume the +/+ from the path.
503
503
 
504
504
  Unlike the other matching methods, +r.root+ takes no arguments.
505
505
 
506
- Note that +r.root+ does not match if the path is empty, you should use
507
- <tt>r.get true</tt> for that. If you want to match either the
508
- the empty path or +/+, you can use <tt>r.get ["", true]</tt>.
506
+ Note that +r.root+ does not match if the path is empty;
507
+ you should use <tt>r.get true</tt> for that.
508
+ If you want to match either the the empty path or +/+,
509
+ you can use <tt>r.get ["", true]</tt>.
509
510
 
510
- Note that +r.root+ does not match non-GET requests, so to handle
511
- <tt>POST /</tt> requests, use <tt>r.post ''</tt>.
511
+ Note that +r.root+ only matches +GET+ requests.
512
+ So, to handle <tt>POST /</tt> requests, use <tt>r.post ''</tt>.
512
513
 
513
514
  == Request and Response
514
515
 
515
- While the request object is yielded to the route block, it is also
516
- available via the +request+ method. Likewise, the response object
517
- is available via the +response+ method.
516
+ While the request object is yielded to the +route+ block,
517
+ it is also available via the +request+ method.
518
+ Likewise, the response object is available via the +response+ method.
518
519
 
519
- The request object is an instance of a subclass of <tt>Rack::Request</tt>
520
- with some additional methods, and the response object is an
521
- instance of a subclass of <tt>Rack::Response</tt> with some additional
522
- methods.
520
+ The request object is an instance of a subclass of <tt>Rack::Request</tt>,
521
+ with some additional methods.
522
+ The response object is an instance of a subclass of <tt>Rack::Response</tt>,
523
+ with some additional methods.
523
524
 
524
- If you want to extend the request and response objects with additional
525
- modules, you can do so via the +request_module+ or +response_module+
526
- methods, or via plugins.
525
+ If you want to extend the request and response objects with additional modules,
526
+ you can do so via the +request_module+ or +response_module+ methods, or via plugins.
527
527
 
528
528
  == Pollution
529
529
 
530
- Roda tries very hard to avoid polluting the scope of the +route+
531
- block. The only instance variables defined by default in the scope of
532
- the +route+ block are <tt>@_request</tt> and <tt>@_response</tt>. The only methods defined
533
- (beyond the default methods for +Object+) are: +env+, +opts+, +request+,
534
- +response+, +call+, +session+, and +_route+ (private). Constants inside the
535
- Roda namespace are all prefixed with +Roda+ (e.g. <tt>Roda::RodaRequest</tt>). This
536
- should make it unlikely that Roda will cause a namespace issue with your
537
- application code.
530
+ Roda tries very hard to avoid polluting the scope of the +route+ block.
531
+ This should make it unlikely that Roda will cause namespace issues
532
+ with your application code:
533
+
534
+ - The only instance variables defined by default in the scope of the +route+ block
535
+ are <tt>@_request</tt> and <tt>@_response</tt>.
536
+ - The only methods defined (beyond the default methods for +Object+) are:
537
+ +env+, +opts+, +request+, +response+, +call+, +session+, and +_route+ (private).
538
+ - Constants inside the Roda namespace are all prefixed with +Roda+
539
+ (e.g., <tt>Roda::RodaRequest</tt>).
538
540
 
539
541
  == Captures
540
542
 
541
- You may have noticed that some matchers yield a value to the block. The rules
542
- for determining if a matcher will yield a value are simple:
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:
543
545
 
544
546
  1. Regexp captures: <tt>/posts\/(\d+)-(.*)/</tt> will yield two values, corresponding to each capture.
545
547
  2. String placeholders: <tt>"users/:id"</tt> will yield the value in the position of +:id+.
546
548
  3. Symbols: +:foobar+ will yield if a segment is available.
547
549
  4. File extensions: <tt>:extension=>"css"</tt> will yield the basename of the matched file.
548
- 5. Parameters: <tt>:param=>"user"</tt> will yield the value of the parameter user, if present.
550
+ 5. Parameters: <tt>:param=>"user"</tt> will yield the value of the parameter +user+, if present.
549
551
 
550
- The first case is important because it shows the underlying effect of regex
551
- captures.
552
+ The first case is important because it shows the underlying effect of Regexp captures.
552
553
 
553
- In the second case, the substring +:id+ gets replaced by <tt>([^\\/]+)</tt> and the
554
- regexp becomes <tt>/users\/([^\/]+)/</tt> before performing the match, thus it reverts
555
- to the first form we saw.
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.
556
557
 
557
- In the third case, the symbol, no matter what it says, gets replaced
558
- by <tt>/([^\\/]+)/</tt>, and again we are in presence of case 1.
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.
559
560
 
560
561
  The fourth case, again, reverts to the basic matcher: it generates the string
561
562
  <tt>/([^\/]+?)\.#{ext}\z/</tt> before performing the match.
562
563
 
563
- The fifth case is different: it checks if the the parameter supplied is present
564
+ The fifth case is different: it checks if the parameter supplied is present
564
565
  in the request (via POST or QUERY_STRING) and it pushes the value as a capture.
565
566
 
566
567
  == Composition
@@ -588,19 +589,19 @@ inside a Roda app, using +r.run+:
588
589
 
589
590
  run App.app
590
591
 
591
- This will take any path starting with +/api+ and send it to +API+. In this
592
- example, +API+ is a Roda app, but it could easily be a Sinatra, Rails, or
593
- other Rack app.
592
+ This will take any path starting with +/api+ and send it to +API+.
593
+ In this example, +API+ is a Roda app, but it could easily be
594
+ a Sinatra, Rails, or other Rack app.
594
595
 
595
- When you use +r.run+, Roda calls the given Rack app (+API+ in this
596
- case), and whatever the Rack app returns will be returned as the response
597
- for the current application.
596
+ When you use +r.run+, Roda calls the given Rack app (+API+ in this case);
597
+ whatever the Rack app returns will be returned
598
+ as the response for the current application.
598
599
 
599
600
  === multi_route plugin
600
601
 
601
- If you are just looking to split up the main route block up by branches, you
602
- should use the +multi_route+ plugin, which keeps the current scope of
603
- the route block:
602
+ If you are just looking to split up the main route block up by branches,
603
+ you should use the +multi_route+ plugin,
604
+ which keeps the current scope of the +route+ block:
604
605
 
605
606
  class App < Roda
606
607
  plugin :multi_route
@@ -620,20 +621,20 @@ the route block:
620
621
 
621
622
  run App.app
622
623
 
623
- This allows you to set instance variables in the main route block, and still
624
- have access to them inside the +api+ route block.
624
+ This allows you to set instance variables in the main +route+ block
625
+ and still have access to them inside the +api+ +route+ block.
625
626
 
626
627
  == Testing
627
628
 
628
629
  It is very easy to test Roda with {Rack::Test}[https://github.com/brynary/rack-test]
629
- or {Capybara}[https://github.com/jnicklas/capybara]. Roda's own tests use
630
- {RSpec}[http://rspec.info]. The default rake task will run the specs for Roda, if
631
- RSpec is installed.
630
+ or {Capybara}[https://github.com/jnicklas/capybara].
631
+ Roda's own tests use {RSpec}[http://rspec.info].
632
+ The default Rake task will run the specs for Roda, if RSpec is installed.
632
633
 
633
634
  == Settings
634
635
 
635
- Each Roda app can store settings in the +opts+ hash. The settings are
636
- inherited if you happen to subclass +Roda+.
636
+ Each Roda app can store settings in the +opts+ hash.
637
+ The settings are inherited if you happen to subclass +Roda+.
637
638
 
638
639
  Roda.opts[:layout] = "guest"
639
640
 
@@ -645,26 +646,27 @@ inherited if you happen to subclass +Roda+.
645
646
  Users.opts[:layout] # => 'guest'
646
647
  Admin.opts[:layout] # => 'admin'
647
648
 
648
- Feel free to store whatever you find convenient. Note that when subclassing,
649
- Roda only does a shallow clone of the settings. If you store nested structures
650
- and plan to mutate them in subclasses, it is your responsibility to dup the nested
651
- structures inside +Roda.inherited+ (making sure to call +super+). The
652
- plugins that ship with Roda all handle this. Also, note that this means that
653
- future modifications to the parent class after subclassing do not affect the
654
- subclass.
649
+ Feel free to store whatever you find convenient.
650
+ Note that when subclassing, Roda only does a shallow clone of the settings.
651
+ If you store nested structures and plan to mutate them in subclasses,
652
+ it is your responsibility to dup the nested structures inside +Roda.inherited+
653
+ (making sure to call +super+).
654
+ The plugins that ship with Roda all handle this.
655
+ Also, note that this means that modifications to the parent class
656
+ made after subclassing do _not_ affect the subclass.
655
657
 
656
658
  == Rendering
657
659
 
658
- Roda ships with a +render+ plugin that provides helpers for rendering templates. It uses
659
- {Tilt}[https://github.com/rtomayko/tilt], a gem that interfaces with many template
660
- engines. The +erb+ engine is used by default.
660
+ Roda ships with a +render+ plugin that provides helpers for rendering templates.
661
+ It uses {Tilt}[https://github.com/rtomayko/tilt],
662
+ a gem that interfaces with many template engines.
663
+ The +erb+ engine is used by default.
661
664
 
662
- Note that in order to use this plugin you need to have Tilt installed, along
663
- with the templating engines you want to use.
665
+ Note that in order to use this plugin you need to have Tilt installed,
666
+ along with the templating engines you want to use.
664
667
 
665
668
  This plugin adds the +render+ and +view+ methods, for rendering templates.
666
- The difference between +render+ and +view+ is that +view+ will by default
667
- attempt to render the template inside the default layout template, where
669
+ By default, +view+ will render the template inside the default layout template;
668
670
  +render+ will just render the template.
669
671
 
670
672
  class App < Roda
@@ -674,8 +676,8 @@ attempt to render the template inside the default layout template, where
674
676
  @var = '1'
675
677
 
676
678
  r.is "render" do
677
- # Renders the views/home.erb template, which will have access to the
678
- # instance variable @var, as well as local variable content
679
+ # Renders the views/home.erb template, which will have access to
680
+ # the instance variable @var, as well as local variable content.
679
681
  render("home", :locals=>{:content => "hello, world"})
680
682
  end
681
683
 
@@ -706,9 +708,10 @@ You can override the default rendering options by passing a hash to the plugin:
706
708
 
707
709
  == Sessions
708
710
 
709
- By default, Roda doesn't turn on sessions, but most users are going to
710
- want to turn on session support, and the simplest way to do that is to
711
- use the <tt>Rack::Session::Cookie</tt> middleware that comes with rack:
711
+ By default, Roda doesn't turn on sessions,
712
+ but most users are going to want to turn on session support.
713
+ The simplest way to do this is to use the <tt>Rack::Session::Cookie</tt> middleware
714
+ that comes with Rack:
712
715
 
713
716
  require "roda"
714
717
 
@@ -718,39 +721,39 @@ use the <tt>Rack::Session::Cookie</tt> middleware that comes with rack:
718
721
 
719
722
  == Security
720
723
 
721
- Web application security is a very large topic, but here are some
722
- things you can do with Roda to prevent some common web application
723
- vulnerabilities.
724
+ Web application security is a very large topic,
725
+ but here are some things you can do with Roda
726
+ to prevent some common web application vulnerabilities.
724
727
 
725
728
  === Session Security
726
729
 
727
- If you are using sessions, you should also always set a session
728
- secret using the +:secret+ option as shown above. Make sure this
729
- secret is not disclosed, because if an attacker knows the +:secret+
730
- value, they can inject arbitrary session values, which in the worst case
731
- scenario can lead to remote code execution.
730
+ If you are using sessions, you should also always set a session secret,
731
+ using the +:secret+ option as shown above.
732
+ Make sure that this secret is not disclosed,
733
+ because if an attacker knows the +:secret+ value,
734
+ they can inject arbitrary session values.
735
+ In the worst case scenario, this can lead to remote code execution.
732
736
 
733
- Keep in mind that with <tt>Rack::Session::Cookie</tt>, the content in
734
- the session cookie is not encrypted, just signed to prevent tampering.
735
- This means you should not store any data in the session that itself is
736
- secret.
737
+ Keep in mind that with <tt>Rack::Session::Cookie</tt>,
738
+ the content in the session cookie is not encrypted,
739
+ just signed to prevent tampering.
740
+ This means you should not store any secret data in the session.
737
741
 
738
742
  === Cross Site Request Forgery (CSRF)
739
743
 
740
744
  CSRF can be prevented by using the +csrf+ plugin that ships with Roda,
741
- which uses the {rack_csrf}[https://github.com/baldowl/rack_csrf]
742
- library. Just make sure that you include the CSRF token tags in your
743
- html as appropriate.
745
+ which uses the {rack_csrf}[https://github.com/baldowl/rack_csrf] library.
746
+ Just make sure that you include the CSRF token tags in your HTML, as appropriate.
744
747
 
745
- It's also possible to use the <tt>Rack::Csrf</tt> middleware directly,
748
+ It's also possible to use the <tt>Rack::Csrf</tt> middleware directly;
746
749
  you don't have to use the +csrf+ plugin.
747
750
 
748
751
  === Cross Site Scripting (XSS)
749
752
 
750
753
  The easiest way to prevent XSS with Roda is to use a template library
751
- that automatically escapes output by default. The +:escape+ option
752
- to the render plugin sets the ERB template processor to escape by
753
- default, so that in your templates:
754
+ that automatically escapes output by default.
755
+ The +:escape+ option to the +render+ plugin sets the ERb template processor
756
+ to escape by default, so that in your templates:
754
757
 
755
758
  <%= '<>' %> # outputs &lt;&gt;
756
759
  <%== '<>' %> # outputs <>
@@ -759,10 +762,10 @@ This support requires {Erubis}[http://www.kuwata-lab.com/erubis/].
759
762
 
760
763
  === Other
761
764
 
762
- For prevention of some other vulnerabilities, such as click-jacking,
763
- directory traversal, session hijacking, and IP spoofing, consider using
764
- {Rack::Protection}[https://github.com/rkh/rack-protection], which is
765
- a rack middleware that can be added the usual way:
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:
766
769
 
767
770
  require 'roda'
768
771
  require 'rack/protection'
@@ -773,63 +776,17 @@ a rack middleware that can be added the usual way:
773
776
 
774
777
  == Plugins
775
778
 
776
- Roda provides a way to extend its functionality with plugins. Plugins can
777
- override any Roda method and call +super+ to get the default behavior.
778
-
779
- === Included Plugins
780
-
781
- These plugins ship with roda:
782
-
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.
787
- backtracking_array :: Allows array matchers to backtrack if later matchers
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.
792
- content_for :: Allows storage of content in one template and retrieval of
793
- that content in a different template.
794
- csrf :: Adds CSRF protection and helper methods using
795
- {rack_csrf}[https://github.com/baldowl/rack_csrf].
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.
799
- error_handler :: Adds a +error+ block that is called for all responses that
800
- raise exceptions.
801
- flash :: Adds a flash handler.
802
- h :: Adds h method for html escaping.
803
- halt :: Augments request#halt method to take status and/or body or status,
804
- headers, and body.
805
- head :: Treat HEAD requests like GET requests with an empty response body.
806
- header_matchers :: Adds host, header, and accept hash matchers.
807
- hooks :: Adds before and after methods to run code before and after requests.
808
- indifferent_params :: Adds params method with indifferent access to params,
809
- allowing use of symbol keys for accessing params.
810
- json :: Allows match blocks to return arrays and hashes, using a json
811
- representation as the response body.
812
- middleware :: Allows the Roda app to be used as a rack middleware, calling the
813
- next middleware if no route matches.
814
- multi_route :: Adds the ability for multiple named route blocks, with the
815
- ability to dispatch to them add any point in the main route block.
816
- not_allowed :: Adds support for automatically returning 405 Method Not Allowed
817
- responses.
818
- not_found :: Adds a +not_found+ block that is called for all 404 responses
819
- without bodies.
820
- pass :: Adds a pass method allowing you to skip the current +r.on+ block as if
821
- it did not match.
822
- path :: Adds support for named paths.
823
- per_thread_caching :: Switches the thread-safe cache from a shared cache to a
824
- per-thread cache.
825
- render :: Adds support for rendering templates via tilt, as described above.
826
- render_each :: Render a template for each value in an enumerable.
827
- streaming :: Adds support for streaming responses.
828
- symbol_matchers :: Adds support for symbol-specific matching regexps.
829
- symbol_views :: Allows match blocks to return template name symbols, uses the
830
- template view as the response body.
831
- view_subdirs :: Allows for setting a view subdirectory to use on a per-request
832
- basis.
779
+ By design, Roda has a very small core, providing only the essentials.
780
+ All nonessential features are added via plugins.
781
+ This is why Roda is referred to as a routing tree web framework toolkit.
782
+ Using a combination of Roda plugins,
783
+ you can build the routing tree web framework that needs your needs.
784
+
785
+ Roda's plugins can override any Roda method and call +super+
786
+ to get the default behavior, which makes Roda very extensible.
787
+
788
+ {Roda ships with a large number of plugins}[http://roda.jeremyevans.net/documentation.html#included-plugins],
789
+ and {some other libraries ship with support for Roda}[http://roda.jeremyevans.net/documentation.html#external].
833
790
 
834
791
  === External Plugins
835
792
 
@@ -841,8 +798,8 @@ autoforme :: Adds support for easily creating a simple administrative front
841
798
 
842
799
  === How to create plugins
843
800
 
844
- Authoring your own plugins is pretty straightforward. Plugins are just modules,
845
- which may contain any of the following modules:
801
+ Authoring your own plugins is pretty straightforward.
802
+ Plugins are just modules, which may contain any of the following modules:
846
803
 
847
804
  InstanceMethods :: module included in the Roda class
848
805
  ClassMethods :: module that extends the Roda class
@@ -851,16 +808,16 @@ RequestClassMethods :: module extending the class of the request
851
808
  ResponseMethods :: module included in the class of the response
852
809
  ResponseClassMethods :: module extending the class of the response
853
810
 
854
- If the plugin responds to +load_dependencies+, it will be called first, and should
855
- be used if the plugin depends on another plugin.
811
+ If the plugin responds to +load_dependencies+, it will be called first,
812
+ and should be used if the plugin depends on another plugin.
856
813
 
857
- If the plugin responds to +configure+, it will be called last, and should be
858
- used to configure the plugin.
814
+ If the plugin responds to +configure+, it will be called last,
815
+ and should be used to configure the plugin.
859
816
 
860
- Both +load_dependencies+ and +configure+ are called with the additional arguments
861
- and block given to the plugin call.
817
+ Both +load_dependencies+ and +configure+ are called
818
+ with the additional arguments and block that was given to the plugin call.
862
819
 
863
- So a simple plugin to add an instance method would be:
820
+ So, a simple plugin to add an instance method would be:
864
821
 
865
822
  module MarkdownHelper
866
823
  module InstanceMethods
@@ -874,14 +831,15 @@ So a simple plugin to add an instance method would be:
874
831
 
875
832
  === Registering plugins
876
833
 
877
- If you want to ship a Roda plugin in a gem, but still have
878
- Roda load it automatically via <tt>Roda.plugin :plugin_name</tt>, you should
879
- place it where it can be required via +roda/plugins/plugin_name+, and
880
- then have the file register it as a plugin via
881
- <tt>Roda::RodaPlugins.register_plugin</tt>. It's recommended but not required
882
- that you store your plugin module in the <tt>Roda::RodaPlugins</tt> namespace:
834
+ If you want to ship a Roda plugin in a gem,
835
+ but still have Roda load it automatically via <tt>Roda.plugin :plugin_name</tt>,
836
+ you should place it where it can be required via +roda/plugins/plugin_name+
837
+ and then have the file register it as a plugin via
838
+ <tt>Roda::RodaPlugins.register_plugin</tt>.
839
+ It's recommended, but not required, that you store your plugin module
840
+ in the <tt>Roda::RodaPlugins</tt> namespace:
883
841
 
884
- module Roda
842
+ class Roda
885
843
  module RodaPlugins
886
844
  module Markdown
887
845
  module InstanceMethods
@@ -895,10 +853,11 @@ that you store your plugin module in the <tt>Roda::RodaPlugins</tt> namespace:
895
853
  end
896
854
  end
897
855
 
898
- You should avoid creating your module directly in the +Roda+ namespace
899
- to avoid polluting the namespace. Additionally, any instance variables
900
- created inside InstanceMethods should be prefixed with an underscore
901
- (e.g. <tt>@_variable</tt>) to avoid polluting the scope.
856
+ To avoid namespace pollution,
857
+ you should avoid creating your module directly in the +Roda+ namespace.
858
+ Additionally, any instance variables created inside +InstanceMethods+
859
+ should be prefixed with an underscore (e.g., <tt>@_variable</tt>)
860
+ to avoid polluting the scope.
902
861
 
903
862
  == License
904
863