diff options
-rw-r--r-- | actionmailer/lib/action_mailer/base.rb | 168 | ||||
-rw-r--r-- | actionmailer/test/mail_render_test.rb | 15 | ||||
-rw-r--r-- | actionpack/lib/abstract_controller/layouts.rb | 9 | ||||
-rw-r--r-- | actionpack/lib/abstract_controller/rendering_controller.rb | 19 | ||||
-rw-r--r-- | actionpack/lib/action_controller/metal/layouts.rb | 10 | ||||
-rw-r--r-- | actionpack/lib/action_controller/metal/rendering_controller.rb | 24 | ||||
-rw-r--r-- | actionpack/test/abstract/helper_test.rb | 4 |
7 files changed, 115 insertions, 134 deletions
diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index d01120d0d8..3009d8cdfc 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -376,13 +376,19 @@ module ActionMailer #:nodoc: # The mail object instance referenced by this mailer. attr_reader :mail attr_reader :template_name, :default_template_name, :action_name + attr_internal :response_body def controller_path self.class.controller_path end - + def formats - @template.formats + [:"*/*"] + end + + # Refactor out all mailer_name + def _prefix + mailer_name end class << self @@ -468,67 +474,68 @@ module ActionMailer #:nodoc: # Initialize the mailer via the given +method_name+. The body will be # rendered and a new TMail::Mail object created. def create!(method_name, *parameters) #:nodoc: - ActiveSupport::Notifications.instrument(:create_mail, :name => method_name) do - initialize_defaults(method_name) - __send__(method_name, *parameters) + initialize_defaults(method_name) + __send__(method_name, *parameters) + + # Check if render was called. + @body = self.response_body if @body.is_a?(Hash) && @body.empty? - # If an explicit, textual body has not been set, we check assumptions. - unless String === @body - # TODO Hax + # If an explicit, textual body has not been set, we check assumptions. + unless String === @body + # TODO Fix me. Deprecate assigns to be given as a :body hash + if @body.is_a?(Hash) @body.each do |k, v| instance_variable_set(:"@#{k}", v) end - - # First, we look to see if there are any likely templates that match, - # which include the content-type in their file name (i.e., - # "the_template_file.text.html.erb", etc.). Only do this if parts - # have not already been specified manually. - # if @parts.empty? - template_root.find_all(@template, {}, template_path).each do |template| - @parts << Part.new( - :content_type => template.mime_type ? template.mime_type.to_s : "text/plain", - :disposition => "inline", - :charset => charset, - :body => render_to_string(:_template => template) - ) - end - - if @parts.size > 1 - @content_type = "multipart/alternative" if @content_type !~ /^multipart/ - @parts = sort_parts(@parts, @implicit_parts_order) - end - # end - - # Then, if there were such templates, we check to see if we ought to - # also render a "normal" template (without the content type). If a - # normal template exists (or if there were no implicit parts) we render - # it. - # ==== - # TODO: Revisit this - # template_exists = @parts.empty? - # template_exists ||= template_root.find("#{mailer_name}/#{@template}") - # @body = render_message(@template, @body) if template_exists - - # Finally, if there are other message parts and a textual body exists, - # we shift it onto the front of the parts and set the body to nil (so - # that create_mail doesn't try to render it in addition to the parts). - # ==== - # TODO: Revisit this - # if !@parts.empty? && String === @body - # @parts.unshift Part.new(:charset => charset, :body => @body) - # @body = nil - # end end - # If this is a multipart e-mail add the mime_version if it is not - # already set. - @mime_version ||= "1.0" if !@parts.empty? + # First, we look to see if there are any likely templates that match, + # which include the content-type in their file name (i.e., + # "the_template_file.text.html.erb", etc.). Only do this if parts + # have not already been specified manually. + # if @parts.empty? + template_root.find_all(@template, {}, template_path).each do |template| + @parts << Part.new( + :content_type => template.mime_type ? template.mime_type.to_s : "text/plain", + :disposition => "inline", + :charset => charset, + :body => render_to_body(:_template => template) + ) + end - # build the mail object itself - @mail = create_mail + if @parts.size > 1 + @content_type = "multipart/alternative" if @content_type !~ /^multipart/ + @parts = sort_parts(@parts, @implicit_parts_order) + end + # end + + # Then, if there were such templates, we check to see if we ought to + # also render a "normal" template (without the content type). If a + # normal template exists (or if there were no implicit parts) we render + # it. + # ==== + # TODO: Revisit this + # template_exists = @parts.empty? + # template_exists ||= template_root.find("#{mailer_name}/#{@template}") + # @body = render_message(@template, @body) if template_exists + + # Finally, if there are other message parts and a textual body exists, + # we shift it onto the front of the parts and set the body to nil (so + # that create_mail doesn't try to render it in addition to the parts). + # ==== + # TODO: Revisit this + # if !@parts.empty? && String === @body + # @parts.unshift Part.new(:charset => charset, :body => @body) + # @body = nil + # end end - @mail + # If this is a multipart e-mail add the mime_version if it is not + # already set. + @mime_version ||= "1.0" if !@parts.empty? + + # build the mail object itself + @mail = create_mail end # Delivers a TMail::Mail object. By default, it delivers the cached mail @@ -537,7 +544,7 @@ module ActionMailer #:nodoc: def deliver!(mail = @mail) raise "no mail object available for delivery!" unless mail - unless logger.nil? + if logger logger.info "Sent mail to #{Array(recipients).join(', ')}" logger.debug "\n#{mail.encoded}" end @@ -571,45 +578,16 @@ module ActionMailer #:nodoc: @sent_on ||= Time.now end - def _determine_template(options) - super - layout = options.key?(:layout) ? options[:layout] : :default - options[:_layout] = _layout_for_option(layout, options[:_template].details) - end - - def render_message(method_name, body) - render :file => method_name, :body => body - ensure - @current_template_content_type = nil - end - - def render(opts) - file = opts[:file] - opts[:locals] ||= {} - - @template = initialize_template_class(opts.delete(:body)) - - if file - prefix = mailer_name unless file =~ /\// - template = view_paths.find(file, {:formats => formats}, prefix) + def render(*args) + # TODO Fix me. Deprecate assigns to be given as a :body hash + options = args.last.is_a?(Hash) ? args.last : {} + if options[:body] + options.delete(:body).each do |k, v| + instance_variable_set(:"@#{k}", v) + end end - layout = opts.key?(:layout) ? opts.delete(:layout) : :default - layout = _layout_for_option(layout, :formats => formats) - - if template - @template._render_template(template, layout, opts) - elsif inline = opts[:inline] - @template._render_inline(inline, layout, opts) - end - end - - def default_template_format - if @current_template_content_type - Mime::Type.lookup(@current_template_content_type).to_sym - else - :html - end + super end def template_root @@ -624,12 +602,6 @@ module ActionMailer #:nodoc: "#{mailer_name}" end - def initialize_template_class(assigns) - template = ActionView::Base.new(self.class.view_paths, assigns, self) - template.formats = [default_template_format] - template - end - def sort_parts(parts, order = []) order = order.collect { |s| s.downcase } diff --git a/actionmailer/test/mail_render_test.rb b/actionmailer/test/mail_render_test.rb index 45811612eb..3f66fb1e43 100644 --- a/actionmailer/test/mail_render_test.rb +++ b/actionmailer/test/mail_render_test.rb @@ -12,7 +12,15 @@ class RenderMailer < ActionMailer::Base recipients recipient subject "using helpers" from "tester@example.com" - body render(:file => "signed_up", :body => { :recipient => recipient }) + body render(:file => "templates/signed_up", :body => { :recipient => recipient }) + end + + def implicit_body(recipient) + recipients recipient + subject "using helpers" + from "tester@example.com" + + render(:template => "templates/signed_up", :body => { :recipient => recipient }) end def rxml_template(recipient) @@ -69,6 +77,11 @@ class RenderHelperTest < Test::Unit::TestCase restore_delivery_method end + def test_implicit_body + mail = RenderMailer.create_implicit_body(@recipient) + assert_equal "Hello there, \n\nMr. test@localhost", mail.body.strip + end + def test_inline_template mail = RenderMailer.create_inline_template(@recipient) assert_equal "Hello, Earth", mail.body.strip diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb index 4723e18a01..f4f1d41360 100644 --- a/actionpack/lib/abstract_controller/layouts.rb +++ b/actionpack/lib/abstract_controller/layouts.rb @@ -157,6 +157,7 @@ module AbstractController end private + # This will be overwritten by _write_layout_method def _layout(details) end @@ -191,6 +192,14 @@ module AbstractController end end + def _determine_template(options) + super + + return if (options.key?(:text) || options.key?(:inline) || options.key?(:partial)) && !options.key?(:layout) + layout = options.key?(:layout) ? options[:layout] : :default + options[:_layout] = _layout_for_option(layout, options[:_template].details) + end + # Take in the name and details and find a Template. # # ==== Parameters diff --git a/actionpack/lib/abstract_controller/rendering_controller.rb b/actionpack/lib/abstract_controller/rendering_controller.rb index bbf941aa32..9fb7935ce4 100644 --- a/actionpack/lib/abstract_controller/rendering_controller.rb +++ b/actionpack/lib/abstract_controller/rendering_controller.rb @@ -109,6 +109,21 @@ module AbstractController # to a directory. # _partial<TrueClass, FalseClass>:: Whether or not the file to look up is a partial def _determine_template(options) + if options.key?(:text) + options[:_template] = ActionView::TextTemplate.new(options[:text], formats.first) + elsif options.key?(:inline) + handler = ActionView::Template.handler_class_for_extension(options[:type] || "erb") + template = ActionView::Template.new(options[:inline], "inline #{options[:inline].inspect}", handler, {}) + options[:_template] = template + elsif options.key?(:template) + options[:_template_name] = options[:template] + elsif options.key?(:file) + options[:_template_name] = options[:file] + elsif !options.key?(:partial) + options[:_template_name] ||= options[:action] + options[:_prefix] = _prefix + end + name = (options[:_template_name] || action_name).to_s options[:_template] ||= with_template_cache(name) do @@ -124,6 +139,10 @@ module AbstractController view_paths.exists?(name, details, options[:_prefix], options[:_partial]) end + def _prefix + self.class.name.underscore + end + def with_template_cache(name) yield end diff --git a/actionpack/lib/action_controller/metal/layouts.rb b/actionpack/lib/action_controller/metal/layouts.rb index e7859e3fec..cc7088248a 100644 --- a/actionpack/lib/action_controller/metal/layouts.rb +++ b/actionpack/lib/action_controller/metal/layouts.rb @@ -167,15 +167,5 @@ module ActionController controller_path end end - - private - def _determine_template(options) - super - - return if (options.key?(:text) || options.key?(:inline) || options.key?(:partial)) && !options.key?(:layout) - layout = options.key?(:layout) ? options[:layout] : :default - options[:_layout] = _layout_for_option(layout, options[:_template].details) - end - end end diff --git a/actionpack/lib/action_controller/metal/rendering_controller.rb b/actionpack/lib/action_controller/metal/rendering_controller.rb index 4da32ca1b3..afd484b0ec 100644 --- a/actionpack/lib/action_controller/metal/rendering_controller.rb +++ b/actionpack/lib/action_controller/metal/rendering_controller.rb @@ -38,11 +38,6 @@ module ActionController def process_action(*) self.formats = request.formats.map {|x| x.to_sym} - - super - end - - def _determine_template(*) super end @@ -74,25 +69,6 @@ module ActionController self.class.template_cache[Thread.current[:format_locale_key]][name] ||= super end - def _determine_template(options) - if options.key?(:text) - options[:_template] = ActionView::TextTemplate.new(options[:text], formats.first) - elsif options.key?(:inline) - handler = ActionView::Template.handler_class_for_extension(options[:type] || "erb") - template = ActionView::Template.new(options[:inline], "inline #{options[:inline].inspect}", handler, {}) - options[:_template] = template - elsif options.key?(:template) - options[:_template_name] = options[:template] - elsif options.key?(:file) - options[:_template_name] = options[:file] - elsif !options.key?(:partial) - options[:_template_name] = (options[:action] || action_name).to_s - options[:_prefix] = _prefix - end - - super - end - def _process_options(options) status, content_type, location = options.values_at(:status, :content_type, :location) self.status = status if status diff --git a/actionpack/test/abstract/helper_test.rb b/actionpack/test/abstract/helper_test.rb index 5a363c9aa5..b6952d2758 100644 --- a/actionpack/test/abstract/helper_test.rb +++ b/actionpack/test/abstract/helper_test.rb @@ -7,10 +7,12 @@ module AbstractController include AbstractController::RenderingController include Helpers + def _prefix() end + def render(string) super(:_template_name => string) end - + append_view_path File.expand_path(File.join(File.dirname(__FILE__), "views")) end |