aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Valim <jose.valim@gmail.com>2010-03-12 20:39:53 +0100
committerJosé Valim <jose.valim@gmail.com>2010-03-12 20:39:53 +0100
commitf2c0a353aef41a6df2de8e1fe3eaa3d8bbd8a6dd (patch)
treea854e0b7b79968f7f7cdfb57d29fd6644805c5ae
parent2a12686832fbcf0566454904a5d733998506bf56 (diff)
downloadrails-f2c0a353aef41a6df2de8e1fe3eaa3d8bbd8a6dd.tar.gz
rails-f2c0a353aef41a6df2de8e1fe3eaa3d8bbd8a6dd.tar.bz2
rails-f2c0a353aef41a6df2de8e1fe3eaa3d8bbd8a6dd.zip
Finish cleaning up rendering stack from views and move assigns evaluation to controller (so plugins and/or controllers can overwrite just one method).
-rw-r--r--actionmailer/test/base_test.rb2
-rw-r--r--actionmailer/test/old_base/mail_service_test.rb3
-rw-r--r--actionpack/lib/abstract_controller.rb1
-rw-r--r--actionpack/lib/abstract_controller/assigns.rb21
-rw-r--r--actionpack/lib/abstract_controller/layouts.rb6
-rw-r--r--actionpack/lib/abstract_controller/rendering.rb16
-rw-r--r--actionpack/lib/action_controller/metal/mime_responds.rb1
-rw-r--r--actionpack/lib/action_controller/metal/renderers.rb3
-rw-r--r--actionpack/lib/action_controller/metal/rendering.rb21
-rw-r--r--actionpack/lib/action_view/base.rb9
-rw-r--r--actionpack/lib/action_view/helpers/prototype_helper.rb1
-rw-r--r--actionpack/lib/action_view/render/layouts.rb5
-rw-r--r--actionpack/lib/action_view/render/rendering.rb37
-rw-r--r--actionpack/lib/action_view/template/handlers/rjs.rb3
-rw-r--r--actionpack/lib/action_view/template/text.rb14
15 files changed, 68 insertions, 75 deletions
diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb
index c1cf1f0157..f5fd12a6b0 100644
--- a/actionmailer/test/base_test.rb
+++ b/actionmailer/test/base_test.rb
@@ -2,6 +2,8 @@
require 'abstract_unit'
class BaseTest < ActiveSupport::TestCase
+ # TODO Add some tests for implicity layout render and url helpers
+ # so we can get rid of old base tests altogether with old base.
class BaseMailer < ActionMailer::Base
self.mailer_name = "base_mailer"
diff --git a/actionmailer/test/old_base/mail_service_test.rb b/actionmailer/test/old_base/mail_service_test.rb
index 70dafaf33c..6d0b2c53a3 100644
--- a/actionmailer/test/old_base/mail_service_test.rb
+++ b/actionmailer/test/old_base/mail_service_test.rb
@@ -444,9 +444,6 @@ class ActionMailerTest < Test::Unit::TestCase
expected.from = "system@loudthinking.com"
expected.date = Time.local(2004, 12, 12)
- # Stub the render method so no alternative renderers need be present.
- ActionView::Base.any_instance.stubs(:render).returns("Hello there, \n\nMr. #{@recipient}")
-
# Now that the template is registered, there should be one part. The text/plain part.
created = nil
assert_nothing_raised { created = TestMailer.custom_templating_extension(@recipient) }
diff --git a/actionpack/lib/abstract_controller.rb b/actionpack/lib/abstract_controller.rb
index 2da4dc052c..de95f935c2 100644
--- a/actionpack/lib/abstract_controller.rb
+++ b/actionpack/lib/abstract_controller.rb
@@ -12,6 +12,7 @@ require 'active_support/i18n'
module AbstractController
extend ActiveSupport::Autoload
+ autoload :Assigns
autoload :Base
autoload :Callbacks
autoload :Collector
diff --git a/actionpack/lib/abstract_controller/assigns.rb b/actionpack/lib/abstract_controller/assigns.rb
new file mode 100644
index 0000000000..21459c6d51
--- /dev/null
+++ b/actionpack/lib/abstract_controller/assigns.rb
@@ -0,0 +1,21 @@
+module AbstractController
+ module Assigns
+ # This method should return a hash with assigns.
+ # You can overwrite this configuration per controller.
+ # :api: public
+ def view_assigns
+ hash = {}
+ variables = instance_variable_names
+ variables -= protected_instance_variables if respond_to?(:protected_instance_variables)
+ variables.each { |name| hash[name] = instance_variable_get(name) }
+ hash
+ end
+
+ # This method assigns the hash specified in _assigns_hash to the given object.
+ # :api: private
+ # TODO Ideally, this should be done on AV::Base.new initialization.
+ def _evaluate_assigns(object)
+ view_assigns.each { |k,v| object.instance_variable_set(k, v) }
+ end
+ end
+end \ No newline at end of file
diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb
index 2f9616124a..95a6101109 100644
--- a/actionpack/lib/abstract_controller/layouts.rb
+++ b/actionpack/lib/abstract_controller/layouts.rb
@@ -284,6 +284,12 @@ module AbstractController
layout = options.key?(:layout) ? options.delete(:layout) : :default
value = _layout_for_option(layout)
options[:layout] = (value =~ /\blayouts/ ? value : "layouts/#{value}") if value
+
+ # TODO Layout for partials should be handled here, because inside the
+ # partial renderer it looks for the layout as a partial.
+ if options.key?(:partial) && options[:layout]
+ options[:layout] = view_context.find_layout(options[:layout])
+ end
end
end
diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb
index 42f4939108..16664098e5 100644
--- a/actionpack/lib/abstract_controller/rendering.rb
+++ b/actionpack/lib/abstract_controller/rendering.rb
@@ -31,6 +31,8 @@ module AbstractController
module Rendering
extend ActiveSupport::Concern
+
+ include AbstractController::Assigns
include AbstractController::ViewPaths
# Overwrite process to setup I18n proxy.
@@ -54,8 +56,8 @@ module AbstractController
@_view_context ||= ActionView::Base.for_controller(self)
end
- # Mostly abstracts the fact that calling render twice is a DoubleRenderError.
- # Delegates render_to_body and sticks the result in self.response_body.
+ # Normalize arguments, options and then delegates render_to_body and
+ # sticks the result in self.response_body.
def render(*args, &block)
options = _normalize_args(*args, &block)
_normalize_options(options)
@@ -78,8 +80,10 @@ module AbstractController
end
# Find and renders a template based on the options given.
- def _render_template(options)
- view_context.render_template(options) { |template| _with_template_hook(template) }
+ # :api: private
+ def _render_template(options) #:nodoc:
+ _evaluate_assigns(view_context)
+ view_context.render(options)
end
# The prefix used in render "foo" shortcuts.
@@ -134,9 +138,5 @@ module AbstractController
def _process_options(options)
end
-
- def _with_template_hook(template)
- self.formats = template.formats
- end
end
end
diff --git a/actionpack/lib/action_controller/metal/mime_responds.rb b/actionpack/lib/action_controller/metal/mime_responds.rb
index e70a20b2be..2ac199265d 100644
--- a/actionpack/lib/action_controller/metal/mime_responds.rb
+++ b/actionpack/lib/action_controller/metal/mime_responds.rb
@@ -261,6 +261,7 @@ module ActionController #:nodoc:
block.call(collector) if block_given?
if format = request.negotiate_mime(collector.order)
+ self.content_type ||= format.to_s
self.formats = [format.to_sym]
collector.response_for(format)
else
diff --git a/actionpack/lib/action_controller/metal/renderers.rb b/actionpack/lib/action_controller/metal/renderers.rb
index 49d3d6b466..08325b468c 100644
--- a/actionpack/lib/action_controller/metal/renderers.rb
+++ b/actionpack/lib/action_controller/metal/renderers.rb
@@ -87,8 +87,9 @@ module ActionController
end
add :update do |proc, options|
+ _evaluate_assigns(view_context)
generator = ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.new(view_context, &proc)
- self.content_type = Mime::JS
+ self.content_type = Mime::JS
self.response_body = generator.to_s
end
end
diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb
index f892bd9b91..2167fe9a32 100644
--- a/actionpack/lib/action_controller/metal/rendering.rb
+++ b/actionpack/lib/action_controller/metal/rendering.rb
@@ -5,26 +5,31 @@ module ActionController
include ActionController::RackDelegation
include AbstractController::Rendering
- def process(*)
+ # Before processing, set the request formats in current controller formats.
+ def process(*) #:nodoc:
self.formats = request.formats.map { |x| x.to_sym }
super
end
- def render(*args)
+ # Check for double render errors and set the content_type after rendering.
+ def render(*args) #:nodoc:
raise ::AbstractController::DoubleRenderError if response_body
super
+ self.content_type ||= Mime[formats.first].to_s
response_body
end
private
- def _normalize_args(action=nil, options={}, &blk)
+ # Normalize arguments by catching blocks and setting them on :update.
+ def _normalize_args(action=nil, options={}, &blk) #:nodoc:
options = super
options[:update] = blk if block_given?
options
end
- def _normalize_options(options)
+ # Normalize both text and status options.
+ def _normalize_options(options) #:nodoc:
if options.key?(:text) && options[:text].respond_to?(:to_text)
options[:text] = options[:text].to_text
end
@@ -36,7 +41,8 @@ module ActionController
super
end
- def _process_options(options)
+ # Process controller specific options, as status, content-type and location.
+ def _process_options(options) #:nodoc:
status, content_type, location = options.values_at(:status, :content_type, :location)
self.status = status if status
@@ -46,10 +52,5 @@ module ActionController
super
end
- def _with_template_hook(template)
- super
- self.content_type ||= template.mime_type.to_s
- end
-
end
end
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb
index f1b1c22075..feaf45c333 100644
--- a/actionpack/lib/action_view/base.rb
+++ b/actionpack/lib/action_view/base.rb
@@ -264,14 +264,5 @@ module ActionView #:nodoc:
response.body_parts << part
nil
end
-
- # Evaluates the local assigns and controller ivars, pushes them to the view.
- def _evaluate_assigns_and_ivars #:nodoc:
- if controller
- variables = controller.instance_variable_names
- variables -= controller.protected_instance_variables if controller.respond_to?(:protected_instance_variables)
- variables.each { |name| instance_variable_set(name, controller.instance_variable_get(name)) }
- end
- end
end
end
diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb
index be49b5cc28..e58fdf81fb 100644
--- a/actionpack/lib/action_view/helpers/prototype_helper.rb
+++ b/actionpack/lib/action_view/helpers/prototype_helper.rb
@@ -180,7 +180,6 @@ module ActionView
# #include_helpers_from_context has nothing to overwrite.
class JavaScriptGenerator #:nodoc:
def initialize(context, &block) #:nodoc:
- context._evaluate_assigns_and_ivars
@context, @lines = context, []
@context.update_details(:formats => [:js, :html]) do
include_helpers_from_context
diff --git a/actionpack/lib/action_view/render/layouts.rb b/actionpack/lib/action_view/render/layouts.rb
index 91a92a833a..0cb688ca77 100644
--- a/actionpack/lib/action_view/render/layouts.rb
+++ b/actionpack/lib/action_view/render/layouts.rb
@@ -1,8 +1,5 @@
-require 'active_support/core_ext/object/try'
-
module ActionView
module Layouts
-
# You can think of a layout as a method that is called with a block. _layout_for
# returns the contents that are yielded to the layout. If the user calls yield
# :some_name, the block, by default, returns content_for(:some_name). If the user
@@ -46,7 +43,7 @@ module ActionView
# This is the method which actually finds the layout using details in the lookup
# context object. If no layout is found, it checkes if at least a layout with
# the given name exists across all details before raising the error.
- def _find_layout(layout) #:nodoc:
+ def find_layout(layout) #:nodoc:
begin
layout =~ /^\// ?
with_fallbacks { find_template(layout) } : find_template(layout)
diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb
index d9ac1f6290..9b5b976727 100644
--- a/actionpack/lib/action_view/render/rendering.rb
+++ b/actionpack/lib/action_view/render/rendering.rb
@@ -12,14 +12,17 @@ module ActionView
#
# If no options hash is passed or :update specified, the default is to render a partial and use the second parameter
# as the locals hash.
- def render(options = {}, locals = {}, &block) #:nodoc:
+ def render(options = {}, locals = {}, &block)
case options
when Hash
if block_given?
content = _render_partial(options.merge(:partial => options[:layout]), &block)
safe_concat(content)
+ elsif options.key?(:partial)
+ _render_partial(options)
else
- _render(options)
+ template = _determine_template(options)
+ _render_template(template, options[:layout], options)
end
when :update
update_page(&block)
@@ -28,31 +31,6 @@ module ActionView
end
end
- # This is the API to render a ViewContext's template from a controller.
- def render_template(options, &block)
- _evaluate_assigns_and_ivars
-
- # TODO Layout for partials should be handled here, because inside the
- # partial renderer it looks for the layout as a partial.
- if options.key?(:partial) && options[:layout]
- options[:layout] = _find_layout(options[:layout])
- end
-
- _render(options, &block)
- end
-
- # This method holds the common render logic for both controllers and
- # views rendering stacks.
- def _render(options) #:nodoc:
- if options.key?(:partial)
- _render_partial(options)
- else
- template = _determine_template(options)
- yield template if block_given?
- _render_template(template, options[:layout], options)
- end
- end
-
# Determine the template to be rendered using the given options.
def _determine_template(options) #:nodoc:
if options.key?(:inline)
@@ -71,8 +49,10 @@ module ActionView
# Renders the given template. An string representing the layout can be
# supplied as well.
def _render_template(template, layout = nil, options = {}) #:nodoc:
+ self.formats = template.formats
+
locals = options[:locals] || {}
- layout = _find_layout(layout) if layout
+ layout = find_layout(layout) if layout
ActiveSupport::Notifications.instrument("action_view.render_template",
:identifier => template.identifier, :layout => layout.try(:identifier)) do
@@ -88,6 +68,5 @@ module ActionView
content
end
end
-
end
end
diff --git a/actionpack/lib/action_view/template/handlers/rjs.rb b/actionpack/lib/action_view/template/handlers/rjs.rb
index 63e7dc0902..128be5077c 100644
--- a/actionpack/lib/action_view/template/handlers/rjs.rb
+++ b/actionpack/lib/action_view/template/handlers/rjs.rb
@@ -6,8 +6,7 @@ module ActionView
self.default_format = Mime::JS
def compile(template)
- "controller.response.content_type ||= Mime::JS;" +
- "update_page do |page|;#{template.source}\nend"
+ "update_page do |page|;#{template.source}\nend"
end
def default_format
diff --git a/actionpack/lib/action_view/template/text.rb b/actionpack/lib/action_view/template/text.rb
index df394b0fb0..269340514c 100644
--- a/actionpack/lib/action_view/template/text.rb
+++ b/actionpack/lib/action_view/template/text.rb
@@ -1,10 +1,12 @@
module ActionView #:nodoc:
class Template
class Text < String #:nodoc:
- def initialize(string, content_type = nil)
+ attr_accessor :mime_type
+
+ def initialize(string, mime_type = nil)
super(string.to_s)
- @content_type = Mime[content_type] || content_type if content_type
- @content_type ||= Mime::TEXT
+ @mime_type = Mime[mime_type] || mime_type if mime_type
+ @mime_type ||= Mime::TEXT
end
def identifier
@@ -19,12 +21,8 @@ module ActionView #:nodoc:
to_s
end
- def mime_type
- @content_type
- end
-
def formats
- [@content_type.to_sym]
+ [@mime_type.to_sym]
end
def partial?