reactive-mvc 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. data/LICENSE +21 -0
  2. data/Manifest +34 -0
  3. data/README +30 -0
  4. data/Rakefile +5 -0
  5. data/lib/reactive-mvc.rb +26 -0
  6. data/lib/reactive-mvc/controller.rb +16 -0
  7. data/lib/reactive-mvc/controller/base.rb +405 -0
  8. data/lib/reactive-mvc/controller/filters.rb +767 -0
  9. data/lib/reactive-mvc/controller/flash.rb +161 -0
  10. data/lib/reactive-mvc/controller/helpers.rb +203 -0
  11. data/lib/reactive-mvc/controller/layout.rb +285 -0
  12. data/lib/reactive-mvc/controller/output.rb +262 -0
  13. data/lib/reactive-mvc/controller/rescue.rb +208 -0
  14. data/lib/reactive-mvc/dispatcher.rb +133 -0
  15. data/lib/reactive-mvc/view.rb +18 -0
  16. data/lib/reactive-mvc/view/base.rb +388 -0
  17. data/lib/reactive-mvc/view/helpers.rb +38 -0
  18. data/lib/reactive-mvc/view/partials.rb +207 -0
  19. data/lib/reactive-mvc/view/paths.rb +125 -0
  20. data/lib/reactive-mvc/view/renderable.rb +98 -0
  21. data/lib/reactive-mvc/view/renderable_partial.rb +49 -0
  22. data/lib/reactive-mvc/view/template.rb +110 -0
  23. data/lib/reactive-mvc/view/template_error.rb +9 -0
  24. data/lib/reactive-mvc/view/template_handler.rb +9 -0
  25. data/lib/reactive-mvc/view/template_handlers.rb +43 -0
  26. data/lib/reactive-mvc/view/template_handlers/builder.rb +15 -0
  27. data/lib/reactive-mvc/view/template_handlers/erb.rb +20 -0
  28. data/lib/reactive-mvc/view/template_handlers/ruby_code.rb +9 -0
  29. data/reactive_app_generators/mvc/USAGE +10 -0
  30. data/reactive_app_generators/mvc/mvc_generator.rb +48 -0
  31. data/reactive_app_generators/mvc/templates/application_controller.rb +2 -0
  32. data/reactive_generators/controller/USAGE +7 -0
  33. data/reactive_generators/controller/controller_generator.rb +24 -0
  34. data/reactive_generators/controller/templates/controller.rb +2 -0
  35. metadata +113 -0
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2008-2009 Pascal Hurni
2
+ Copyright (c) 2004-2007 David Heinemeier Hansson
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,34 @@
1
+ LICENSE
2
+ Manifest
3
+ README
4
+ Rakefile
5
+ lib/reactive-mvc.rb
6
+ lib/reactive-mvc/controller.rb
7
+ lib/reactive-mvc/controller/base.rb
8
+ lib/reactive-mvc/controller/filters.rb
9
+ lib/reactive-mvc/controller/flash.rb
10
+ lib/reactive-mvc/controller/helpers.rb
11
+ lib/reactive-mvc/controller/layout.rb
12
+ lib/reactive-mvc/controller/output.rb
13
+ lib/reactive-mvc/controller/rescue.rb
14
+ lib/reactive-mvc/dispatcher.rb
15
+ lib/reactive-mvc/view.rb
16
+ lib/reactive-mvc/view/base.rb
17
+ lib/reactive-mvc/view/helpers.rb
18
+ lib/reactive-mvc/view/partials.rb
19
+ lib/reactive-mvc/view/paths.rb
20
+ lib/reactive-mvc/view/renderable.rb
21
+ lib/reactive-mvc/view/renderable_partial.rb
22
+ lib/reactive-mvc/view/template.rb
23
+ lib/reactive-mvc/view/template_error.rb
24
+ lib/reactive-mvc/view/template_handler.rb
25
+ lib/reactive-mvc/view/template_handlers.rb
26
+ lib/reactive-mvc/view/template_handlers/builder.rb
27
+ lib/reactive-mvc/view/template_handlers/erb.rb
28
+ lib/reactive-mvc/view/template_handlers/ruby_code.rb
29
+ reactive_app_generators/mvc/USAGE
30
+ reactive_app_generators/mvc/mvc_generator.rb
31
+ reactive_app_generators/mvc/templates/application_controller.rb
32
+ reactive_generators/controller/USAGE
33
+ reactive_generators/controller/controller_generator.rb
34
+ reactive_generators/controller/templates/controller.rb
data/README ADDED
@@ -0,0 +1,30 @@
1
+ == reactive-mvc
2
+
3
+ Reactive plugin that dispatches requests to a local MVC machinery.
4
+
5
+ Version:: 0.2.0
6
+ Author:: Pascal Hurni
7
+ Email:: phi@ruby-reactive.org
8
+ Homepage:: http://www.ruby-reactive.org
9
+
10
+ == Description
11
+
12
+ Provides a local MVC machinery to handle requests of the reactive application.
13
+ The machinery is mapped to what is done in RubyOnRails, so you'll have rails like
14
+ controllers, rails like views and helpers.
15
+
16
+ Because Reactive is Model and View agnostic, this plugin alone will
17
+ not do the complete job.
18
+
19
+ == Configuration
20
+
21
+ <paths> :mvc:: Path to the root of the mvc files. Defaults to "app"
22
+ <paths> :model:: Path for model files. Defaults to ":mvc/models"
23
+ <paths> :views:: Array of paths for views. Defaults to ":mvc/views"
24
+ <paths> :controller:: Path for controllers. Defaults to ":mvc/controllers"
25
+ <paths> :helper:: Path for view helpers. Defaults to ":mvc/helpers"
26
+
27
+ == Requirements
28
+
29
+ * reactive-core >= 0.2.0
30
+ * activesupport >= 2.0.0
@@ -0,0 +1,5 @@
1
+ require 'rubygems'
2
+
3
+ unless Gem.source_index.find_name('reactive-dev').empty?
4
+ require 'reactive-dev/tasks/plugin'
5
+ end
@@ -0,0 +1,26 @@
1
+ Reactive::Initializer.configure :mvc do
2
+ Reactive.configuration.paths[:mvc] = Reactive.configuration.reactive_mvc.root_path || Reactive.path_for("app")
3
+ Reactive.configuration.paths[:views] = Reactive.configuration.reactive_mvc.view_paths || [Reactive.path_for(:mvc, "views")]
4
+ Reactive.configuration.paths[:model] = Reactive.configuration.reactive_mvc.model_path || Reactive.path_for(:mvc, "models")
5
+ Reactive.configuration.paths[:helper] = Reactive.configuration.reactive_mvc.helper_path || Reactive.path_for(:mvc, "helpers")
6
+ Reactive.configuration.paths[:controller] = Reactive.configuration.reactive_mvc.controller_path || Reactive.path_for(:mvc, "controllers")
7
+ Reactive.configuration.paths[:test] = Reactive.configuration.reactive_mvc.test_path || Reactive.path_for("test")
8
+ end
9
+
10
+ Reactive::Initializer.init :mvc do
11
+ require 'reactive-mvc/dispatcher'
12
+ require 'reactive-mvc/controller'
13
+ require 'reactive-mvc/view'
14
+
15
+ # TODO: Seems that this is not required? So how does ruby load application_controller.rb ???
16
+ # ActiveSupport::Dependencies.load_paths |= [:model, :helper, :controller].collect {|dir_id| Reactive.path_for dir_id}
17
+
18
+ Reactive::Mvc::Controller::Base.logger = Reactive::Mvc::View::Base.logger = Reactive.configuration.reactive_mvc.logger || Reactive.logger
19
+
20
+ Reactive::Dispatcher::Base.register(:mvc, Reactive::Mvc::Dispatcher)
21
+
22
+ ActiveSupport::Dependencies.load_paths.push Reactive.configuration.paths[:model], Reactive.configuration.paths[:helper], Reactive.configuration.paths[:controller]
23
+
24
+ # TODO: modify the behaviour of paths directly in Controller::Base
25
+ Reactive::Mvc::Controller::Base.view_paths = Reactive.configuration.paths[:views]
26
+ end
@@ -0,0 +1,16 @@
1
+ require 'reactive-mvc/controller/base'
2
+ require 'reactive-mvc/controller/rescue'
3
+ require 'reactive-mvc/controller/flash'
4
+ require 'reactive-mvc/controller/filters'
5
+ require 'reactive-mvc/controller/layout'
6
+ require 'reactive-mvc/controller/helpers'
7
+ require 'reactive-mvc/controller/output'
8
+
9
+ Reactive::Mvc::Controller::Base.class_eval do
10
+ include Reactive::Mvc::Controller::Flash
11
+ include Reactive::Mvc::Controller::Filters
12
+ include Reactive::Mvc::Controller::Layout
13
+ include Reactive::Mvc::Controller::Rescue
14
+ include Reactive::Mvc::Controller::Helpers
15
+ include Reactive::Mvc::Controller::Output
16
+ end
@@ -0,0 +1,405 @@
1
+ module Reactive::Mvc
2
+ module Controller
3
+ class Error < Reactive::Error #:nodoc:
4
+ end
5
+
6
+ class MethodNotAllowed < Error #:nodoc:
7
+ attr_reader :allowed_methods
8
+
9
+ def initialize(*allowed_methods)
10
+ super("Only #{allowed_methods.to_sentence} requests are allowed.")
11
+ @allowed_methods = allowed_methods
12
+ end
13
+
14
+ def allowed_methods_header
15
+ allowed_methods.map { |method_symbol| method_symbol.to_s.upcase } * ', '
16
+ end
17
+
18
+ def handle_response!(response)
19
+ response.headers['Allow'] ||= allowed_methods_header
20
+ end
21
+ end
22
+
23
+ class NotImplemented < MethodNotAllowed #:nodoc:
24
+ end
25
+
26
+ class UnknownController < Error #:nodoc:
27
+ end
28
+
29
+ class UnknownAction < Error #:nodoc:
30
+ end
31
+
32
+ class MissingFile < Error #:nodoc:
33
+ end
34
+
35
+ class RenderError < Error #:nodoc:
36
+ end
37
+
38
+ class DoubleRenderError < Error #:nodoc:
39
+ DEFAULT_MESSAGE = "Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like \"redirect_to(...) and return\"."
40
+
41
+ def initialize(message = nil)
42
+ super(message || DEFAULT_MESSAGE)
43
+ end
44
+ end
45
+
46
+ class Base
47
+
48
+ # Controller specific instance variables which will not be accessible inside views.
49
+ cattr_reader :protected_instance_variables
50
+ @@protected_instance_variables = %w(@assigns @performed_redirect @performed_render @parent_controller
51
+ @action_name @before_filter_chain_aborted @_params @_flash @_response)
52
+
53
+ # The logger is used for generating information on the action run-time (including benchmarking) if available.
54
+ # Can be set to nil for no logging. Compatible with both Ruby's own Logger and Log4r loggers.
55
+ cattr_accessor :logger
56
+
57
+ # Returns the name of the action this controller is processing.
58
+ attr_reader :action_name
59
+
60
+ # Holds the request object that will be used by the dispatcher.
61
+ attr_internal :request
62
+
63
+ # Holds the response object that will be used by the dispatcher.
64
+ attr_internal :response
65
+
66
+ # Holds a hash of all the parameters passed to the action. Accessed like <tt>params["post_id"]</tt>
67
+ # to get the post_id. No type casts are made, so all values are of the initial type of the request.
68
+ attr_internal :params
69
+
70
+ @@template_classes = {}
71
+
72
+ class << self
73
+
74
+ def process(request, response) #, method = :perform_action, *arguments)
75
+ new.process(request, response) #, method, *arguments)
76
+ end
77
+
78
+ def register_template_class(format, klass)
79
+ @@template_classes[format.to_sym] = klass
80
+ end
81
+
82
+ # Converts the class name from something like "OneModule::TwoModule::NeatController" to "NeatController".
83
+ def controller_class_name
84
+ @controller_class_name ||= name.demodulize
85
+ end
86
+
87
+ # Converts the class name from something like "OneModule::TwoModule::NeatController" to "neat".
88
+ def controller_name
89
+ @controller_name ||= controller_class_name.sub(/Controller$/, '').underscore
90
+ end
91
+
92
+ # Converts the class name from something like "OneModule::TwoModule::NeatController" to "one_module/two_module/neat".
93
+ def controller_path
94
+ @controller_path ||= name.gsub(/Controller$/, '').underscore
95
+ end
96
+
97
+ # Return an array containing the names of public methods that have been marked hidden from the action processor.
98
+ # By default, all methods defined in ActionController::Base and included modules are hidden.
99
+ # More methods can be hidden using <tt>hide_actions</tt>.
100
+ def hidden_actions
101
+ read_inheritable_attribute(:hidden_actions) || write_inheritable_attribute(:hidden_actions, [])
102
+ end
103
+
104
+ # Hide each of the given methods from being callable as actions.
105
+ def hide_action(*names)
106
+ write_inheritable_attribute(:hidden_actions, hidden_actions | names.map(&:to_s))
107
+ end
108
+
109
+ ## View load paths determine the bases from which template references can be made. So a call to
110
+ ## render("test/template") will be looked up in the view load paths array and the closest match will be
111
+ ## returned.
112
+ def view_paths
113
+ @view_paths || superclass.view_paths
114
+ end
115
+
116
+ def view_paths=(value)
117
+ @view_paths = value
118
+ end
119
+
120
+ # Adds a view_path to the front of the view_paths array.
121
+ # If the current class has no view paths, copy them from
122
+ # the superclass. This change will be visible for all future requests.
123
+ #
124
+ # ArticleController.prepend_view_path("views/default")
125
+ # ArticleController.prepend_view_path(["views/default", "views/custom"])
126
+ #
127
+ def prepend_view_path(path)
128
+ @view_paths = superclass.view_paths.dup if @view_paths.nil?
129
+ @view_paths.unshift(*path)
130
+ end
131
+
132
+ # Adds a view_path to the end of the view_paths array.
133
+ # If the current class has no view paths, copy them from
134
+ # the superclass. This change will be visible for all future requests.
135
+ #
136
+ # ArticleController.append_view_path("views/default")
137
+ # ArticleController.append_view_path(["views/default", "views/custom"])
138
+ #
139
+ def append_view_path(path)
140
+ @view_paths = superclass.view_paths.dup if @view_paths.nil?
141
+ @view_paths.push(*path)
142
+ end
143
+
144
+ end
145
+
146
+ # Extracts the action_name from the request parameters and performs that action.
147
+ def process(request, response, method = :perform_action, *arguments) #:nodoc:
148
+ assign_params(request)
149
+ initialize_template_class(response)
150
+ assign_shortcuts(request, response)
151
+
152
+ log_processing
153
+ send(method, *arguments)
154
+
155
+ response
156
+ ensure
157
+ process_cleanup
158
+ end
159
+
160
+ # Converts the class name from something like "OneModule::TwoModule::NeatController" to "NeatController".
161
+ def controller_class_name
162
+ self.class.controller_class_name
163
+ end
164
+
165
+ # Converts the class name from something like "OneModule::TwoModule::NeatController" to "neat".
166
+ def controller_name
167
+ self.class.controller_name
168
+ end
169
+
170
+ # Converts the class name from something like "OneModule::TwoModule::NeatController" to "one_module/two_module/neat".
171
+ def controller_path
172
+ self.class.controller_path
173
+ end
174
+
175
+ self.view_paths = []
176
+
177
+ # View load paths for controller.
178
+ def view_paths
179
+ (@template || self.class).view_paths
180
+ end
181
+
182
+ def view_paths=(value)
183
+ (@template || self.class).view_paths = value
184
+ end
185
+
186
+ # Adds a view_path to the front of the view_paths array.
187
+ # This change affects the current request only.
188
+ #
189
+ # self.prepend_view_path("views/default")
190
+ # self.prepend_view_path(["views/default", "views/custom"])
191
+ #
192
+ def prepend_view_path(path)
193
+ (@template || self.class).prepend_view_path(path)
194
+ end
195
+
196
+ # Adds a view_path to the end of the view_paths array.
197
+ # This change affects the current request only.
198
+ #
199
+ # self.append_view_path("views/default")
200
+ # self.append_view_path(["views/default", "views/custom"])
201
+ #
202
+ def append_view_path(path)
203
+ (@template || self.class).append_view_path(path)
204
+ end
205
+
206
+ protected
207
+ # render
208
+ def render(options = nil, &block) #:doc:
209
+ raise DoubleRenderError, "Can only render or redirect once per action" if performed?
210
+
211
+ if options.nil?
212
+ return render(:file => default_template_name, :layout => true)
213
+ elsif !options.is_a?(Hash)
214
+ raise RenderError, "You called render with invalid options : #{options.inspect}"
215
+ end
216
+
217
+ layout = pick_layout(options)
218
+ logger.info("Rendering template within #{layout}") if logger && layout
219
+
220
+ if options.has_key?(:text)
221
+ text = layout ? @template.render(options.merge(:text => options[:text], :layout => layout)) : options[:text]
222
+ render_for_text(text, options[:status])
223
+
224
+ else
225
+ if file = options[:file]
226
+ render_for_file(file, options[:status], layout, options[:locals] || {})
227
+
228
+ elsif template = options[:template]
229
+ render_for_file(template, options[:status], layout, options[:locals] || {})
230
+
231
+ elsif inline = options[:inline]
232
+ render_for_text(@template.render(options.merge(:layout => layout)), options[:status])
233
+
234
+ elsif action_name = options[:action]
235
+ render_for_file(default_template_name(action_name.to_s), options[:status], layout)
236
+
237
+ elsif options[:partial]
238
+ options[:partial] = default_template_name if options[:partial] == true
239
+ if layout
240
+ render_for_text(@template.render(:text => @template.render(options), :layout => layout), options[:status])
241
+ else
242
+ render_for_text(@template.render(options), options[:status])
243
+ end
244
+
245
+ elsif options[:nothing]
246
+ render_for_text("", options[:status])
247
+
248
+ else
249
+ render_for_file(default_template_name, options[:status], layout)
250
+ end
251
+ end
252
+ end
253
+
254
+ # Renders according to the same rules as <tt>render</tt>, but returns the result in a string instead
255
+ # of sending it as the response body to the browser.
256
+ def render_to_string(options = nil, &block) #:doc:
257
+ render(options, &block)
258
+ ensure
259
+ erase_render_results
260
+ reset_variables_added_to_assigns
261
+ end
262
+
263
+ # Clears the rendered results, allowing for another render to be performed.
264
+ def erase_render_results #:nodoc:
265
+ response.clear
266
+ @performed_render = false
267
+ end
268
+
269
+ # Redirects to the target specified in +options+. This parameter can take one of three forms:
270
+ #
271
+ # * <tt>Hash</tt> - The URL will be generated by calling url_for with the +options+.
272
+ # * <tt>Record</tt> - The URL will be generated by calling url_for with the +options+, which will reference a named URL for that record.
273
+ #
274
+ # Examples:
275
+ # redirect_to :action => "show", :id => 5
276
+ # redirect_to post
277
+ # redirect_to articles_url
278
+ #
279
+ def redirect_to(options = {}) #:doc:
280
+ raise DoubleRenderError if performed?
281
+ logger.info("Redirected to #{options}") if logger && logger.info?
282
+ response.redirected_to = options
283
+ @performed_redirect = true
284
+ end
285
+
286
+ private
287
+
288
+ def render_for_file(template_path, status = nil, layout = nil, locals = {}) #:nodoc:
289
+ logger.info("Rendering #{template_path}" + (status ? " (#{status})" : '')) if logger
290
+ render_for_text(@template.render(:file => template_path, :locals => locals, :layout => layout), status)
291
+ end
292
+
293
+ def render_for_text(text = nil, status = nil) #:nodoc:
294
+ @performed_render = true
295
+ (instance_variable_names - protected_instance_variables).each {|name| response.variables[name[1..-1].to_sym] = instance_variable_get(name)}
296
+ response.body = text.to_s
297
+ # when will we get a proc? TODO investigate: response.body = text.is_a?(Proc) ? text : text.to_s
298
+ end
299
+
300
+ def assign_params(request)
301
+ @action_name = request.params[:action] || 'index'
302
+ @format = request.format
303
+ @_params = request.params.clone
304
+ @_params.delete(:controller)
305
+ @_params.delete(:action)
306
+ end
307
+
308
+ def initialize_template_class(response)
309
+ # Find the suitable Template class for the format of the request TODO: use class inheritable attr instead
310
+ template_class = @@template_classes[@format] || Reactive::Mvc::View::Base
311
+ #unless template_class = @@template_classes[@format]
312
+ # raise "You must assign a template class through Reactive::Controller::Base.register_template_class before processing a request\n" +
313
+ # "This may also happen when no view provider is configured. Check that you have one in config/environment.rb with config.gem 'your_view_provider'"
314
+ #end
315
+
316
+ response.template = template_class.new(view_paths, self)
317
+ response.template.extend self.class.master_helper_module
318
+ response.redirected_to = nil
319
+ @performed_render = @performed_redirect = false
320
+ end
321
+
322
+ def assign_shortcuts(request, response)
323
+ @_request = request
324
+ @_response = response
325
+ @template = response.template
326
+ end
327
+
328
+ def log_processing
329
+ if logger && logger.info?
330
+ logger.info "Processing #{controller_class_name}\##{action_name}"
331
+ logger.info " Parameters: #{respond_to?(:filter_parameters) ? filter_parameters(@_params).inspect : @_params.inspect}"
332
+ end
333
+ end
334
+
335
+ def default_render #:nodoc:
336
+ render
337
+ end
338
+
339
+ def perform_action
340
+ if action_methods.include?(action_name)
341
+ send(action_name)
342
+ default_render unless performed?
343
+ elsif respond_to? :method_missing
344
+ method_missing action_name
345
+ default_render unless performed?
346
+ elsif template_exists?
347
+ default_render
348
+ else
349
+ raise UnknownAction, "No action responded to #{action_name}", caller
350
+ end
351
+ end
352
+
353
+ def performed?
354
+ @performed_render || @performed_redirect
355
+ end
356
+
357
+ def action_methods
358
+ self.class.action_methods
359
+ end
360
+
361
+ def self.action_methods
362
+ @action_methods ||=
363
+ # All public instance methods of this class, including ancestors
364
+ public_instance_methods(true).map { |m| m.to_s }.to_set -
365
+ # Except for public instance methods of Base and its ancestors
366
+ Base.public_instance_methods(true).map { |m| m.to_s } +
367
+ # Be sure to include shadowed public instance methods of this class
368
+ public_instance_methods(false).map { |m| m.to_s } -
369
+ # And always exclude explicitly hidden actions
370
+ hidden_actions
371
+ end
372
+
373
+ def reset_variables_added_to_assigns
374
+ @template.instance_variable_set("@assigns_added", nil)
375
+ end
376
+
377
+ def template_exists?(template_name = default_template_name)
378
+ @template.template_exists?(template_name) # TODO: Contract with the View provider!!!
379
+ end
380
+
381
+ def default_template_name(action_name = self.action_name)
382
+ if action_name
383
+ action_name = action_name.to_s
384
+ if action_name.include?('/') && template_path_includes_controller?(action_name)
385
+ action_name = strip_out_controller(action_name)
386
+ end
387
+ end
388
+ "#{self.controller_path}/#{action_name}"
389
+ end
390
+
391
+ def strip_out_controller(path)
392
+ path.split('/', 2).last
393
+ end
394
+
395
+ def template_path_includes_controller?(path)
396
+ self.controller_path.split('/')[-1] == path.split('/')[0]
397
+ end
398
+
399
+ def process_cleanup
400
+ end
401
+ end
402
+
403
+ end
404
+
405
+ end