Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Revert "Revert "Add layout functionality to mailers.""

This reverts commit 36c6aa0.
  • Loading branch information...
commit 6228220c9b8a3bb32f8617ad2d963dabc965376e 1 parent 36c6aa0
@dhh dhh authored
View
5 actionmailer/CHANGELOG
@@ -1,3 +1,8 @@
+* Add layout functionality to mailers [Pratik]
+
+ Mailer layouts behaves just like controller layouts, except layout names need to
+ have '_mailer' postfix for them to be automatically picked up.
+
*2.1.0 (May 31st, 2008)*
* Fixed that a return-path header would be ignored #7572 [joost]
View
24 actionmailer/lib/action_mailer/base.rb
@@ -246,7 +246,10 @@ module ActionMailer #:nodoc:
# +implicit_parts_order+.
class Base
include AdvAttrAccessor, PartContainer
- include ActionController::UrlWriter if Object.const_defined?(:ActionController)
+ if Object.const_defined?(:ActionController)
+ include ActionController::UrlWriter
+ include ActionController::Layout
+ end
private_class_method :new #:nodoc:
@@ -362,6 +365,7 @@ def mailer_name=(value)
# The mail object instance referenced by this mailer.
attr_reader :mail
+ attr_reader :template_name, :default_template_name, :action_name
class << self
attr_writer :mailer_name
@@ -530,6 +534,7 @@ def initialize_defaults(method_name)
@content_type ||= @@default_content_type.dup
@implicit_parts_order ||= @@default_implicit_parts_order.dup
@template ||= method_name
+ @default_template_name = @action_name = @template
@mailer_name ||= self.class.name.underscore
@parts ||= []
@headers ||= {}
@@ -546,7 +551,22 @@ def render(opts)
if opts[:file] && (opts[:file] !~ /\// && !opts[:file].respond_to?(:render))
opts[:file] = "#{mailer_name}/#{opts[:file]}"
end
- initialize_template_class(body).render(opts)
+
+ begin
+ old_template, @template = @template, initialize_template_class(body)
+ layout = respond_to?(:pick_layout, true) ? pick_layout(opts) : false
+ @template.render(opts.merge(:layout => layout))
+ ensure
+ @template = old_template
+ end
+ end
+
+ def default_template_format
+ :html
+ end
+
+ def candidate_for_layout?(options)
+ !@template.send(:_exempt_from_layout?, default_template_name)
end
def template_root
View
1  actionmailer/test/fixtures/auto_layout_mailer/hello.html.erb
@@ -0,0 +1 @@
+Inside
View
1  actionmailer/test/fixtures/explicit_layout_mailer/logout.html.erb
@@ -0,0 +1 @@
+You logged out
View
1  actionmailer/test/fixtures/explicit_layout_mailer/signup.html.erb
@@ -0,0 +1 @@
+We do not spam
View
1  actionmailer/test/fixtures/layouts/auto_layout_mailer.html.erb
@@ -0,0 +1 @@
+Hello from layout <%= yield %>
View
1  actionmailer/test/fixtures/layouts/spam.html.erb
@@ -0,0 +1 @@
+Spammer layout <%= yield %>
View
78 actionmailer/test/mail_layout_test.rb
@@ -0,0 +1,78 @@
+require 'abstract_unit'
+
+class AutoLayoutMailer < ActionMailer::Base
+ def hello(recipient)
+ recipients recipient
+ subject "You have a mail"
+ from "tester@example.com"
+ end
+
+ def spam(recipient)
+ recipients recipient
+ subject "You have a mail"
+ from "tester@example.com"
+ body render(:inline => "Hello, <%= @world %>", :layout => 'spam', :body => { :world => "Earth" })
+ end
+
+ def nolayout(recipient)
+ recipients recipient
+ subject "You have a mail"
+ from "tester@example.com"
+ body render(:inline => "Hello, <%= @world %>", :layout => false, :body => { :world => "Earth" })
+ end
+end
+
+class ExplicitLayoutMailer < ActionMailer::Base
+ layout 'spam', :except => [:logout]
+
+ def signup(recipient)
+ recipients recipient
+ subject "You have a mail"
+ from "tester@example.com"
+ end
+
+ def logout(recipient)
+ recipients recipient
+ subject "You have a mail"
+ from "tester@example.com"
+ end
+end
+
+class LayoutMailerTest < Test::Unit::TestCase
+ def setup
+ set_delivery_method :test
+ ActionMailer::Base.perform_deliveries = true
+ ActionMailer::Base.deliveries = []
+
+ @recipient = 'test@localhost'
+ end
+
+ def teardown
+ restore_delivery_method
+ end
+
+ def test_should_pickup_default_layout
+ mail = AutoLayoutMailer.create_hello(@recipient)
+ assert_equal "Hello from layout Inside", mail.body.strip
+ end
+
+ def test_should_pickup_layout_given_to_render
+ mail = AutoLayoutMailer.create_spam(@recipient)
+ assert_equal "Spammer layout Hello, Earth", mail.body.strip
+ end
+
+ def test_should_respect_layout_false
+ mail = AutoLayoutMailer.create_nolayout(@recipient)
+ assert_equal "Hello, Earth", mail.body.strip
+ end
+
+ def test_explicit_class_layout
+ mail = ExplicitLayoutMailer.create_signup(@recipient)
+ assert_equal "Spammer layout We do not spam", mail.body.strip
+ end
+
+ def test_explicit_layout_exceptions
+ mail = ExplicitLayoutMailer.create_logout(@recipient)
+ assert_equal "You logged out", mail.body.strip
+ end
+end
View
6 actionpack/lib/action_controller/layout.rb
@@ -216,7 +216,7 @@ def default_layout_with_format(format, layout)
# object). If the layout was defined without a directory, layouts is assumed. So <tt>layout "weblog/standard"</tt> will return
# weblog/standard, but <tt>layout "standard"</tt> will return layouts/standard.
def active_layout(passed_layout = nil)
- layout = passed_layout || self.class.default_layout(response.template.template_format)
+ layout = passed_layout || self.class.default_layout(default_template_format)
active_layout = case layout
when String then layout
when Symbol then __send__(layout)
@@ -276,5 +276,9 @@ def layout_directory?(layout_name)
rescue ActionView::MissingTemplate
false
end
+
+ def default_template_format
+ response.template.template_format
+ end
end
end

1 comment on commit 6228220

@fesplugas

Back … ;)

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