renee 0.3.11 → 0.4.0.pre1

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 (231) hide show
  1. data/Gemfile +17 -0
  2. data/Gemfile-renee +8 -0
  3. data/Gemfile-renee-core +8 -0
  4. data/Gemfile-renee-render +9 -0
  5. data/Gemfile-renee-session +9 -0
  6. data/Gemfile-renee-url-generation +8 -0
  7. data/MIT-LICENSE.txt +7 -0
  8. data/README-renee-core.md +242 -0
  9. data/README-renee-render.md +38 -0
  10. data/README-renee-session.md +3 -0
  11. data/README-renee-url-generation.md +3 -0
  12. data/README.md +131 -6
  13. data/Rakefile +109 -9
  14. data/TODO.txt +45 -0
  15. data/config.ru +26 -0
  16. data/examples/blog/blog.rb +3 -1
  17. data/examples/blog/config.ru +24 -19
  18. data/examples/blog/views/edit.erb +10 -1
  19. data/examples/blog/views/show.erb +5 -0
  20. data/lib/renee.rb +11 -4
  21. data/lib/renee/core.rb +98 -0
  22. data/lib/renee/core/chaining.rb +66 -0
  23. data/lib/renee/core/env_accessors.rb +72 -0
  24. data/lib/renee/core/exceptions.rb +15 -0
  25. data/lib/renee/core/matcher.rb +61 -0
  26. data/lib/renee/core/plugins.rb +31 -0
  27. data/lib/renee/core/rack_interaction.rb +50 -0
  28. data/lib/renee/core/request_context.rb +56 -0
  29. data/lib/renee/core/responding.rb +112 -0
  30. data/lib/renee/core/response.rb +78 -0
  31. data/lib/renee/core/routing.rb +319 -0
  32. data/lib/renee/core/transform.rb +18 -0
  33. data/lib/renee/render.rb +221 -0
  34. data/lib/renee/session.rb +50 -0
  35. data/lib/renee/url_generation.rb +117 -0
  36. data/lib/renee/util.rb +7 -0
  37. data/lib/renee/version.rb +2 -4
  38. data/plan.txt +19 -0
  39. data/renee-core.gemspec +26 -0
  40. data/renee-render.gemspec +30 -0
  41. data/renee-session.gemspec +28 -0
  42. data/renee-url-generation.gemspec +24 -0
  43. data/renee.gemspec +5 -6
  44. data/site/MIT-LICENSE.txt +7 -0
  45. data/site/public/css/app.css +75 -0
  46. data/site/public/docs/renee-core/Renee.html +208 -0
  47. data/site/public/docs/renee-core/Renee/Core.html +366 -0
  48. data/site/public/docs/renee-core/Renee/Core/Chaining.html +192 -0
  49. data/site/public/docs/renee-core/Renee/Core/ClassMethods.html +725 -0
  50. data/site/public/docs/renee-core/Renee/Core/ClientError.html +317 -0
  51. data/site/public/docs/renee-core/Renee/Core/EnvAccessors.html +152 -0
  52. data/site/public/docs/renee-core/Renee/Core/EnvAccessors/ClassMethods.html +354 -0
  53. data/site/public/docs/renee-core/Renee/Core/Matcher.html +675 -0
  54. data/site/public/docs/renee-core/Renee/Core/Plugins.html +475 -0
  55. data/site/public/docs/renee-core/Renee/Core/RackInteraction.html +488 -0
  56. data/site/public/docs/renee-core/Renee/Core/RequestContext.html +511 -0
  57. data/site/public/docs/renee-core/Renee/Core/Responding.html +877 -0
  58. data/site/public/docs/renee-core/Renee/Core/Response.html +691 -0
  59. data/site/public/docs/renee-core/Renee/Core/Routing.html +1589 -0
  60. data/site/public/docs/renee-core/Renee/Core/Transform.html +249 -0
  61. data/site/public/docs/renee-core/Renee/Core/URLGeneration.html +597 -0
  62. data/site/public/docs/renee-core/_index.html +244 -0
  63. data/site/public/docs/renee-core/class_list.html +47 -0
  64. data/site/public/docs/renee-core/css/common.css +1 -0
  65. data/site/public/docs/renee-core/css/full_list.css +55 -0
  66. data/site/public/docs/renee-core/css/style.css +322 -0
  67. data/site/public/docs/renee-core/file.README-renee-core.html +341 -0
  68. data/site/public/docs/renee-core/file.README.html +212 -0
  69. data/site/public/docs/renee-core/file_list.html +49 -0
  70. data/site/public/docs/renee-core/frames.html +13 -0
  71. data/site/public/docs/renee-core/index.html +341 -0
  72. data/site/public/docs/renee-core/js/app.js +205 -0
  73. data/site/public/docs/renee-core/js/full_list.js +167 -0
  74. data/site/public/docs/renee-core/js/jquery.js +16 -0
  75. data/site/public/docs/renee-core/method_list.html +590 -0
  76. data/site/public/docs/renee-core/top-level-namespace.html +103 -0
  77. data/site/public/docs/renee-render/Renee.html +116 -0
  78. data/site/public/docs/renee-render/Renee/Core.html +346 -0
  79. data/site/public/docs/renee-render/Renee/Core/Chaining.html +125 -0
  80. data/site/public/docs/renee-render/Renee/Core/ClassMethods.html +620 -0
  81. data/site/public/docs/renee-render/Renee/Core/ClientError.html +317 -0
  82. data/site/public/docs/renee-render/Renee/Core/EnvAccessors.html +152 -0
  83. data/site/public/docs/renee-render/Renee/Core/EnvAccessors/ClassMethods.html +354 -0
  84. data/site/public/docs/renee-render/Renee/Core/Matcher.html +675 -0
  85. data/site/public/docs/renee-render/Renee/Core/RackInteraction.html +488 -0
  86. data/site/public/docs/renee-render/Renee/Core/RequestContext.html +421 -0
  87. data/site/public/docs/renee-render/Renee/Core/Responding.html +873 -0
  88. data/site/public/docs/renee-render/Renee/Core/Response.html +691 -0
  89. data/site/public/docs/renee-render/Renee/Core/Routing.html +1682 -0
  90. data/site/public/docs/renee-render/Renee/Core/Transform.html +249 -0
  91. data/site/public/docs/renee-render/Renee/Core/URLGeneration.html +597 -0
  92. data/site/public/docs/renee-render/Renee/Render.html +873 -0
  93. data/site/public/docs/renee-render/Renee/Render/ClassMethods.html +382 -0
  94. data/site/public/docs/renee-render/Renee/Render/TemplateNotFound.html +126 -0
  95. data/site/public/docs/renee-render/_index.html +143 -0
  96. data/site/public/docs/renee-render/class_list.html +47 -0
  97. data/site/public/docs/renee-render/css/common.css +1 -0
  98. data/site/public/docs/renee-render/css/full_list.css +55 -0
  99. data/site/public/docs/renee-render/css/style.css +322 -0
  100. data/site/public/docs/renee-render/file.README-renee-render.html +104 -0
  101. data/site/public/docs/renee-render/file.README.html +212 -0
  102. data/site/public/docs/renee-render/file_list.html +49 -0
  103. data/site/public/docs/renee-render/frames.html +13 -0
  104. data/site/public/docs/renee-render/index.html +104 -0
  105. data/site/public/docs/renee-render/js/app.js +205 -0
  106. data/site/public/docs/renee-render/js/full_list.js +167 -0
  107. data/site/public/docs/renee-render/js/jquery.js +16 -0
  108. data/site/public/docs/renee-render/method_list.html +110 -0
  109. data/site/public/docs/renee-render/top-level-namespace.html +103 -0
  110. data/site/public/docs/renee-session/Renee.html +106 -0
  111. data/site/public/docs/renee-session/Renee/Session.html +173 -0
  112. data/site/public/docs/renee-session/Renee/Session/ClassMethods.html +470 -0
  113. data/site/public/docs/renee-session/_index.html +136 -0
  114. data/site/public/docs/renee-session/class_list.html +47 -0
  115. data/site/public/docs/renee-session/css/common.css +1 -0
  116. data/site/public/docs/renee-session/css/full_list.css +55 -0
  117. data/site/public/docs/renee-session/css/style.css +322 -0
  118. data/site/public/docs/renee-session/file.README-renee-core.html +341 -0
  119. data/site/public/docs/renee-session/file.README-renee-session.html +69 -0
  120. data/site/public/docs/renee-session/file_list.html +49 -0
  121. data/site/public/docs/renee-session/frames.html +13 -0
  122. data/site/public/docs/renee-session/index.html +69 -0
  123. data/site/public/docs/renee-session/js/app.js +205 -0
  124. data/site/public/docs/renee-session/js/full_list.js +167 -0
  125. data/site/public/docs/renee-session/js/jquery.js +16 -0
  126. data/site/public/docs/renee-session/method_list.html +102 -0
  127. data/site/public/docs/renee-session/top-level-namespace.html +103 -0
  128. data/site/public/docs/renee-url-generation/Renee.html +208 -0
  129. data/site/public/docs/renee-url-generation/Renee/Core.html +366 -0
  130. data/site/public/docs/renee-url-generation/Renee/Core/Chaining.html +192 -0
  131. data/site/public/docs/renee-url-generation/Renee/Core/ClassMethods.html +725 -0
  132. data/site/public/docs/renee-url-generation/Renee/Core/ClientError.html +317 -0
  133. data/site/public/docs/renee-url-generation/Renee/Core/EnvAccessors.html +152 -0
  134. data/site/public/docs/renee-url-generation/Renee/Core/EnvAccessors/ClassMethods.html +354 -0
  135. data/site/public/docs/renee-url-generation/Renee/Core/Matcher.html +675 -0
  136. data/site/public/docs/renee-url-generation/Renee/Core/Plugins.html +475 -0
  137. data/site/public/docs/renee-url-generation/Renee/Core/RackInteraction.html +488 -0
  138. data/site/public/docs/renee-url-generation/Renee/Core/RequestContext.html +511 -0
  139. data/site/public/docs/renee-url-generation/Renee/Core/Responding.html +877 -0
  140. data/site/public/docs/renee-url-generation/Renee/Core/Response.html +691 -0
  141. data/site/public/docs/renee-url-generation/Renee/Core/Routing.html +1589 -0
  142. data/site/public/docs/renee-url-generation/Renee/Core/Transform.html +249 -0
  143. data/site/public/docs/renee-url-generation/_index.html +244 -0
  144. data/site/public/docs/renee-url-generation/class_list.html +47 -0
  145. data/site/public/docs/renee-url-generation/css/common.css +1 -0
  146. data/site/public/docs/renee-url-generation/css/full_list.css +55 -0
  147. data/site/public/docs/renee-url-generation/css/style.css +322 -0
  148. data/site/public/docs/renee-url-generation/file.README-renee-url-generation.html +69 -0
  149. data/site/public/docs/renee-url-generation/file_list.html +49 -0
  150. data/site/public/docs/renee-url-generation/frames.html +13 -0
  151. data/site/public/docs/renee-url-generation/index.html +69 -0
  152. data/site/public/docs/renee-url-generation/js/app.js +205 -0
  153. data/site/public/docs/renee-url-generation/js/full_list.js +167 -0
  154. data/site/public/docs/renee-url-generation/js/jquery.js +16 -0
  155. data/site/public/docs/renee-url-generation/method_list.html +590 -0
  156. data/site/public/docs/renee-url-generation/top-level-namespace.html +103 -0
  157. data/site/public/docs/renee/Renee.html +232 -0
  158. data/site/public/docs/renee/Renee/Application.html +367 -0
  159. data/site/public/docs/renee/Renee/Core.html +370 -0
  160. data/site/public/docs/renee/Renee/Core/Chaining.html +192 -0
  161. data/site/public/docs/renee/Renee/Core/ClassMethods.html +725 -0
  162. data/site/public/docs/renee/Renee/Core/ClientError.html +317 -0
  163. data/site/public/docs/renee/Renee/Core/EnvAccessors.html +152 -0
  164. data/site/public/docs/renee/Renee/Core/EnvAccessors/ClassMethods.html +354 -0
  165. data/site/public/docs/renee/Renee/Core/Matcher.html +675 -0
  166. data/site/public/docs/renee/Renee/Core/Plugins.html +475 -0
  167. data/site/public/docs/renee/Renee/Core/RackInteraction.html +488 -0
  168. data/site/public/docs/renee/Renee/Core/RequestContext.html +511 -0
  169. data/site/public/docs/renee/Renee/Core/Responding.html +877 -0
  170. data/site/public/docs/renee/Renee/Core/Response.html +691 -0
  171. data/site/public/docs/renee/Renee/Core/Routing.html +1589 -0
  172. data/site/public/docs/renee/Renee/Core/Transform.html +249 -0
  173. data/site/public/docs/renee/Renee/Core/URLGeneration.html +597 -0
  174. data/site/public/docs/renee/Renee/Render.html +877 -0
  175. data/site/public/docs/renee/Renee/Render/ClassMethods.html +382 -0
  176. data/site/public/docs/renee/Renee/Render/TemplateNotFound.html +126 -0
  177. data/site/public/docs/renee/Renee/Session.html +177 -0
  178. data/site/public/docs/renee/Renee/Session/ClassMethods.html +470 -0
  179. data/site/public/docs/renee/Renee/URLGeneration.html +142 -0
  180. data/site/public/docs/renee/Renee/URLGeneration/ClassMethods.html +593 -0
  181. data/site/public/docs/renee/Renee/Util.html +163 -0
  182. data/site/public/docs/renee/_index.html +336 -0
  183. data/site/public/docs/renee/class_list.html +47 -0
  184. data/site/public/docs/renee/css/common.css +1 -0
  185. data/site/public/docs/renee/css/full_list.css +55 -0
  186. data/site/public/docs/renee/css/style.css +322 -0
  187. data/site/public/docs/renee/file.README.html +212 -0
  188. data/site/public/docs/renee/file_list.html +49 -0
  189. data/site/public/docs/renee/frames.html +13 -0
  190. data/site/public/docs/renee/index.html +212 -0
  191. data/site/public/docs/renee/js/app.js +205 -0
  192. data/site/public/docs/renee/js/full_list.js +167 -0
  193. data/site/public/docs/renee/js/jquery.js +16 -0
  194. data/site/public/docs/renee/method_list.html +758 -0
  195. data/site/public/docs/renee/top-level-namespace.html +202 -0
  196. data/site/public/img/favicon.ico +0 -0
  197. data/site/public/img/reneeclean.png +0 -0
  198. data/site/public/img/russiangithub.png +0 -0
  199. data/site/public/img/stoneposter.png +0 -0
  200. data/site/public/img/vospit.jpeg +0 -0
  201. data/site/views/chaining.md +32 -0
  202. data/site/views/index.md +219 -0
  203. data/site/views/layouts/app.haml +16 -0
  204. data/site/views/rack-integration.md +51 -0
  205. data/site/views/responding.md +103 -0
  206. data/site/views/route-generation.md +82 -0
  207. data/site/views/routing.md +261 -0
  208. data/site/views/settings.md +19 -0
  209. data/site/views/team-renee.md +13 -0
  210. data/site/views/tutorial.md +57 -0
  211. data/site/views/variable-types.md +57 -0
  212. data/test.watchr +61 -0
  213. data/test/renee-core/chaining_test.rb +33 -0
  214. data/test/renee-core/env_accessors_test.rb +43 -0
  215. data/test/renee-core/include_test.rb +14 -0
  216. data/test/renee-core/request_context_test.rb +70 -0
  217. data/test/renee-core/responding_test.rb +128 -0
  218. data/test/renee-core/routing_test.rb +443 -0
  219. data/test/renee-core/test_helper.rb +4 -0
  220. data/test/renee-core/variable_type_test.rb +57 -0
  221. data/test/renee-render/render_test.rb +162 -0
  222. data/test/renee-render/test_helper.rb +9 -0
  223. data/test/renee-session/session_test.rb +31 -0
  224. data/test/renee-session/test_helper.rb +9 -0
  225. data/test/renee-url-generation/test_helper.rb +10 -0
  226. data/test/renee-url-generation/url_generation_test.rb +63 -0
  227. data/test/{blog_test.rb → renee/blog_test.rb} +10 -5
  228. data/test/renee/test_helper.rb +56 -0
  229. data/test/test_helper.rb +23 -10
  230. metadata +333 -156
  231. data/.yardopts +0 -6
@@ -0,0 +1,16 @@
1
+ !!!
2
+ %html
3
+ %head
4
+ %title Renee #{title_part}
5
+ %link{ :href => "/css/app.css", :rel => "stylesheet" }
6
+ %link{ :rel => 'icon', :href => "/img/favicon.ico" }
7
+ %script{ :type => 'text/javascript', :src => "/js/jquery-1.6.4.min.js" }
8
+ %script{ :type => 'text/javascript', :src => "/js/app.js" }
9
+ %body
10
+ %a{ :href => "https://github.com/renee-project/renee" }
11
+ %img{ :src => '/img/russiangithub.png', :style => 'position: absolute; top: 0; left: 0; border: 0;'}
12
+ .container
13
+ .logo
14
+ %a{ :href => "/" }
15
+ %img{ :src => "/img/reneeclean.png", :title => 'IN COMMUNIST RUSSIA RENEE FRAMEWORK YOU'}
16
+ = preserve(yield)
@@ -0,0 +1,51 @@
1
+ # Rack integration
2
+
3
+ Renee loves Rack. To create a new Renee application, create a rackup file (typically `config.ru`) and load it using [shotgun](https://rubygems.org/gems/shotgun).
4
+
5
+ :::ruby
6
+ # config.ru
7
+ run Renee do
8
+ # ...
9
+ end
10
+
11
+ From here, you can start consuming parts of the path. Consider:
12
+
13
+ :::ruby
14
+ # config.ru
15
+ run Renee do
16
+ puts env['SCRIPT_NAME'] # /
17
+ puts env['PATH_INFO'] # /blog/something
18
+ path 'blog' do
19
+ puts env['SCRIPT_NAME'] # /blog
20
+ puts env['PATH_INFO'] # /something
21
+ # ..
22
+ end
23
+ end
24
+
25
+ The path is being shifted from PATH_INFO and onto the SCRIPT_NAME. This makes it easy to stop what you're doing, and call into a Rack application, as your `env` will be in the correct state for dispatching to another Rack application. To dispatch at any point you can use `#run!`. Example:
26
+
27
+ :::ruby
28
+ # config.ru
29
+ OtherApp = proc { |env| [200, {}, [env['SCRIPT_NAME'], env['PATH_INFO']]]}
30
+
31
+ run Renee do
32
+ path 'blog' do
33
+ run! OtherApp
34
+ end
35
+ end
36
+
37
+ Now, any request starting with `/blog` will be dispatched to `OtherApp`.
38
+
39
+ If you'd like to use a full Rack::Builder, you can use `#build!`.
40
+
41
+ :::ruby
42
+ run Renee do
43
+ path 'blog' do
44
+ build! do
45
+ use SomeMiddleware
46
+ run SomeRackApplication
47
+ end
48
+ end
49
+ end
50
+
51
+ Full documentation can be found under the YARD docs for [`Renee::Core::Application::RackIntegration`](http://reneerb.com/doc/core/Renee/Core/Application/RackInteraction.html).
@@ -0,0 +1,103 @@
1
+ # Responding
2
+
3
+ ## A note about bang methods
4
+
5
+ Any method that ends with ! (a bang method) will do whatever the non-bang version of that method will do,
6
+ but in addition, it will halt with that response.
7
+
8
+ ## `#halt`
9
+
10
+ Halt will immediately stop processing and respond with the value passed to it. It will respond
11
+ in different ways depending on what was passed to it.
12
+
13
+ ### `Symbol`
14
+
15
+ If it's a symbol, it will attempt to look it up in [`Renee::Core::Application::Responding::HTTP_CODES`](http://reneerb.com/doc/core/Renee/Core/Application/Responding.html).
16
+
17
+ :::ruby
18
+ # Return status with symbol
19
+ halt :not_found
20
+
21
+ ### `String`
22
+
23
+ It will use this to create a Rack::Response object and call `#finish` on it.
24
+
25
+ :::ruby
26
+ # Return 200 with body
27
+ halt "hello!"
28
+
29
+ ### `Array`
30
+
31
+ It will attempt to interpret this as a Rack response.
32
+
33
+ :::ruby
34
+ # Return 200 with body
35
+ halt [200, {}, 'body']
36
+
37
+ ### `Integer`
38
+
39
+ It will return this as a status code.
40
+
41
+ :::ruby
42
+ # Return just 200 status code
43
+ halt 200
44
+
45
+ ## `#respond` (and `#respond!`)
46
+
47
+ The `respond` command makes returning a rack response very explicit,
48
+ you can respond as if you were constructing a Rack::Response
49
+
50
+ :::ruby
51
+ run Renee {
52
+ get { respond!("hello!", 403, "foo" => "bar") }
53
+ }
54
+
55
+ or use the block DSL for convenience:
56
+
57
+ :::ruby
58
+ run Renee {
59
+ get { respond! { status 403; headers :foo => "bar"; body "hello!" } }
60
+ }
61
+
62
+ ## `#redirect` (and `#redirect!`)
63
+
64
+ This will return a rack-response to the path supplied and an optional HTTP status code.
65
+
66
+ :::ruby
67
+ get {
68
+ redirect!('/hello')
69
+ }
70
+
71
+ You can also specify the status code for the redirect:
72
+
73
+ :::ruby
74
+ get {
75
+ redirect!('/hello', 303)
76
+ }
77
+
78
+ ## `#render` (and `#render!`)
79
+
80
+ This will render a template based on the rendering options supplied. The simplest render is just:
81
+
82
+ :::ruby
83
+ render! "index"
84
+
85
+ Assuming you have a views_path setup (see [Settings](/settings)), this will render the first template named `index`.
86
+ You can also specify the template engine explicitly with:
87
+
88
+ :::ruby
89
+ render! "index.haml"
90
+
91
+ This will locate and render the haml template (`index.haml`) within views. You can also pass local variables to
92
+ the template:
93
+
94
+ :::ruby
95
+ render! "index", :locals => { :foo => "bar" }
96
+
97
+ and then access them as expected within the template. Using a layout is also as simple as specifying the
98
+ layout template with a render:
99
+
100
+ :::ruby
101
+ render! "index", :layout => "base"
102
+
103
+ This will render the index template within the base template in the views folder.
@@ -0,0 +1,82 @@
1
+ # Route generation
2
+
3
+ To register paths for later generation, you have four methods at your disposal: `#register`, `#prefix`, `#path`, and `#url`.
4
+
5
+ ## `#register`
6
+
7
+ This allows you to register a route for later generation:
8
+
9
+ :::ruby
10
+ app = Renee.new
11
+ app.register(:path, '/path')
12
+ app.path(:path) # Would return '/path'
13
+
14
+ This also allows for named variables in the path:
15
+
16
+ :::ruby
17
+ app = Renee.new
18
+ app.register(:path, '/path/:id')
19
+ app.path(:path, 123) # Would return '/path/123'
20
+ app.path(:path, :id => 123) # This would also return '/path/123'
21
+
22
+ If you have default values for variables, you can pass them in on the `#register` call:
23
+
24
+ :::ruby
25
+ app = Renee.new
26
+ app.register(:blog_get, '/blog/:page', :page => 1)
27
+ app.path(:blog_get) # Would return '/blog/1'
28
+ app.path(:blog_get, 5) # Would return '/blog/5'
29
+
30
+ ## `#prefix`
31
+
32
+ This allows you to define common parts for nicer re-use:
33
+
34
+ :::ruby
35
+ app = Renee.new
36
+ app.prefix("http://mydomain.com") {
37
+ app.register(:test, "/test")
38
+ app.register(:test2, "/test2")
39
+ }
40
+ app.url(:test) # Would return http://mydomain.com/test
41
+ app.url(:test2) # Would return http://mydomain.com/test2
42
+
43
+ You can even store the objects created by `#prefix` and use them later. In the above example, this would also be equivalent:
44
+
45
+ :::ruby
46
+ app = Renee.new
47
+ domain_prefix = app.prefix("http://mydomain.com")
48
+ domain_prefix.register(:test, "/test")
49
+ domain_prefix.register(:test, "/test2")
50
+
51
+ This makes registering similar routes more concise.
52
+
53
+ ## `#path`
54
+
55
+ This creates paths for the paths you have registered. The first parameter is the name of the route. After that an optional hash can be
56
+ supplied to dictate the value of variables in the path. Any key-values not consumed by the path will be appended as a query string to
57
+ the generated path.
58
+
59
+ Example:
60
+
61
+ :::ruby
62
+ app = Renee.new
63
+ app.register(:blog, '/blog')
64
+ app.path(:blog) # Would return '/blog'
65
+ app.path(:blog, :page => 1) # Would return '/blog?page=1'
66
+
67
+ ## `#url`
68
+
69
+ This is identical to path with one special consideration. If the registered path had a scheme, host or port, it will be added to the generated path:
70
+
71
+ :::ruby
72
+ app = Renee.new
73
+ app.register(:blog, 'http://localhost/blog')
74
+ app.url(:blog) # Would return 'http://localhost/blog'
75
+
76
+ If you leave off the scheme, this will create scheme in-variant URLs:
77
+
78
+ :::ruby
79
+ app = Renee.new
80
+ app.register(:blog, '://localhost/blog')
81
+ app.url(:blog) # Would return '://localhost/blog',
82
+ # did I mention, these are awesome?
@@ -0,0 +1,261 @@
1
+ # Routing
2
+
3
+ ## Rack integration
4
+
5
+ ### `#run` (and `#run!`)
6
+
7
+ This method will take whatever is passed to it and send `#call` to it.
8
+
9
+ ### `#build` (and `#build!`)
10
+
11
+ This method will take run the code block passed to it and wrap it with a Rack::Builder, then run it.
12
+
13
+ Example:
14
+
15
+ :::ruby
16
+ Renee {
17
+ build! {
18
+ use Rack::ContentLength
19
+ run proc {|env| [200, {}, ["hello rack!"]]}
20
+ }
21
+ }
22
+
23
+ ## Request context
24
+
25
+ The most basic part of Renee is the request context. This gives you access to the current env,
26
+ a Rack::Request wrapped version of the env.
27
+
28
+ ## Path-based
29
+
30
+ All path based routing proceeds by removing the matched part from `PATH_INFO`, and adding it to the end of
31
+ `SCRIPT_NAME` before executing the block passed to it. Therefore, only the path based routing method mutate
32
+ the rack environment, and they are the only methods that do so.
33
+
34
+ ### `#path`
35
+
36
+ This will match the part supplied to it.
37
+
38
+ Example:
39
+
40
+ :::ruby
41
+ Renee {
42
+ path('test') {
43
+ halt 'i got /test!' # your path must start with /test to get here.
44
+ }
45
+ }
46
+
47
+ Paths can also be nested within one another:
48
+
49
+ :::ruby
50
+ Renee {
51
+ path('blog') {
52
+ path('foo') { get { halt "path is /blog/foo" } }
53
+ }
54
+ }
55
+
56
+ If the part supplied doesn't start with a `/`, one will be added. If there is a trailing slash, and consuming it would
57
+ cause `PATH_INFO` to be empty, it will be consumed as well. In the above example, `/test/` would also match.
58
+
59
+ ### `#exact_path`
60
+
61
+ This is identical to `#path`, except trailing slashes will not be matched. For example:
62
+
63
+ :::ruby
64
+ Renee {
65
+ exact_path('test') {
66
+ halt 'i got /test!' # your path must be /test to get here.
67
+ }
68
+ }
69
+
70
+ ### `#whole_path`
71
+
72
+ This is identical to `#path`, except it will not execute the block unless it consumes the entire path.
73
+ Trailing slashes will be ignored.
74
+
75
+ :::ruby
76
+ Renee {
77
+ whole_path('test') {
78
+ halt 'i got /test!' # your path must be exactly /test to get here.
79
+ }
80
+ }
81
+
82
+ ### `#part`
83
+
84
+ This is similar to `#path`, except it's used for parts of the path instead of a whole part delimited by `/`'s. For example:
85
+
86
+ :::ruby
87
+ Renee {
88
+ part('one') {
89
+ part('two') {
90
+ part('three') {
91
+ halt "onetwothree" # this will only match /onetwothree
92
+ }
93
+ }
94
+ }
95
+ }
96
+
97
+ ### `#extension`
98
+
99
+ You can also use `extension` as a way to define formats:
100
+
101
+ :::ruby
102
+ path '/test' do
103
+ extension 'html' do
104
+ halt 'html'
105
+ end
106
+ extension 'json' do
107
+ halt 'json'
108
+ end
109
+ end
110
+
111
+ This will have `test.html` respond with 'html' and `test.json` respond with 'json'.
112
+
113
+ ### `#var` (also `#variable`)
114
+
115
+ This will match a part of path (delimited by `/`'s) and yield that value back to the block passed to it. Example:
116
+
117
+ :::ruby
118
+ Renee {
119
+ var { |id|
120
+ # this will match /one and return "the id is `one'"
121
+ halt "the id is `#{id}'"
122
+ }
123
+ }
124
+
125
+ You can access the variables (passed into the request) using the local variables yielded to the block. Variables are a powerful
126
+ way to express expected parameters for a given set of requests. You can specify variables that match a regex:
127
+
128
+ :::ruby
129
+ path('blog') {
130
+ var(/\d+/) { |id| get { halt "path is /blog/#{id}" } }
131
+ }
132
+
133
+ and even explicitly cast your variable types:
134
+
135
+ :::ruby
136
+ path('blog') {
137
+ var :integer do |id|
138
+ get { halt "path is /blog/#{id} and id is an integer" }
139
+ end
140
+ end
141
+
142
+ ### `#part_var` (also `#partial_variable`)
143
+
144
+ This will match a part of path and yield that value back to the block passed to it.
145
+ It will consume partial parts of the path like `#part`.
146
+
147
+ ### `#remainder`
148
+
149
+ This will consume the remaining part of the path and yield that value to the block passed to it. Example:
150
+
151
+ :::ruby
152
+ Renee {
153
+ remainder {|p|
154
+ # this will match anything and yield the result.
155
+ halt "I got #{p} back."
156
+ }
157
+ }
158
+
159
+ Notice this allows you to handle the cases within a particular route scope and manage them based on the "rest" of the uri yielded in the `remainder` block. You
160
+ can handle different remainders in all the different path blocks.
161
+
162
+ ### `#complete`
163
+
164
+ This will only match if the `PATH_INFO` has been entirely consumed. If the PATH_INFO was only `/`, it
165
+ will be consumed by this method. Example:
166
+
167
+ :::ruby
168
+ Renee {
169
+ complete {
170
+ halt "consumption is complete" # this will only match '/' and ''
171
+ }
172
+ }
173
+
174
+ ## Request method-based
175
+
176
+ Request methods can be defined easily:
177
+
178
+ :::ruby
179
+ run Renee {
180
+ get { halt "a get!" }
181
+ post { halt "a post!" }
182
+ put { halt "a put!" }
183
+ delete { halt "a delete!" }
184
+ }
185
+
186
+ ### `#get`
187
+
188
+ This will match if the path is complete and the request method is `GET`. Optionally,
189
+ you can pass it a path, which will match using `complete_path` and then perform the request method matching.
190
+
191
+ ### `#put`
192
+
193
+ This is the same as `#get`, except for the request method `PUT`.
194
+
195
+ ### `#post`
196
+
197
+ This is the same as `#get`, except for the request method `POST`.
198
+
199
+ ### `#delete`
200
+
201
+ This is the same as `#get`, except for the request method `DELETE`.
202
+
203
+ ## Query-based
204
+
205
+ ### `#query`
206
+
207
+ Query allows you either match a hash of key-value pairs from the query path.
208
+ Or, it will match a list of keys. If one of the keys is not present, this this will not yield
209
+ the values corresponding to the keys supplied.
210
+
211
+ Example:
212
+
213
+ :::ruby
214
+ Renee {
215
+ query(:key => 'value') {
216
+ halt "The query string contained key=value"
217
+ }
218
+
219
+ query :key, :secret { |key_value, secret_value|
220
+ halt "Key is #{key_value}, secret_value is
221
+ #{secret_value} (and these will never be nil)"
222
+ }
223
+ }
224
+
225
+ ### `#query_string`
226
+
227
+ This will match an exact query string. It's equivalent to `match === env['QUERY_STRING']`
228
+ where match is the value passed in.
229
+
230
+ :::ruby
231
+ path 'foo' do
232
+ query_string 'bar' do
233
+ get { halt 'BAR!' }
234
+ end
235
+
236
+ query_string 'baz' do
237
+ get { halt 'BAZ!' }
238
+ end
239
+ end
240
+
241
+ This will respond to `/foo?bar` with "BAR!" and `/foo?baz` with "BAZ!".
242
+ You can also specify query_string in a variety of other ways:
243
+
244
+ :::ruby
245
+ # Check key and value of query param
246
+ query_string 'foo=bar' do
247
+ post { halt [200,{},'foo'] }
248
+ end
249
+
250
+ # Declare query params as a hash
251
+ query :foo => "bar" do
252
+ halt 200
253
+ end
254
+
255
+ # Switch based on a query parameter
256
+ query :foo do |var|
257
+ case var
258
+ when 'bar' then halt 200
259
+ when 'bar2' then halt 500
260
+ end
261
+ end