renee 0.3.11 → 0.4.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
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