Allow to choose the template path and template name used in implicit rendering with ActionMailer.

This commit is contained in:
José Valim 2010-02-19 10:51:17 +01:00
parent e49f94d71c
commit be35a1510d
2 changed files with 81 additions and 46 deletions

@ -452,10 +452,27 @@ def attachments
# field for the 'envelope from' value.
#
# If you do not pass a block to the +mail+ method, it will find all templates in the
# template path that match the method name that it is being called from, it will then
# create parts for each of these templates intelligently, making educated guesses
# on correct content type and sequence, and return a fully prepared Mail::Message
# ready to call <tt>:deliver</tt> on to send.
# view paths using by default the mailer name and the method name that it is being
# called from, it will then create parts for each of these templates intelligently,
# making educated guesses on correct content type and sequence, and return a fully
# prepared Mail::Message ready to call <tt>:deliver</tt> on to send.
#
# For example:
#
# class Notifier < ActionMailer::Base
# default :from => 'no-reply@test.lindsaar.net',
#
# def welcome
# mail(:to => 'mikel@test.lindsaar.net')
# end
# end
#
# Will look for all templates at "app/views/notifier" with name "welcome". However, those
# can be customized:
#
# mail(:template_path => 'notifications', :template_name => 'another')
#
# And now it will look for all templates at "app/views/notifications" with name "another".
#
# If you do pass a block, you can render specific templates of your choice:
#
@ -493,7 +510,7 @@ def mail(headers={}, &block)
# Merge defaults from class
headers = headers.reverse_merge(self.class.default)
charset = headers[:charset]
charset = headers.delete(:charset)
# Quote fields
headers[:subject] ||= default_i18n_subject
@ -514,13 +531,11 @@ def mail(headers={}, &block)
end
# Set configure delivery behavior
wrap_delivery_behavior!(headers[:delivery_method])
wrap_delivery_behavior!(headers.delete(:delivery_method))
# Remove headers already treated and assign all others
headers.except!(:subject, :to, :from, :cc, :bcc, :reply_to)
headers.except!(:body, :parts_order, :content_type, :charset, :delivery_method)
# Remove any missing configuration header and assign all others
headers.except!(:parts_order, :content_type)
headers.each { |k, v| m[k] = v }
m
end
@ -548,12 +563,12 @@ def default_i18n_subject #:nodoc:
# TODO: Move this into Mail
def quote_fields!(headers, charset) #:nodoc:
m = @_message
m.subject ||= quote_if_necessary(headers[:subject], charset) if headers[:subject]
m.to ||= quote_address_if_necessary(headers[:to], charset) if headers[:to]
m.from ||= quote_address_if_necessary(headers[:from], charset) if headers[:from]
m.cc ||= quote_address_if_necessary(headers[:cc], charset) if headers[:cc]
m.bcc ||= quote_address_if_necessary(headers[:bcc], charset) if headers[:bcc]
m.reply_to ||= quote_address_if_necessary(headers[:reply_to], charset) if headers[:reply_to]
m.subject ||= quote_if_necessary(headers.delete(:subject), charset) if headers[:subject]
m.to ||= quote_address_if_necessary(headers.delete(:to), charset) if headers[:to]
m.from ||= quote_address_if_necessary(headers.delete(:from), charset) if headers[:from]
m.cc ||= quote_address_if_necessary(headers.delete(:cc), charset) if headers[:cc]
m.bcc ||= quote_address_if_necessary(headers.delete(:bcc), charset) if headers[:bcc]
m.reply_to ||= quote_address_if_necessary(headers.delete(:reply_to), charset) if headers[:reply_to]
end
def collect_responses_and_parts_order(headers) #:nodoc:
@ -566,11 +581,14 @@ def collect_responses_and_parts_order(headers) #:nodoc:
responses = collector.responses
elsif headers[:body]
responses << {
:body => headers[:body],
:body => headers.delete(:body),
:content_type => self.class.default[:content_type] || "text/plain"
}
else
each_template do |template|
templates_path = headers.delete(:template_path) || self.class.mailer_name
templates_name = headers.delete(:template_name) || action_name
each_template(templates_path, templates_name) do |template|
responses << {
:body => render_to_body(:_template => template),
:content_type => template.mime_type.to_s
@ -581,14 +599,16 @@ def collect_responses_and_parts_order(headers) #:nodoc:
[responses, parts_order]
end
def each_template(&block) #:nodoc:
self.class.view_paths.each do |load_paths|
templates = load_paths.find_all(action_name, {}, self.class.mailer_name)
templates = templates.uniq_by { |t| t.details[:formats] }
def each_template(paths, name, &block) #:nodoc:
Array(paths).each do |path|
self.class.view_paths.each do |load_paths|
templates = load_paths.find_all(name, {}, path)
templates = templates.uniq_by { |t| t.details[:formats] }
unless templates.empty?
templates.each(&block)
return
unless templates.empty?
templates.each(&block)
return
end
end
end
end

@ -14,8 +14,13 @@ def welcome(hash = {})
mail({:subject => "The first email on new API!"}.merge!(hash))
end
def simple(hash = {})
mail(hash)
def welcome_with_headers(hash = {})
headers hash
mail
end
def welcome_from_another_path(path)
mail(:template_name => "welcome", :template_path => path)
end
def html_only(hash = {})
@ -25,11 +30,6 @@ def html_only(hash = {})
def plain_text_only(hash = {})
mail(hash)
end
def simple_with_headers(hash = {})
headers hash
mail
end
def attachment_with_content(hash = {})
attachments['invoice.pdf'] = 'This is test File content'
@ -78,8 +78,12 @@ def custom_block(include_html=false)
format.html{ render "welcome" } if include_html
end
end
def different_template(template_name='')
def implicit_different_template(template_name='')
mail(:template_name => template_name)
end
def explicit_different_template(template_name='')
mail do |format|
format.text { render :template => "#{mailer_name}/#{template_name}" }
format.html { render :template => "#{mailer_name}/#{template_name}" }
@ -88,13 +92,10 @@ def different_template(template_name='')
def different_layout(layout_name='')
mail do |format|
format.text {
render :layout => layout_name
}
format.text { render :layout => layout_name }
format.html { render :layout => layout_name }
end
end
end
test "method call to mail does not raise error" do
@ -154,7 +155,7 @@ def different_layout(layout_name='')
test "can pass random headers in as a hash to mail" do
hash = {'X-Special-Domain-Specific-Header' => "SecretValue",
'In-Reply-To' => '1234@mikel.me.com' }
mail = BaseMailer.simple(hash)
mail = BaseMailer.welcome(hash)
assert_equal('SecretValue', mail['X-Special-Domain-Specific-Header'].decoded)
assert_equal('1234@mikel.me.com', mail['In-Reply-To'].decoded)
end
@ -162,7 +163,7 @@ def different_layout(layout_name='')
test "can pass random headers in as a hash" do
hash = {'X-Special-Domain-Specific-Header' => "SecretValue",
'In-Reply-To' => '1234@mikel.me.com' }
mail = BaseMailer.simple_with_headers(hash)
mail = BaseMailer.welcome_with_headers(hash)
assert_equal('SecretValue', mail['X-Special-Domain-Specific-Header'].decoded)
assert_equal('1234@mikel.me.com', mail['In-Reply-To'].decoded)
end
@ -247,9 +248,9 @@ def different_layout(layout_name='')
end
test "uses random default headers from class" do
with_default BaseMailer, "X-SPAM" => "Not spam" do
email = BaseMailer.simple
assert_equal("Not spam", email["X-SPAM"].decoded)
with_default BaseMailer, "X-Custom" => "Custom" do
email = BaseMailer.welcome
assert_equal("Custom", email["X-Custom"].decoded)
end
end
@ -476,18 +477,32 @@ def different_layout(layout_name='')
end
# Rendering
test "that you can specify a different template" do
mail = BaseMailer.different_template('explicit_multipart_templates')
test "you can specify a different template for implicit render" do
mail = BaseMailer.implicit_different_template('implicit_multipart')
assert_equal("HTML Implicit Multipart", mail.html_part.body.decoded)
assert_equal("TEXT Implicit Multipart", mail.text_part.body.decoded)
end
test "you can specify a different template for explicit render" do
mail = BaseMailer.explicit_different_template('explicit_multipart_templates')
assert_equal("HTML Explicit Multipart Templates", mail.html_part.body.decoded)
assert_equal("TEXT Explicit Multipart Templates", mail.text_part.body.decoded)
end
test "that you can specify a different layout" do
test "you can specify a different layout" do
mail = BaseMailer.different_layout('different_layout')
assert_equal("HTML -- HTML", mail.html_part.body.decoded)
assert_equal("PLAIN -- PLAIN", mail.text_part.body.decoded)
end
test "you can specify the template path for implicit lookup" do
mail = BaseMailer.welcome_from_another_path('another.path/base_mailer')
assert_equal("Welcome from another path", mail.body.encoded)
mail = BaseMailer.welcome_from_another_path(['unknown/invalid', 'another.path/base_mailer'])
assert_equal("Welcome from another path", mail.body.encoded)
end
protected
# Execute the block setting the given values and restoring old values after