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
data/Rakefile CHANGED
@@ -1,13 +1,113 @@
1
1
  require 'rake/testtask'
2
- require 'yard'
3
2
 
4
- Rake::TestTask.new do |t|
5
- t.libs.push "lib"
6
- t.test_files = FileList[File.expand_path('../test/**/*_test.rb', __FILE__)]
7
- t.verbose = true
3
+ ROOT = File.expand_path(File.dirname(__FILE__))
4
+
5
+ task :default => :test
6
+
7
+ def lsh(cmd, &block)
8
+ out, code = lsh_with_code(cmd, &block)
9
+ code == 0 ? out : raise(out.empty? ? "Running `#{cmd}' failed. Run this command directly for more detailed output." : out)
10
+ end
11
+
12
+ def lsh_with_code(cmd, &block)
13
+ cmd << " 2>&1"
14
+ outbuf = ''
15
+ outbuf = `#{cmd}`
16
+ if $? == 0
17
+ block.call(outbuf) if block
18
+ end
19
+ [outbuf, $?]
20
+ end
21
+
22
+ renee_gems = %w[
23
+ renee-core
24
+ renee-render
25
+ renee-url-generation
26
+ renee-session
27
+ renee
28
+ ].freeze
29
+
30
+ desc "build #{renee_gems.join(', ')} gems"
31
+ task :build do
32
+ renee_gems.each do |g|
33
+ lsh "mkdir -p pkg && gem build #{g}.gemspec && mv *.gem pkg"
34
+ puts "#{g} built"
35
+ end
36
+ end
37
+
38
+ task :release => [:build, :yard] do
39
+ require File.join(ROOT, 'lib', 'renee', 'version')
40
+ version_tag = "v#{Renee::VERSION}"
41
+ begin
42
+ raise("#{version_tag} has already been committed") if lsh('git tag').split(/\n/).include?(version_tag)
43
+ sh "git tag #{version_tag}"
44
+ puts "adding tag #{version_tag}"
45
+ renee_gems.each do |g|
46
+ sh "gem push pkg/#{g}-#{Renee::VERSION}.gem"
47
+ puts "#{g} pushed"
48
+ end
49
+ sh "git push"
50
+ sh "git push --tags"
51
+ rescue
52
+ puts "something went wrong"
53
+ sh "git tag -d #{version_tag}"
54
+ raise
55
+ end
56
+ end
57
+
58
+ task :install => :build do
59
+ require File.join(ROOT, 'lib', 'renee', 'version')
60
+ renee_gems.each do |g|
61
+ lsh "gem install pkg/#{g}-#{Renee::VERSION}.gem"
62
+ puts "#{g} installed"
63
+ end
64
+ end
65
+
66
+ task :bundle do
67
+ renee_gems.each do |g|
68
+ sh "env BUNDLE_GEMFILE=Gemfile-#{g} bundle"
69
+ end
70
+ end
71
+
72
+ renee_gems_tasks = Hash[renee_gems.map{|rg| [rg, :"test_#{rg.gsub('-', '_')}"]}].freeze
73
+
74
+ desc "Run tests for all renee stack gems"
75
+ task :test do
76
+ renee_gems_tasks.values.each do |task|
77
+ Rake::Task[task].invoke
78
+ end
8
79
  end
9
80
 
10
- desc "Generate documentation for the Padrino framework"
11
- task :doc do
12
- YARD::CLI::Yardoc.new.run
13
- end
81
+ renee_gems_tasks.each do |g, tn|
82
+ desc "Run tests for #{g} (shell out)"
83
+ task tn do
84
+ sh "env BUNDLE_GEMFILE=Gemfile-#{g} bundle exec rake test-#{g}"
85
+ end
86
+
87
+ Rake::TestTask.new("test-#{g}") do |t|
88
+ t.libs.push "lib"
89
+ t.test_files = FileList[File.expand_path("../test/#{g}/**/*_test.rb", __FILE__)]
90
+ t.verbose = true
91
+ end
92
+ end
93
+
94
+ desc "Generate YARD documentation"
95
+ task :'yard' do
96
+ require 'yard'
97
+ Dir['*.gemspec'].to_a.each do |gemspec|
98
+ spec = Gem::Specification.load(gemspec)
99
+ puts "spec #{spec.inspect}"
100
+ task_name = :"yard:#{spec.name}"
101
+ rb_files = spec.files.select{|f| f[/^lib/]}
102
+ readme = spec.name == 'renee' ? "README.md" : "README-#{spec.name}.md"
103
+ pid = fork do # yard has some shared state somewhere. poor poor yard.
104
+ YARD::Rake::YardocTask.new(task_name) do |t|
105
+ t.options = ['-o', File.expand_path("../site/public/docs/#{spec.name}", __FILE__), '--readme', readme, '--no-private', '--markup', 'markdown']
106
+ t.files = rb_files
107
+ end
108
+ Rake::Task[task_name].execute
109
+ end
110
+ _, status = Process.waitpid2(pid)
111
+ raise unless status.success?
112
+ end
113
+ end
data/TODO.txt ADDED
@@ -0,0 +1,45 @@
1
+ [ ] accept handling
2
+ [ ] content-type / mime-type handling, registration
3
+ [ ] serving static files from a public folder?
4
+ [ ] exception handling in requests? handling not founds gracefully in dev?
5
+ [ ] integration with models
6
+ [ ] how do helpers work? how do extensions work?
7
+ [ ] caching helpers
8
+ [ ] auth helpers
9
+ [ ] support for better stacktraces (i.e showexceptions)
10
+ [ ] default registered middlewares? (method::override or rack::head or sessions)
11
+ [ ] configurable forced encodings to default things to utf-8?
12
+ [ ] request logger (sql, rendering, etc)
13
+ [ ] context passing between multiple renee's, clearly, env is a big part of this.
14
+ [ ] the marketing site for this whole thing
15
+ [ ] more examples
16
+ [ ] through documentation
17
+ [ ] sinatra-like streaming API?
18
+
19
+ Helpers and functionality in sinatra, worth discussing if we should include similar:
20
+
21
+ * Helper for accessing the session?
22
+ - session
23
+ * What does rack::session give you? is it any good?
24
+
25
+ * Helper for setting content type
26
+ - content_type :json
27
+ * this is equiv to headers(:content_type => ... ), see above
28
+ ** kind of except this is mime-type intelligent
29
+
30
+ * Send a file as a response
31
+ send_file "some/file.txt"
32
+ yes!
33
+
34
+ * Support for cache_control, expires, last_modified, etag
35
+ cache_control :public, :must_revalidate, :max_age => 60
36
+ expires 500, :public, :must_revalidate
37
+ etag(value, options = {})
38
+ last_modified(time)
39
+ see above!
40
+
41
+
42
+ * mime-type provides?
43
+ yes!
44
+ * user_agent filtering helpers?
45
+ yes !
data/config.ru ADDED
@@ -0,0 +1,26 @@
1
+ require 'renee'
2
+ require 'haml'
3
+ require 'rdiscount'
4
+ require 'rack/codehighlighter'
5
+ require 'rack/google-analytics'
6
+ require 'coderay'
7
+
8
+ views = Dir[File.expand_path('../site/views/*.md', __FILE__)].map { |f| f[/\/([^\/]+)\.md/, 1] }
9
+
10
+ run Renee {
11
+ path('concept') { redirect! '/' }
12
+ views.each { |view|
13
+ path = view == 'index' ? '' : view
14
+ path("/#{path}").get {
15
+ title = (view == 'index') ? '' : " &mdash; #{view.split('-').join(' ')}"
16
+ render! view, :locals => {:title_part => title }
17
+ }
18
+ }
19
+ }.setup {
20
+ use Rack::Static, :urls => ['/css', '/img', '/doc'], :root => 'site/public'
21
+ use Rack::Codehighlighter, :coderay, :element => "pre>code", :pattern => /\A:::(\w+)\s*\n/
22
+ use Rack::GoogleAnalytics, :tracker => 'UA-26317661-1'
23
+
24
+ views_path File.expand_path('../site/views', __FILE__)
25
+ default_layout 'layouts/app'
26
+ }
@@ -7,7 +7,9 @@ class Blog
7
7
  end
8
8
 
9
9
  def new_post(title, contents)
10
- @posts << Post.new(self, @post_id += 1, title, contents)
10
+ post = Post.new(self, @post_id += 1, title, contents)
11
+ @posts << post
12
+ post
11
13
  end
12
14
 
13
15
  def find_post(id)
@@ -13,28 +13,33 @@ run Renee {
13
13
  var :integer do |id|
14
14
  @post = @blog.find_post(id)
15
15
  halt 404 unless @post
16
- path('edit') { render! 'edit' }
17
-
18
- get { render! 'show' }
19
- delete { @post.delete!; halt :ok }
20
- put {
21
- @post.title = request['title'] if request['title']
16
+ path('edit').get.render! 'edit' # show editor
17
+ get.render! 'show' # show post
18
+ delete do
19
+ @post.delete!
20
+ redirect! "/"
21
+ end
22
+ put do
23
+ @post.title = request['title'] if request['title']
22
24
  @post.contents = request['contents'] if request['contents']
23
- halt :ok
24
- }
25
+ redirect! "/#{@post.id}"
26
+ end
25
27
  end
26
28
 
27
- post {
28
- if request['title'] && request['contents']
29
- @blog.new_post(request['title'], request['contents'])
30
- halt :created
31
- else
32
- halt :bad_request
33
- end
34
- }
29
+ post do
30
+ halt :bad_request, "No title specified" unless request['title']
31
+ halt :bad_request, "No contents specified" unless request['contents']
32
+ post = @blog.new_post(request['title'], request['contents'])
33
+ redirect! "/#{post.id}"
34
+ end
35
35
 
36
- extension('json') { get { halt @blog.posts.map{ |p| {:contents => p.contents} }.to_json } }
37
- no_extension { get { render! 'index' } }
36
+ get do
37
+ case extension
38
+ when 'json' then halt @blog.posts.map { |p| {:contents => p.contents} }.to_json
39
+ else render! 'index'
40
+ end
41
+ end
38
42
  }.setup {
43
+ use Rack::MethodOverride
39
44
  views_path File.expand_path(File.dirname(__FILE__) + "/views")
40
- }
45
+ }
@@ -1 +1,10 @@
1
- Editing <%= @post.title %>
1
+ Editing <%= @post.title %>
2
+
3
+ <form action="/<%= @post.id%>" method="post">
4
+ <input type="hidden" name="_method" value="put" />
5
+
6
+ Title
7
+ <input name=title value="<%= @post.title %>"><br/>
8
+ <textarea name=contents><%= @post.contents %></textarea><br/>
9
+ <input type=submit>
10
+ </form>
@@ -2,4 +2,9 @@
2
2
 
3
3
  <p><%= @post.contents %></p>
4
4
 
5
+ <a href="/<%= @post.id %>/edit">Edit</a>
6
+ <form method="post" action="/<%= @post.id %>">
7
+ <input type="hidden" name="_method" value="delete" />
8
+ <input data-confirm='Are you sure?' value="Delete" type="submit" />
9
+ </form>
5
10
  <a href="/">See all posts</a>
data/lib/renee.rb CHANGED
@@ -1,5 +1,8 @@
1
- require 'renee_core'
2
- require 'renee_render'
1
+ require 'renee/version'
2
+ require 'renee/core'
3
+ require 'renee/render'
4
+ require 'renee/session'
5
+ require 'renee/url_generation'
3
6
 
4
7
  # Method for creating new Renee applications.
5
8
  # @see http://reneerb.com
@@ -8,7 +11,9 @@ require 'renee_render'
8
11
  # halt "hello renee"
9
12
  # }
10
13
  def Renee(&blk)
11
- Class.new(Renee::Application).app(&blk)
14
+ app_class = Class.new(Renee::Application)
15
+ app_class.app(&blk)
16
+ app_class
12
17
  end
13
18
 
14
19
  # Top-level Renee constant.
@@ -16,6 +21,8 @@ module Renee
16
21
  # Main class for a Renee application. This class should be subclasses if you want to define your own Renee
17
22
  # implementations.
18
23
  class Application < Core
19
- include Renee::Render
24
+ include Render
25
+ include URLGeneration
26
+ include Session
20
27
  end
21
28
  end
data/lib/renee/core.rb ADDED
@@ -0,0 +1,98 @@
1
+ require 'rack'
2
+
3
+ require 'renee/version'
4
+ require 'renee/core/matcher'
5
+ require 'renee/core/chaining'
6
+ require 'renee/core/response'
7
+ require 'renee/core/exceptions'
8
+ require 'renee/core/rack_interaction'
9
+ require 'renee/core/request_context'
10
+ require 'renee/core/transform'
11
+ require 'renee/core/routing'
12
+ require 'renee/core/responding'
13
+ require 'renee/core/env_accessors'
14
+ require 'renee/core/plugins'
15
+
16
+ # Top-level Renee constant
17
+ module Renee
18
+ # @example
19
+ # Renee.core { path('/hello') { halt :ok } }
20
+ def self.core(&blk)
21
+ cls = Class.new(Renee::Core)
22
+ cls.app(&blk) if blk
23
+ cls
24
+ end
25
+
26
+ # The top-level class for creating core application.
27
+ # For convience you can also used a method named #Renee
28
+ # for decalaring new instances.
29
+ class Core
30
+ # Current version of Renee::Core
31
+ VERSION = Renee::VERSION
32
+
33
+ # Error raised if routing fails. Use #continue_routing to continue routing.
34
+ NotMatchedError = Class.new(RuntimeError)
35
+
36
+ # Class methods that are included in new instances of {Core}
37
+ module ClassMethods
38
+ include Plugins
39
+
40
+ # The application block used to create your application.
41
+ attr_reader :application_block
42
+
43
+ # Provides a rack interface compliant call method. This method creates a new instance of your class and calls
44
+ # #call on it.
45
+ def call(env)
46
+ new.call(env)
47
+ end
48
+
49
+ # Allows you to set the #application_block on your class.
50
+ # @yield The application block
51
+ def app(&app)
52
+ @application_block = app
53
+ setup do
54
+ register_variable_type :integer, IntegerMatcher
55
+ register_variable_type :int, :integer
56
+ end
57
+ end
58
+
59
+ # Runs class methods on your application.
60
+ def setup(&blk)
61
+ instance_eval(&blk)
62
+ self
63
+ end
64
+
65
+ # The currently available variable types you've defined.
66
+ def variable_types
67
+ @variable_types ||= {}
68
+ end
69
+
70
+ # Registers a new variable type for use within {Renee::Core::Routing#variable} and others.
71
+ # @param [Symbol] name The name of the variable.
72
+ # @param [Regexp] matcher A regexp describing what part of an arbitrary string to capture.
73
+ # @return [Renee::Core::Matcher] A matcher
74
+ def register_variable_type(name, matcher)
75
+ matcher = case matcher
76
+ when Matcher then matcher
77
+ when Array then Matcher.new(matcher.map{|m| variable_types[m]})
78
+ when Symbol then variable_types[matcher]
79
+ else Matcher.new(matcher)
80
+ end
81
+ matcher.name = name
82
+ variable_types[name] = matcher
83
+ end
84
+ end
85
+
86
+ include Chaining
87
+ include RequestContext
88
+ include Routing
89
+ include Responding
90
+ include RackInteraction
91
+ include Transform
92
+ include EnvAccessors
93
+
94
+ class << self
95
+ include ClassMethods
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,66 @@
1
+ module Renee
2
+ class Core
3
+ # Module for creating chainable methods. To use this within your own modules, first `include Chaining`, then,
4
+ # mark methods you want to be available with `chain_method :method_name`.
5
+ # @example
6
+ # module MoreRoutingMethods
7
+ # include Chaining
8
+ # def other_routing_method
9
+ # # ..
10
+ # end
11
+ # chain_method :other_routing_method
12
+ #
13
+ module Chaining
14
+ # @private
15
+ class ChainingProxy
16
+ def initialize(target, m, args = nil)
17
+ @target, @calls = target, []
18
+ @calls << [m, args]
19
+ end
20
+
21
+ def method_missing(m, *args, &blk)
22
+ @calls << [m, args]
23
+ if blk.nil? && @target.class.respond_to?(:chainable?) && @target.class.chainable?(m)
24
+ self
25
+ else
26
+ inner_args = []
27
+ ret = nil
28
+ callback = proc do |*callback_args|
29
+ inner_args.concat(callback_args)
30
+ if @calls.size == 0
31
+ ret = blk.call(*inner_args) if blk
32
+ else
33
+ call = @calls.shift
34
+ ret = call.at(1) ? @target.send(call.at(0), *call.at(1), &callback) : @target.send(call.at(0), &callback)
35
+ end
36
+ end
37
+ ret = callback.call
38
+ ret
39
+ end
40
+ end
41
+ end
42
+
43
+ # @private
44
+ module ClassMethods
45
+ def chainable?(m)
46
+ method_defined?(:"#{m}_chainable")
47
+ end
48
+
49
+ def chainable(*methods)
50
+ methods.each do |m|
51
+ define_method(:"#{m}_chainable") { }
52
+ end
53
+ end
54
+
55
+ end
56
+
57
+ def create_chain_proxy(method_name, *args)
58
+ ChainingProxy.new(self, method_name, args)
59
+ end
60
+
61
+ def self.included(o)
62
+ o.extend(ClassMethods)
63
+ end
64
+ end
65
+ end
66
+ end