merb 0.4.0 → 0.4.1

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 (143) hide show
  1. data/README +23 -160
  2. data/Rakefile +15 -14
  3. data/app_generators/merb/merb_generator.rb +4 -3
  4. data/app_generators/merb/templates/Rakefile +1 -6
  5. data/app_generators/merb/templates/app/mailers/views/layout/{application.erb → application.html.erb} +0 -0
  6. data/app_generators/merb/templates/app/mailers/views/layout/application.text.erb +1 -0
  7. data/app_generators/merb/templates/app/parts/views/layout/application.html.erb +1 -0
  8. data/app_generators/merb/templates/app/views/layout/application.html.erb +2 -2
  9. data/app_generators/merb/templates/config/dependencies.rb +1 -1
  10. data/app_generators/merb/templates/config/router.rb +4 -1
  11. data/app_generators/merb/templates/spec/spec_helper.rb +2 -3
  12. data/lib/autotest/merb_rspec.rb +1 -0
  13. data/lib/merb/abstract_controller.rb +31 -2
  14. data/lib/merb/controller.rb +5 -5
  15. data/lib/merb/core_ext/get_args.rb +5 -1
  16. data/lib/merb/exceptions.rb +17 -0
  17. data/lib/merb/generators/merb_app/merb_app.rb +4 -1
  18. data/lib/merb/generators/merb_plugin.rb +4 -1
  19. data/lib/merb/logger.rb +5 -1
  20. data/lib/merb/mail_controller.rb +1 -1
  21. data/lib/merb/mailer.rb +2 -2
  22. data/lib/merb/mixins/controller.rb +5 -1
  23. data/lib/merb/mixins/render.rb +57 -27
  24. data/lib/merb/part_controller.rb +1 -1
  25. data/lib/merb/request.rb +2 -2
  26. data/lib/merb/server.rb +33 -5
  27. data/lib/merb/template/erubis.rb +1 -1
  28. data/lib/merb.rb +15 -5
  29. data/merb_generators/resource/resource_generator.rb +9 -2
  30. data/spec/fixtures/config/merb.yml +18 -0
  31. data/spec/fixtures/controllers/dispatch_spec_controllers.rb +227 -0
  32. data/spec/fixtures/controllers/render_spec_controllers.rb +115 -0
  33. data/spec/fixtures/foo.rb +3 -0
  34. data/spec/fixtures/mailers/views/layout/application.html.erb +3 -0
  35. data/spec/fixtures/mailers/views/layout/application.text.erb +3 -0
  36. data/spec/fixtures/mailers/views/test_mail_controller/eighth.html.erb +1 -0
  37. data/spec/fixtures/mailers/views/test_mail_controller/eighth.text.erb +1 -0
  38. data/spec/fixtures/mailers/views/test_mail_controller/first.html.erb +1 -0
  39. data/spec/fixtures/mailers/views/test_mail_controller/first.text.erb +1 -0
  40. data/spec/fixtures/mailers/views/test_mail_controller/ninth.html.erb +1 -0
  41. data/spec/fixtures/mailers/views/test_mail_controller/ninth.text.erb +1 -0
  42. data/spec/fixtures/mailers/views/test_mail_controller/second.text.erb +1 -0
  43. data/spec/fixtures/mailers/views/test_mail_controller/third.html.erb +1 -0
  44. data/spec/fixtures/models/router_spec_models.rb +20 -0
  45. data/spec/fixtures/parts/views/layout/todo_part.html.erb +3 -0
  46. data/spec/fixtures/parts/views/layout/todo_part.xml.erb +3 -0
  47. data/spec/fixtures/parts/views/todo_part/formatted_output.html.erb +1 -0
  48. data/spec/fixtures/parts/views/todo_part/formatted_output.js.erb +1 -0
  49. data/spec/fixtures/parts/views/todo_part/formatted_output.xml.erb +1 -0
  50. data/spec/fixtures/parts/views/todo_part/list.html.erb +3 -0
  51. data/spec/fixtures/sample.txt +1 -0
  52. data/spec/fixtures/views/erubis.html.erb +1 -0
  53. data/spec/fixtures/views/examples/_erubis.html.erb +1 -0
  54. data/spec/fixtures/views/examples/_haml.html.haml +1 -0
  55. data/spec/fixtures/views/examples/_markaby.html.mab +1 -0
  56. data/spec/fixtures/views/examples/_throw_content.html.erb +6 -0
  57. data/spec/fixtures/views/examples/hello.xml.builder +1 -0
  58. data/spec/fixtures/views/examples/js.js.erb +1 -0
  59. data/spec/fixtures/views/examples/template_catch_content.html.erb +15 -0
  60. data/spec/fixtures/views/examples/template_catch_content_from_partial.html.erb +6 -0
  61. data/spec/fixtures/views/examples/template_throw_content.html.erb +10 -0
  62. data/spec/fixtures/views/exceptions/admin_access_required.html.erb +1 -0
  63. data/spec/fixtures/views/extension_template_controller/_nested_js.js.erb +1 -0
  64. data/spec/fixtures/views/extension_template_controller/_nested_xml.xml.erb +1 -0
  65. data/spec/fixtures/views/extension_template_controller/_render_partial_multiple_times.html.erb +1 -0
  66. data/spec/fixtures/views/extension_template_controller/erubis_templates.html.erb +1 -0
  67. data/spec/fixtures/views/extension_template_controller/erubis_templates.js.erb +1 -0
  68. data/spec/fixtures/views/extension_template_controller/erubis_templates.rhtml +1 -0
  69. data/spec/fixtures/views/extension_template_controller/erubis_templates.xml.erb +1 -0
  70. data/spec/fixtures/views/extension_template_controller/haml_index.html.haml +0 -0
  71. data/spec/fixtures/views/extension_template_controller/haml_templates.html.haml +1 -0
  72. data/spec/fixtures/views/extension_template_controller/haml_templates.js.haml +1 -0
  73. data/spec/fixtures/views/extension_template_controller/haml_templates.xml.haml +1 -0
  74. data/spec/fixtures/views/extension_template_controller/index.html.erb +0 -0
  75. data/spec/fixtures/views/extension_template_controller/markaby_index.html.mab +0 -0
  76. data/spec/fixtures/views/extension_template_controller/markaby_templates.html.mab +1 -0
  77. data/spec/fixtures/views/extension_template_controller/markaby_templates.js.mab +1 -0
  78. data/spec/fixtures/views/extension_template_controller/markaby_templates.xml.mab +1 -0
  79. data/spec/fixtures/views/extension_template_controller/render_multiple_partials.html.erb +4 -0
  80. data/spec/fixtures/views/extension_template_controller/render_nested_js.js.erb +1 -0
  81. data/spec/fixtures/views/extension_template_controller/render_nested_xml.xml.erb +1 -0
  82. data/spec/fixtures/views/haml.html.haml +1 -0
  83. data/spec/fixtures/views/haml.xml.haml +2 -0
  84. data/spec/fixtures/views/layout/application.html.erb +1 -0
  85. data/spec/fixtures/views/layout/application.xml.erb +1 -0
  86. data/spec/fixtures/views/layout/nested/example.html.erb +1 -0
  87. data/spec/fixtures/views/markaby.html.mab +1 -0
  88. data/spec/fixtures/views/nested/example/test.html.erb +1 -0
  89. data/spec/fixtures/views/partials/_erubis.html.erb +1 -0
  90. data/spec/fixtures/views/partials/_erubis_collection.html.erb +1 -0
  91. data/spec/fixtures/views/partials/_erubis_collection_with_locals.html.erb +1 -0
  92. data/spec/fixtures/views/partials/_erubis_new.html.erb +1 -0
  93. data/spec/fixtures/views/partials/_haml.html.haml +1 -0
  94. data/spec/fixtures/views/partials/_haml_collection.html.haml +1 -0
  95. data/spec/fixtures/views/partials/_haml_collection_with_locals.html.haml +1 -0
  96. data/spec/fixtures/views/partials/_haml_new.html.haml +1 -0
  97. data/spec/fixtures/views/partials/_markaby.html.mab +1 -0
  98. data/spec/fixtures/views/partials/_markaby_collection.html.mab +1 -0
  99. data/spec/fixtures/views/partials/_markaby_collection_with_locals.html.mab +1 -0
  100. data/spec/fixtures/views/partials/_markaby_new.html.mab +1 -0
  101. data/spec/fixtures/views/render_object_controller/render_object_with_template.html.erb +1 -0
  102. data/spec/fixtures/views/render_object_controller/render_object_with_template.js.erb +1 -0
  103. data/spec/fixtures/views/render_object_controller/render_object_with_template.xml.erb +1 -0
  104. data/spec/fixtures/views/template_views/interface__buffer_erubis.html.erb +4 -0
  105. data/spec/fixtures/views/template_views/interface__buffer_haml.html.haml +7 -0
  106. data/spec/fixtures/views/template_views/interface__buffer_markaby.html.mab +7 -0
  107. data/spec/fixtures/views/template_views/interface_capture_erubis.html.erb +15 -0
  108. data/spec/fixtures/views/template_views/interface_capture_haml.html.haml +15 -0
  109. data/spec/fixtures/views/template_views/interface_capture_markaby.html.mab +4 -0
  110. data/spec/fixtures/views/template_views/interface_concat_erubis.html.erb +12 -0
  111. data/spec/fixtures/views/template_views/interface_concat_haml.html.haml +11 -0
  112. data/spec/fixtures/views/template_views/interface_concat_markaby.html.mab +14 -0
  113. data/spec/fixtures/views/test.dir/the_template.html.erb +1 -0
  114. data/spec/merb/abstract_controller_spec.rb +37 -0
  115. data/spec/merb/caching_spec.rb +102 -0
  116. data/spec/merb/config_spec.rb +29 -0
  117. data/spec/merb/controller_filters_spec.rb +188 -0
  118. data/spec/merb/controller_spec.rb +144 -0
  119. data/spec/merb/cookie_store_spec.rb +85 -0
  120. data/spec/merb/core_ext_spec.rb +430 -0
  121. data/spec/merb/dispatch_spec.rb +514 -0
  122. data/spec/merb/fake_request_spec.rb +72 -0
  123. data/spec/merb/form_control_mixin_spec.rb +431 -0
  124. data/spec/merb/generator_spec.rb +121 -0
  125. data/spec/merb/handler_spec.rb +169 -0
  126. data/spec/merb/mail_controller_spec.rb +144 -0
  127. data/spec/merb/mailer_spec.rb +87 -0
  128. data/spec/merb/multipart_spec.rb +49 -0
  129. data/spec/merb/part_controller_spec.rb +92 -0
  130. data/spec/merb/plugins_spec.rb +80 -0
  131. data/spec/merb/render_spec.rb +378 -0
  132. data/spec/merb/request_spec.rb +243 -0
  133. data/spec/merb/responder_spec.rb +561 -0
  134. data/spec/merb/router_spec.rb +726 -0
  135. data/spec/merb/template_spec.rb +41 -0
  136. data/spec/merb/upload_handler_spec.rb +101 -0
  137. data/spec/merb/view_context_spec.rb +148 -0
  138. data/spec/spec_generator_helper.rb +19 -0
  139. data/spec/spec_helper.rb +88 -0
  140. metadata +203 -65
  141. data/lib/merb/caching/store/memcache.rb +0 -20
  142. data/script/destroy +0 -14
  143. data/script/generate +0 -14
data/README CHANGED
@@ -1,7 +1,7 @@
1
1
  = Merb
2
- <em>Lightweight MVC Ruby app server. For high performance dynamic pages.</em>
3
2
 
4
- ==== Dependencies
3
+ ==== FrameWork Development Dependencies
4
+
5
5
  Install these gems first:
6
6
 
7
7
  * mongrel
@@ -16,52 +16,45 @@ Install these gems first:
16
16
  * haml
17
17
  * markaby
18
18
  * mailfactory
19
- * activerecord (if you want to store sessions in a database)
19
+ * Ruby2Ruby
20
20
 
21
21
  Then you can build the merb gem from svn trunk like so:
22
22
 
23
- $ sudo gem install mongrel json json_pure erubis mime-types rspec hpricot mocha rubigen haml markaby mailfactory -y
23
+ $ sudo gem install mongrel json json_pure erubis mime-types rspec hpricot mocha rubigen haml markaby mailfactory Ruby2Ruby -y
24
24
  $ svn co http://svn.devjavu.com/merb/trunk merb
25
25
  $ cd merb
26
26
  $ rake install
27
27
 
28
28
  To generate a new merb app after the gem is installed:
29
29
 
30
- $ merb -g myapp
31
-
32
- To run your application, simply type +merb+ in the project directory.
30
+ $ merb myapp
33
31
 
34
- == Features
32
+ === The +merb+ server
35
33
 
36
- === Mongrel handler
37
- Merb has a Mongrel handler built in that parses incoming requests
38
- including multipart uploads and post as well as <tt>?query=strings</tt>. Puts the
39
- params into params and the cookies into cookies when it instantiates your
40
- controller class.
34
+ right now you add your routes in
35
+ the appdir/config/router.rb file. So by default it runs on port 4000
41
36
 
42
- === RouteMatcher and route compiler
37
+ $ cd /path/to/your/merb/app
38
+ $ merb
43
39
 
44
- Reads your route definition and compiles
45
- a method on the fly that will match the request path against each route and do the right thing.
40
+ Or to start merb on a different port:
46
41
 
47
- === _NEW_ RESTful Routes
42
+ $ merb -p 3500
48
43
 
49
- Note the <tt>r.resource :posts</tt> macro. That makes it possible to use a RESTful CRUD style controller for the posts resource
44
+ To start a cluster of merb servers you specify the first port and then how many
45
+ servers you want spawned. SO this command will start a merb instance on ports
46
+ 3000, 3001, 3002
50
47
 
51
- Merb::Router.prepare do |r|
52
- r.resources :posts
53
- r.default_routes
54
- r.add '/', :controller => 'files', :action => 'index'
55
- end
48
+ $ merb -p 3000 -c 3
56
49
 
57
- The <tt>r.default_routes</tt> routes adds the standard routes:
50
+ To start a Merb IRB console where all your models and other classes are pre loaded
51
+ use the -i flag
58
52
 
59
- /controller/action/id.xml
60
- /controller/action/id
61
- /controller/action.xml
62
- /controller/action
63
- /controller.xml # index action
64
- /controller # index action
53
+ $ merb -i
54
+
55
+ To see all the available command line flags use:
56
+
57
+ $ merb -h
65
58
 
66
59
  === Controllers
67
60
 
@@ -97,104 +90,6 @@ release the mutex. It’s basically like handing over the proc to mongrel and
97
90
  mongrel handles calling it in a thread safe manner.
98
91
 
99
92
 
100
- class Test < Merb::Controller
101
- def hello
102
- # params, headers and cookies are available here.
103
- @name = params[:name]
104
- render
105
- end
106
- end
107
-
108
- You can also render partials like so:
109
-
110
- <%= partial(:comments) %>
111
-
112
- This assumes a <tt>_comments.rhtml</tt> file in the same view dir as the current
113
- controller/view.
114
-
115
- Partials compile the template ands returns a string. So you can also call
116
- them and assign them to a var if you want:
117
-
118
- def someaction
119
- @one = partial(:one)
120
- @two = partial(:two)
121
- end
122
-
123
- Partials can also render views from other controllers by specifying the path:
124
-
125
- partial('/shared/foo')
126
-
127
- Merb also allows for returning JavaScript instead of html for ajax actions
128
- You have to use the render_js instead of normal render:
129
-
130
- def ajax_action
131
- @posts = Post.find :all
132
- render_js
133
- end
134
-
135
- # ajax_action.jerb
136
- $('comments').update('<%=js partial(:posts) %>');
137
-
138
- # _posts.herb
139
- <ul>
140
- <% @posts.each do |p| %>
141
- <li>
142
- <%= p.title %><br />
143
- <%= p.body %>
144
- </li>
145
- <% end %>
146
- </ul>
147
-
148
- The .jerb template is used for this purpose.
149
-
150
- ==== RESTful Controllers
151
-
152
- RESTful controllers use a different dispatch system based on the request method verbs. Merb
153
- supports multi return values based on the accept header via +respond_to+.
154
-
155
- class Posts < Merb::Controller
156
- # GET /posts
157
- # GET /posts.xml
158
- def index
159
- @posts = Post.find :all
160
- respond_to {|format|
161
- format.html { render }
162
- format.js { render :js => :index }
163
- format.xml { render :xml => @posts.to_xml }
164
- }
165
- end
166
-
167
- # GET /posts/1
168
- # GET /posts/1.xml
169
- def show
170
- end
171
-
172
- # GET /posts/new
173
- def new
174
- end
175
-
176
- # GET /posts/1;edit
177
- def edit
178
- end
179
-
180
- # POST /posts
181
- # POST /posts.xml
182
- def create
183
- end
184
-
185
- # PUT /posts/1
186
- # PUT /posts/1.xml
187
- def update
188
- end
189
-
190
- # DELETE /posts/1
191
- # DELETE /posts/1.xml
192
- def destroy
193
- end
194
- end
195
-
196
- Learn more about this in the controller documentation.
197
-
198
93
  ==== Before and after filters
199
94
 
200
95
  Use the before method in your controllers. before accepts either a symbol, string or a Proc/lambda object. If you give it a symbol it will call a method with the same name as the symbol. If you give it a proc that takes one argument it will call the proc with the current controller as that argument. You can use :only and :exclude as options to your filters to exclude or include actionsfrom certain filters. :only and :exclude take :symbols or [:sym, :sam] array of symbols.
@@ -246,51 +141,19 @@ After filters accept a symbol, string or Proc and call that proc with the contro
246
141
 
247
142
  after Proc.new {|c| Tidy.new(c.body) }, :only => :index
248
143
 
249
- === Sessions
250
-
251
- Sessions are available when you start merb with the sql_session set to true or the
252
- memory_session set to true. See generated app for migration too add session table.
253
-
254
144
  === Helpers
255
145
 
256
146
  app/helpers/global_helper.rb will be available to all of your views.
257
147
  Helpers named after your controller plus _helper.rb will be included in the views
258
148
  for that controller only.
259
149
 
260
- === The +merb+ server
261
-
262
- right now you add your routes in
263
- the appdir/config/router.rb file. So by default it runs on port 4000
264
-
265
- $ cd /path/to/your/merb/app
266
- $ merb
267
-
268
- Or to start merb on a different port:
269
-
270
- $ merb -p 3500
271
-
272
- To start a cluster of merb servers you specify the first port and then how many
273
- servers you want spawned. SO this command will start a merb instance on ports
274
- 3000, 3001, 3002
275
-
276
- $ merb -p 3000 -c 3
277
-
278
- To start a Merb IRB console where all your models and other classes are pre loaded
279
- use the -i flag
280
-
281
- $merb -i
282
-
283
150
  === File uploads
284
- This is one of the things that Merb was written for. Rails doesn't allow
285
- multiple concurrent file uploads at once without blocking an entire rails backend for each file upload. Merb allows multiple file uploads at once.
286
151
  When a file is uploaded with Merb, it gets put in a Tempfile. So
287
152
  you just want to copy it to the right place on the filesystem.
288
153
 
289
154
  def upload
290
155
  puts params[:file].inspect
291
-
292
156
  FileUtils.mv params[:file][:tempfile].path, MERB_ROOT+"/uploads/#{params[:file][:filename]}"
293
-
294
157
  render
295
158
  end
296
159
 
data/Rakefile CHANGED
@@ -14,7 +14,7 @@ require __DIR__+'/tools/annotation_extract'
14
14
  include FileUtils
15
15
 
16
16
  NAME = "merb"
17
- VERS = "0.4.0"
17
+ VERS = "0.4.1"
18
18
  CLEAN.include ['**/.*.sw?', '*.gem', '.config']
19
19
 
20
20
  setup_clean [ "pkg", "lib/*.bundle", "*.gem", "doc/rdoc", ".config", 'coverage', "cache"]
@@ -28,17 +28,16 @@ task :doc => [:rdoc]
28
28
 
29
29
 
30
30
  Rake::RDocTask.new do |rdoc|
31
- files =['README', 'LICENSE', 'TODO', 'lib/**/*.rb']
32
- rdoc.rdoc_files.add(files)
33
- rdoc.main = "README" # page to start on
34
- rdoc.title = "Merb Docs"
35
- rdoc.template = __DIR__+"/tools/allison/allison.rb"
36
- rdoc.rdoc_dir = 'doc/rdoc' # rdoc output folder
37
- rdoc.options << '--line-numbers' << '--inline-source'
31
+ files = ['README', 'LICENSE', 'CHANGELOG',
32
+ 'lib/**/*.rb']
33
+ rdoc.rdoc_files.add(files)
34
+ rdoc.main = 'README'
35
+ rdoc.title = 'Merb Docs'
36
+ rdoc.template = `allison --path`.chomp+'.rb'
37
+ rdoc.rdoc_dir = 'doc/rdoc'
38
+ rdoc.options << '--line-numbers' << '--inline-source'
38
39
  end
39
40
 
40
-
41
-
42
41
  spec = Gem::Specification.new do |s|
43
42
  s.name = NAME
44
43
  s.version = VERS
@@ -60,7 +59,7 @@ spec = Gem::Specification.new do |s|
60
59
  s.add_dependency('rubigen')
61
60
  s.required_ruby_version = '>= 1.8.4'
62
61
 
63
- s.files = %w(LICENSE README Rakefile TODO) + Dir.glob("{bin,test,lib,examples,app_generators,merb_generators,merb_default_generators,rspec_generators,test_unit_generators,script}/**/*")
62
+ s.files = %w(LICENSE README Rakefile TODO) + Dir.glob("{bin,spec,lib,examples,app_generators,merb_generators,merb_default_generators,rspec_generators,test_unit_generators,script}/**/*")
64
63
 
65
64
  s.require_path = "lib"
66
65
  s.bindir = "bin"
@@ -88,10 +87,8 @@ end
88
87
  desc "rdoc to rubyforge"
89
88
  task :doc_rforge do
90
89
  sh %{rake doc}
91
- sh %{rake doc_webgen}
92
90
  sh %{sudo chmod -R 755 doc}
93
- sh %{scp -r -p doc/site/output/* ezmobius@rubyforge.org:/var/www/gforge-projects/merb}
94
- sh %{scp -r -p doc/rdoc/* ezmobius@rubyforge.org:/var/www/gforge-projects/merb/rdoc}
91
+ sh %{/usr/bin/scp -r -p doc/rdoc/* ezmobius@rubyforge.org:/var/www/gforge-projects/merb}
95
92
  end
96
93
 
97
94
  desc 'Run all specs and then rcov'
@@ -140,6 +137,10 @@ task :stats do
140
137
  CodeStatistics.new(*STATS_DIRECTORIES).to_s
141
138
  end
142
139
 
140
+ task :release => :package do
141
+ sh %{rubyforge add_release merb merb #{VERS} pkg/#{NAME}-#{VERS}.gem}
142
+ end
143
+
143
144
  ##############################################################################
144
145
  # SVN
145
146
  ##############################################################################
@@ -26,7 +26,8 @@ class MerbGenerator < RubiGen::Base
26
26
  m.file_copy_each %w( Rakefile )
27
27
  m.file_copy_each %w( application.rb exceptions.rb ), "app/controllers"
28
28
  m.file_copy_each %w( global_helper.rb ), "app/helpers"
29
- m.file_copy_each %w( application.erb ), "app/mailers/views/layout"
29
+ m.file_copy_each %w( application.html.erb ), "app/parts/views/layout"
30
+ m.file_copy_each %w( application.html.erb application.text.erb ), "app/mailers/views/layout"
30
31
  m.file_copy_each %w( application.html.erb ), "app/views/layout"
31
32
  m.file_copy_each %w( internal_server_error.html.erb not_found.html.erb not_acceptable.html.erb ), "app/views/exceptions"
32
33
  m.file_copy_each %w( merb.jpg ), "public/images"
@@ -86,9 +87,9 @@ EOS
86
87
  app/models
87
88
  app/helpers
88
89
  app/mailers/helpers
89
- app/mailers/views
90
90
  app/mailers/views/layout
91
- app/parts
91
+ app/parts/helpers
92
+ app/parts/views/layout
92
93
  app/views/layout
93
94
  app/views/exceptions
94
95
  config/environments
@@ -7,12 +7,7 @@ require 'rubygems'
7
7
 
8
8
  MERB_ENV = ENV['MERB_ENV'] if ENV['MERB_ENV']
9
9
 
10
- if File.directory?( File.join(File.dirname(__FILE__), "framework"))
11
- $:.unshift('framework')
12
- require File.join(File.dirname(__FILE__), "framework/merb")
13
- else
14
- require 'merb'
15
- end
10
+ require File.dirname(__FILE__)+'/config/boot.rb'
16
11
  require MERB_FRAMEWORK_ROOT+'/tasks'
17
12
  MERB_ROOT = File.dirname(__FILE__)
18
13
  include FileUtils
@@ -0,0 +1 @@
1
+ <%= catch_content :layout %>
@@ -0,0 +1 @@
1
+ <%= catch_content :layout %>
@@ -1,8 +1,8 @@
1
1
  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
- <html xmlns="http://www.w3.org/1999/xhtml">
2
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-us" lang="en-us">
3
3
  <head>
4
4
  <title>Fresh Merb App</title>
5
- <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
5
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
6
6
  <link rel="stylesheet" href="/stylesheets/master.css" type="text/css" media="screen" charset="utf-8">
7
7
  </head>
8
8
  <body>
@@ -28,7 +28,7 @@ use_test :rspec
28
28
 
29
29
  # These are some examples of how you might specify dependencies.
30
30
  #
31
- # dependencies "RedCloth", "merb-form-helpers"
31
+ # dependencies "RedCloth", "merb_helpers"
32
32
  # OR
33
33
  # dependency "RedCloth", "> 3.0"
34
34
  # OR
@@ -24,7 +24,10 @@ Merb::Router.prepare do |r|
24
24
  # RESTful routes
25
25
  # r.resources :posts
26
26
 
27
- # Default route, usually you don't want to change this
27
+ # This is the default route for /:controller/:action/:id
28
+ # This is fine for most cases. If you're heavily using resource-based
29
+ # routes, you may want to comment/remove this line to prevent
30
+ # clients from calling your create or destroy actions with a GET
28
31
  r.default_routes
29
32
 
30
33
  # Change this for your home page to be available at /
@@ -1,7 +1,6 @@
1
- require File.join(File.dirname(__FILE__), "..", 'config', 'boot')
2
-
1
+ MERB_ENV="test"
3
2
  $TESTING=true
4
-
3
+ require File.join(File.dirname(__FILE__), "..", 'config', 'boot')
5
4
  require File.join(MERB_ROOT, 'config', 'merb_init')
6
5
 
7
6
  require 'merb/test/helper'
@@ -23,6 +23,7 @@
23
23
  ### SOFTWARE.
24
24
 
25
25
  require 'autotest/rspec'
26
+ require 'merb/core_ext/inflector'
26
27
 
27
28
  class Autotest::MerbRspec < Autotest::Rspec
28
29
 
@@ -8,7 +8,17 @@ module Merb
8
8
  class_inheritable_accessor :action_argument_list
9
9
  self.action_argument_list = Hash.new([])
10
10
 
11
-
11
+ cattr_accessor :_abstract_subclasses
12
+ cattr_accessor :_template_path_cache
13
+ self._abstract_subclasses = []
14
+ self._template_path_cache
15
+
16
+ class << self
17
+ def inherited(klass)
18
+ _abstract_subclasses << klass.to_s unless _abstract_subclasses.include?(klass.to_s)
19
+ super
20
+ end
21
+ end
12
22
 
13
23
  # Holds internal execution times. Prefaced with an underscore to not
14
24
  # conflict with user-defined controller instance variables.
@@ -46,6 +56,25 @@ module Merb
46
56
  @_benchmarks[:after_filters_time] = Time.now - start if after_filters
47
57
  end
48
58
 
59
+
60
+ # Adds a path to the template path cache. This is requried for
61
+ # any view templates or layouts to be found during renering.
62
+ #
63
+ # Example
64
+ #
65
+ # Merb::AbstractController.add_path_to_template_cache('/full/path/to/template.html.erb')
66
+ def self.add_path_to_template_cache(template)
67
+ arry = template.split("/").last.split(".")
68
+ return false if template == "" || arry.size != 3
69
+ key = template.split(".")[0..-2].join(".")
70
+ self._template_path_cache[key] = template
71
+ end
72
+
73
+ # Resets the template_path_cache to an empty hash
74
+ def self.reset_template_path_cache!
75
+ self._template_path_cache = {}
76
+ end
77
+
49
78
  protected
50
79
 
51
80
  def call_action(action)
@@ -209,7 +238,7 @@ module Merb
209
238
 
210
239
 
211
240
  def content_type
212
- params[:format]
241
+ params[:format] || :html
213
242
  end
214
243
  end
215
244
 
@@ -7,22 +7,22 @@ module Merb
7
7
  # to your controller via params. It also parses the ?query=string and
8
8
  # puts that into params as well.
9
9
  class Controller < AbstractController
10
+ class_inheritable_accessor :_session_id_key, :_session_expiry
10
11
  cattr_accessor :_subclasses
11
12
  self._subclasses = []
12
13
 
13
- class_inheritable_accessor :_session_id_key, :_session_expiry
14
- self._session_id_key = :_session_id
14
+ self._session_id_key = '_session_id'
15
15
  self._session_expiry = Time.now + Merb::Const::WEEK * 2
16
16
 
17
17
  include Merb::ControllerMixin
18
18
  include Merb::ResponderMixin
19
19
  include Merb::ControllerExceptions
20
-
20
+
21
21
  class << self
22
22
  def inherited(klass)
23
- _subclasses << klass.to_s
23
+ _subclasses << klass.to_s unless _subclasses.include?(klass.to_s)
24
24
  super
25
- end
25
+ end
26
26
 
27
27
  def callable_actions
28
28
  @callable_actions ||= begin
@@ -25,7 +25,9 @@ begin
25
25
  def get_args
26
26
  arg_node = deep_array_node(:args)
27
27
  args = arg_node.arg_nodes
28
- lasgns = arg_node.deep_array_node(:block)[1..-1]
28
+ default_node = arg_node.deep_array_node(:block)
29
+ return args unless default_node
30
+ lasgns = default_node[1..-1]
29
31
  lasgns.each do |asgn|
30
32
  args.assoc(asgn[1]) << eval(RubyToRuby.new.process(asgn[2]))
31
33
  end
@@ -37,6 +39,8 @@ begin
37
39
  module GetArgs
38
40
  def get_args
39
41
  klass, meth = self.to_s.split(/ /).to_a[1][0..-2].split("#")
42
+ # Remove stupidity for #<Method: Class(Object)#foo>
43
+ klass = $` if klass =~ /\(/
40
44
  ParseTreeArray.translate(Object.const_get(klass), meth).get_args
41
45
  end
42
46
  end
@@ -92,10 +92,27 @@ module Merb
92
92
  # restricted to administrators.</p>
93
93
  #
94
94
  module ControllerExceptions
95
+
96
+ # Mapping of status code names to their numeric value.
97
+ STATUS_CODES = {}
98
+
95
99
  class Base < StandardError
96
100
  def name
97
101
  self.class.to_s.snake_case.split('::').last
98
102
  end
103
+
104
+ #
105
+ # Registers any subclasses with status codes for easy lookup by
106
+ # set_status in Merb::Controller.
107
+ #
108
+ # Inheritance ensures this method gets inherited by any subclasses, so
109
+ # it goes all the way down the chain of inheritance.
110
+ #
111
+ def self.inherited(subclass)
112
+ if subclass.const_defined?(:STATUS)
113
+ STATUS_CODES[subclass.name.snake_case.to_sym] = subclass.const_get(:STATUS)
114
+ end
115
+ end
99
116
  end
100
117
 
101
118
  class Informational < Merb::ControllerExceptions::Base; end
@@ -9,7 +9,10 @@ module Merb
9
9
  require 'rubigen'
10
10
 
11
11
  require 'rubigen/scripts/generate'
12
- RubiGen::Base.use_application_sources!
12
+ source = RubiGen::PathSource.new(:application,
13
+ File.join(File.dirname(__FILE__), "../../../../app_generators"))
14
+ RubiGen::Base.reset_sources
15
+ RubiGen::Base.append_sources source
13
16
  RubiGen::Scripts::Generate.new.run([path], :generator => 'merb', :backtrace => true)
14
17
  end
15
18
 
@@ -9,7 +9,10 @@ module Merb
9
9
  require 'rubigen'
10
10
 
11
11
  require 'rubigen/scripts/generate'
12
- RubiGen::Base.use_application_sources!
12
+ source = RubiGen::PathSource.new(:application,
13
+ File.join(File.dirname(__FILE__), "../../../app_generators"))
14
+ RubiGen::Base.reset_sources
15
+ RubiGen::Base.append_sources source
13
16
  RubiGen::Scripts::Generate.new.run([path], :generator => 'merb_plugin', :backtrace => true)
14
17
  end
15
18
 
data/lib/merb/logger.rb CHANGED
@@ -30,7 +30,11 @@ module Merb
30
30
  end
31
31
 
32
32
  def flush
33
- @log.write @buffer.slice!(0..-1).to_s unless @buffer.size == 0
33
+ if @log.respond_to?(:write_nonblock)
34
+ @log.write_nonblock @buffer.slice!(0..-1).to_s unless @buffer.size == 0
35
+ else
36
+ @log.write @buffer.slice!(0..-1).to_s unless @buffer.size == 0
37
+ end
34
38
  end
35
39
 
36
40
  def close
@@ -66,7 +66,7 @@ module Merb
66
66
 
67
67
  class MailController < AbstractController
68
68
 
69
- self._template_root = File.expand_path(self._template_root / "../app/mailers/views")
69
+ self._template_root = File.expand_path(self._template_root / "../mailers/views")
70
70
  class_inheritable_accessor :_mailer_klass
71
71
  self._mailer_klass = Merb::Mailer
72
72
 
data/lib/merb/mailer.rb CHANGED
@@ -20,7 +20,7 @@ module Merb
20
20
  # :port=>'25',
21
21
  # :user=>'user',
22
22
  # :pass=>'pass',
23
- # :auth=>:plain # :plain, :login, or :cram_md5, default :plain
23
+ # :auth=>:plain # :plain, :login, :cram_md5, the default is no auth
24
24
  # }
25
25
  #
26
26
  # or
@@ -52,7 +52,7 @@ module Merb
52
52
  # :plain, :login, or :cram_md5
53
53
  def net_smtp
54
54
  Net::SMTP.start(config[:host], config[:port].to_i, config[:domain],
55
- config[:user], config[:pass], (config[:auth].to_sym||:plain)) { |smtp|
55
+ config[:user], config[:pass], config[:auth]) { |smtp|
56
56
  smtp.send_message(@mail.to_s, @mail.from.first, @mail.to)
57
57
  }
58
58
  end
@@ -62,7 +62,7 @@ module Merb
62
62
  route_name = nil
63
63
  end
64
64
 
65
- url = if new_params.respond_to?(:keys) &&
65
+ url = if new_params.respond_to?(:keys) && route_name.nil? &&
66
66
  !(new_params.keys & [:controller, :action, :id]).empty?
67
67
  url_from_default_route(new_params)
68
68
  elsif route_name.nil? && !route.regexp?
@@ -81,6 +81,10 @@ module Merb
81
81
  end
82
82
 
83
83
  def url_from_route(symbol, new_params = {})
84
+ if new_params.respond_to?(:new_record?) && new_params.new_record?
85
+ symbol = "#{symbol}".singularize.to_sym
86
+ new_params = {}
87
+ end
84
88
  route = symbol.is_a?(Symbol) ? Merb::Router.named_routes[symbol] : symbol
85
89
  raise "URL could not be constructed. Route symbol not found: #{symbol.inspect}" unless route
86
90
  path = route.generate(new_params, params)