Skip to content
Browse files

Allow to choose the template path and template name used in implicit …

…rendering with ActionMailer.
  • Loading branch information...
1 parent e49f94d commit be35a1510d065fc8575524e1b6b9f2bebd3e138c @josevalim josevalim committed Feb 19, 2010
Showing with 81 additions and 46 deletions.
  1. +45 −25 actionmailer/lib/action_mailer/base.rb
  2. +36 −21 actionmailer/test/base_test.rb
View
70 actionmailer/lib/action_mailer/base.rb
@@ -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
View
57 actionmailer/test/base_test.rb
@@ -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,15 +155,15 @@ 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
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

0 comments on commit be35a15

Please sign in to comment.
Something went wrong with that request. Please try again.