Add basic template rendering to new DSL.

This commit is contained in:
José Valim and Mikel Lindsaar
2010-01-22 13:27:20 +01:00
parent 6cf378aeb0
commit dcb9253693
8 changed files with 88 additions and 68 deletions

View File

@@ -280,6 +280,7 @@ module ActionMailer #:nodoc:
extlib_inheritable_accessor :default_charset
self.default_charset = "utf-8"
# TODO This should be used when calling render
extlib_inheritable_accessor :default_content_type
self.default_content_type = "text/plain"
@@ -357,7 +358,7 @@ module ActionMailer #:nodoc:
begin
# TODO Move me to the instance
if @@perform_deliveries
mail.deliver!
mail.deliver!
self.deliveries << mail
end
rescue Exception => e # Net::SMTP errors or sendmail pipe errors
@@ -393,32 +394,62 @@ module ActionMailer #:nodoc:
# Guard flag to prevent both the old and the new API from firing
# Should be removed when old API is deprecated
@mail_was_called = true
m = @message
m.content_type ||= headers[:content_type] || self.class.default_content_type
m.charset ||= headers[:charset] || self.class.default_charset
m.mime_version ||= headers[:mime_version] || self.class.default_mime_version
m.subject = quote_if_necessary(headers[:subject], m.charset) if headers[:subject]
m.to = quote_address_if_necessary(headers[:to], m.charset) if headers[:to]
m.from = quote_address_if_necessary(headers[:from], m.charset) if headers[:from]
m.cc = quote_address_if_necessary(headers[:cc], m.charset) if headers[:cc]
m.bcc = quote_address_if_necessary(headers[:bcc], m.charset) if headers[:bcc]
m.reply_to = quote_address_if_necessary(headers[:reply_to], m.charset) if headers[:reply_to]
m.date = headers[:date] if headers[:date]
# Get default subject from I18n if none is set
headers[:subject] ||= I18n.t(:subject, :scope => [:actionmailer, mailer_name, action_name],
:default => action_name.humanize)
m.body.set_sort_order(headers[:parts_order] || self.class.default_implicit_parts_order)
# Give preference to headers and fallbacks to the ones set in mail
headers[:content_type] ||= m.content_type
headers[:charset] ||= m.charset
headers[:mime_version] ||= m.mime_version
# # Set the subject if not set yet
# @subject ||= I18n.t(:subject, :scope => [:actionmailer, mailer_name, method_name],
# :default => method_name.humanize)
m.content_type = headers[:content_type] || self.class.default_content_type.dup
m.charset = headers[:charset] || self.class.default_charset.dup
m.mime_version = headers[:mime_version] || self.class.default_mime_version.dup
m.subject ||= quote_if_necessary(headers[:subject], m.charset) if headers[:subject]
m.to ||= quote_address_if_necessary(headers[:to], m.charset) if headers[:to]
m.from ||= quote_address_if_necessary(headers[:from], m.charset) if headers[:from]
m.cc ||= quote_address_if_necessary(headers[:cc], m.charset) if headers[:cc]
m.bcc ||= quote_address_if_necessary(headers[:bcc], m.charset) if headers[:bcc]
m.reply_to ||= quote_address_if_necessary(headers[:reply_to], m.charset) if headers[:reply_to]
m.date ||= headers[:date] if headers[:date]
if block_given?
# Do something
else
# TODO Ensure that we don't need to pass I18n.locale as detail
templates = self.class.template_root.find_all(action_name, {}, mailer_name)
if templates.size == 1
unless headers[:content_type]
proper_charset = m.charset
m.content_type = templates[0].mime_type.to_s
m.charset = proper_charset
end
m.body = render_to_body(:_template => templates[0])
else
templates.each do |template|
part = Mail::Part.new
part.content_type = template.mime_type.to_s
part.charset = m.charset
part.body = render_to_body(:_template => template)
end
end
end
m.body.set_sort_order(headers[:parts_order] || self.class.default_implicit_parts_order.dup)
# TODO: m.body.sort_parts!
m
end
def fill_in_part(part, template, charset)
end
# Instantiate a new mailer object. If +method_name+ is not +nil+, the mailer
# will be initialized according to the named method. If not, the mailer will
# remain uninitialized (useful when you only need to invoke the "receive"

View File

@@ -120,19 +120,12 @@ module ActionMailer
initialize_defaults(method_name)
super
unless @mail_was_called
# Create e-mail parts
create_parts
# Set the subject if not set yet
@subject ||= I18n.t(:subject, :scope => [:actionmailer, mailer_name, method_name],
:default => method_name.humanize)
# Build the mail object itself
create_mail
end
@message
end
# Add a part to a multipart message, with the given content-type. The
# part itself is yielded to the block so that other properties (charset,
# body, headers, etc.) can be set on it.

View File

@@ -22,7 +22,7 @@ module ActionMailer
end
# Access the message instance.
def message
def message #:nodoc:
@message
end
end

View File

@@ -44,7 +44,9 @@ class BaseTest < ActiveSupport::TestCase
:subject => 'The first email on new API!'
}
class TestMailer < ActionMailer::Base
class BaseMailer < ActionMailer::Base
self.mailer_name = "base_mailer"
def welcome(hash = {})
headers['X-SPAM'] = "Not SPAM"
mail(DEFAULT_HEADERS.merge(hash))
@@ -63,11 +65,11 @@ class BaseTest < ActiveSupport::TestCase
end
test "method call to mail does not raise error" do
assert_nothing_raised { TestMailer.deliver_welcome }
assert_nothing_raised { BaseMailer.deliver_welcome }
end
test "mail() should set the headers of the mail message" do
email = TestMailer.deliver_welcome
email = BaseMailer.deliver_welcome
assert_equal(email.to, ['mikel@test.lindsaar.net'])
assert_equal(email.from, ['jose@test.plataformatec.com'])
assert_equal(email.subject, 'The first email on new API!')
@@ -75,7 +77,7 @@ class BaseTest < ActiveSupport::TestCase
test "mail() with bcc, cc, content_type, charset, mime_version, reply_to and date" do
@time = Time.now
email = TestMailer.deliver_welcome(:bcc => 'bcc@test.lindsaar.net',
email = BaseMailer.deliver_welcome(:bcc => 'bcc@test.lindsaar.net',
:cc => 'cc@test.lindsaar.net',
:content_type => 'multipart/mixed',
:charset => 'iso-8559-1',
@@ -91,68 +93,70 @@ class BaseTest < ActiveSupport::TestCase
assert_equal(email.date, @time)
end
test "mail() renders the template using the method being processed" do
email = BaseMailer.deliver_welcome
assert_equal("Welcome", email.body.encoded)
end
test "custom headers" do
email = TestMailer.deliver_welcome
email = BaseMailer.deliver_welcome
assert_equal("Not SPAM", email['X-SPAM'].decoded)
end
test "attachment with content" do
email = TestMailer.deliver_attachment_with_content
email = BaseMailer.deliver_attachment_with_content
assert_equal(1, email.attachments.length)
assert_equal('invoice.pdf', email.attachments[0].filename)
assert_equal('This is test File content', email.attachments['invoice.pdf'].decoded)
end
test "attachment gets content type from filename" do
email = TestMailer.deliver_attachment_with_content
email = BaseMailer.deliver_attachment_with_content
assert_equal('invoice.pdf', email.attachments[0].filename)
end
test "attachment with hash" do
email = TestMailer.deliver_attachment_with_hash
email = BaseMailer.deliver_attachment_with_hash
assert_equal(1, email.attachments.length)
assert_equal('invoice.jpg', email.attachments[0].filename)
assert_equal("\312\213\254\232)b", email.attachments['invoice.jpg'].decoded)
end
# test "mail sets proper content type when attachment is included" do
# email = BaseMailer.deliver_attachment_with_content
# assert_equal(1, email.attachments.length)
# assert_equal("multipart/mixed", email.content_type)
# end
test "uses default charset from class" do
swap TestMailer, :default_charset => "US-ASCII" do
email = TestMailer.deliver_welcome
swap BaseMailer, :default_charset => "US-ASCII" do
email = BaseMailer.deliver_welcome
assert_equal("US-ASCII", email.charset)
email = TestMailer.deliver_welcome(:charset => "iso-8559-1")
email = BaseMailer.deliver_welcome(:charset => "iso-8559-1")
assert_equal("iso-8559-1", email.charset)
end
end
test "uses default content type from class" do
swap TestMailer, :default_content_type => "text/html" do
email = TestMailer.deliver_welcome
assert_equal("text/html", email.mime_type)
email = TestMailer.deliver_welcome(:content_type => "application/xml")
assert_equal("application/xml", email.mime_type)
end
end
test "uses default mime version from class" do
swap TestMailer, :default_mime_version => "2.0" do
email = TestMailer.deliver_welcome
swap BaseMailer, :default_mime_version => "2.0" do
email = BaseMailer.deliver_welcome
assert_equal("2.0", email.mime_version)
email = TestMailer.deliver_welcome(:mime_version => "1.0")
email = BaseMailer.deliver_welcome(:mime_version => "1.0")
assert_equal("1.0", email.mime_version)
end
end
# def test_that_class_defaults_are_set_on_instantiation
# pending
# end
#
# def test_should_set_the_subject_from_i18n
# pending
# end
test "subject gets default from I18n" do
email = BaseMailer.deliver_welcome(:subject => nil)
assert_equal "Welcome", email.subject
I18n.backend.store_translations('en', :actionmailer => {:base_mailer => {:welcome => {:subject => "New Subject!"}}})
email = BaseMailer.deliver_welcome(:subject => nil)
assert_equal "New Subject!", email.subject
end
protected
# Execute the block setting the given values and restoring old values after

View File

@@ -0,0 +1 @@
Welcome

View File

@@ -1,2 +0,0 @@
body: <%= @body %>
bar: <%= @bar %>

View File

@@ -416,15 +416,6 @@ class ActionMailerTest < Test::Unit::TestCase
assert_equal expected.encoded, delivered.encoded
end
def test_subject_with_i18n
assert_nothing_raised { TestMailer.deliver_subject_with_i18n(@recipient) }
assert_equal "Subject with i18n", ActionMailer::Base.deliveries.first.subject.to_s
I18n.backend.store_translations('en', :actionmailer => {:test_mailer => {:subject_with_i18n => {:subject => "New Subject!"}}})
assert_nothing_raised { TestMailer.deliver_subject_with_i18n(@recipient) }
assert_equal "New Subject!", ActionMailer::Base.deliveries.last.subject.to_s
end
def test_custom_template
expected = new_mail
expected.to = @recipient

View File

@@ -1,3 +1,5 @@
require 'active_support/core_ext/object/try'
module ActionView
module Rendering
# Returns the result of a render that's dictated by the options hash. The primary options are: