diff options
Diffstat (limited to 'actionmailer')
-rw-r--r-- | actionmailer/CHANGELOG.md | 15 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/base.rb | 15 | ||||
-rw-r--r-- | actionmailer/lib/action_mailer/preview.rb | 39 | ||||
-rw-r--r-- | actionmailer/test/base_test.rb | 45 |
4 files changed, 109 insertions, 5 deletions
diff --git a/actionmailer/CHANGELOG.md b/actionmailer/CHANGELOG.md index 1867a392eb..ede8cfccbf 100644 --- a/actionmailer/CHANGELOG.md +++ b/actionmailer/CHANGELOG.md @@ -1,3 +1,18 @@ +* Add the ability to intercept emails before previewing in a similar fashion + to how emails can be intercepted before delivery, e.g: + + class CSSInlineStyler + def self.previewing_email(message) + # inline CSS styles + end + end + + ActionMailer::Base.register_preview_interceptor CSSInlineStyler + + Fixes #13622. + + *Andrew White* + * Add mailer previews feature based on 37 Signals mail_view gem *Andrew White* diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 41db62cc58..5af0217973 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -330,6 +330,21 @@ module ActionMailer # An overview of all previews is accessible at <tt>http://localhost:3000/rails/mailers</tt> # on a running development server instance. # + # Previews can also be intercepted in a similar manner as deliveries can be by registering + # a preview interceptor that has a <tt>previewing_email</tt> method: + # + # class CssInlineStyler + # def self.previewing_email(message) + # # inline CSS styles + # end + # end + # + # config.action_mailer.register_preview_interceptor :css_inline_styler + # + # Note that interceptors need to be registered both with <tt>register_interceptor</tt> + # and <tt>register_preview_interceptor</tt> if they should operate on both sending and + # previewing emails. + # # = Configuration options # # These options are specified on the class level, like diff --git a/actionmailer/lib/action_mailer/preview.rb b/actionmailer/lib/action_mailer/preview.rb index ecceaf8c70..0efd702e4d 100644 --- a/actionmailer/lib/action_mailer/preview.rb +++ b/actionmailer/lib/action_mailer/preview.rb @@ -10,6 +10,31 @@ module ActionMailer # config.action_mailer.preview_path = "#{Rails.root}/lib/mailer_previews" # class_attribute :preview_path, instance_writer: false + + # :nodoc: + mattr_accessor :preview_interceptors, instance_writer: false + self.preview_interceptors = [] + + # Register one or more Interceptors which will be called before mail is previewed. + def register_preview_interceptors(*interceptors) + interceptors.flatten.compact.each { |interceptor| register_preview_interceptor(interceptor) } + end + + # Register am Interceptor which will be called before mail is previewed. + # Either a class or a string can be passed in as the Interceptor. If a + # string is passed in it will be <tt>constantize</tt>d. + def register_preview_interceptor(interceptor) + preview_interceptor = case interceptor + when String, Symbol + interceptor.to_s.camelize.constantize + else + interceptor + end + + unless preview_interceptors.include?(preview_interceptor) + preview_interceptors << preview_interceptor + end + end end end @@ -23,10 +48,14 @@ module ActionMailer descendants end - # Returns the mail object for the given email name + # Returns the mail object for the given email name. The registered preview + # interceptors will be informed so that they can transform the message + # as they would if the mail was actually being delivered. def call(email) preview = self.new - preview.public_send(email) + message = preview.public_send(email) + inform_preview_interceptors(message) + message end # Returns all of the available email previews @@ -68,6 +97,12 @@ module ActionMailer def preview_path? #:nodoc: Base.preview_path? end + + def inform_preview_interceptors(message) #:nodoc: + Base.preview_interceptors.each do |interceptor| + interceptor.previewing_email(message) + end + end end end end diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index c1759d9b92..454e1afe97 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -539,12 +539,18 @@ class BaseTest < ActiveSupport::TestCase end class MyInterceptor - def self.delivering_email(mail) - end + def self.delivering_email(mail); end + def self.previewing_email(mail); end end class MySecondInterceptor - def self.delivering_email(mail) + def self.delivering_email(mail); end + def self.previewing_email(mail); end + end + + class BaseMailerPreview < ActionMailer::Preview + def welcome + BaseMailer.welcome end end @@ -570,6 +576,39 @@ class BaseTest < ActiveSupport::TestCase mail.deliver end + test "you can register a preview interceptor to the mail object that gets passed the mail object before previewing" do + ActionMailer::Base.register_preview_interceptor(MyInterceptor) + mail = BaseMailer.welcome + BaseMailerPreview.stubs(:welcome).returns(mail) + MyInterceptor.expects(:previewing_email).with(mail) + BaseMailerPreview.call(:welcome) + end + + test "you can register a preview interceptor using its stringified name to the mail object that gets passed the mail object before previewing" do + ActionMailer::Base.register_preview_interceptor("BaseTest::MyInterceptor") + mail = BaseMailer.welcome + BaseMailerPreview.stubs(:welcome).returns(mail) + MyInterceptor.expects(:previewing_email).with(mail) + BaseMailerPreview.call(:welcome) + end + + test "you can register an interceptor using its symbolized underscored name to the mail object that gets passed the mail object before previewing" do + ActionMailer::Base.register_preview_interceptor(:"base_test/my_interceptor") + mail = BaseMailer.welcome + BaseMailerPreview.stubs(:welcome).returns(mail) + MyInterceptor.expects(:previewing_email).with(mail) + BaseMailerPreview.call(:welcome) + end + + test "you can register multiple preview interceptors to the mail object that both get passed the mail object before previewing" do + ActionMailer::Base.register_preview_interceptors("BaseTest::MyInterceptor", MySecondInterceptor) + mail = BaseMailer.welcome + BaseMailerPreview.stubs(:welcome).returns(mail) + MyInterceptor.expects(:previewing_email).with(mail) + MySecondInterceptor.expects(:previewing_email).with(mail) + BaseMailerPreview.call(:welcome) + end + test "being able to put proc's into the defaults hash and they get evaluated on mail sending" do mail1 = ProcMailer.welcome['X-Proc-Method'] yesterday = 1.day.ago |