diff options
Diffstat (limited to 'actionmailer')
7 files changed, 98 insertions, 13 deletions
diff --git a/actionmailer/CHANGELOG.md b/actionmailer/CHANGELOG.md index 5685871ac9..9fdda52f77 100644 --- a/actionmailer/CHANGELOG.md +++ b/actionmailer/CHANGELOG.md @@ -1,3 +1,17 @@ +* MailerGenerator now generates layouts by default. HTML mailer layout will + include `<html>` and `<body>` tags which will help to reduce spam score in + some spam detection engines. Mailers will now inherit from `ApplicationMailer` + which sets the default layout. + + *Andy Jeffries* + +* `link_to` and `url_for` generate URLs by default in templates, it is no + longer needed to pass `only_path: false`. + + Fixes #16497 and #16589. + + *Xavier Noria*, *Richard Schneeman* + * Attachments can be added while rendering the mail template. Fixes #16974. diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index a70bf1544a..23139bcbe8 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -15,11 +15,17 @@ module ActionMailer # # $ rails generate mailer Notifier # - # The generated model inherits from <tt>ActionMailer::Base</tt>. A mailer model defines methods + # The generated model inherits from <tt>ApplicationMailer</tt> which in turn + # inherits from <tt>ActionMailer::Base</tt>. A mailer model defines methods # used to generate an email message. In these methods, you can setup variables to be used in # the mailer views, options on the mail itself such as the <tt>:from</tt> address, and attachments. # - # class Notifier < ActionMailer::Base + # class ApplicationMailer < ActionMailer::Base + # default from: 'from@exmaple.com' + # layout 'mailer' + # end + # + # class Notifier < ApplicationMailer # default from: 'no-reply@example.com', # return_path: 'system@example.com' # @@ -84,7 +90,7 @@ module ActionMailer # name as the method in your mailer model. For example, in the mailer defined above, the template at # <tt>app/views/notifier/welcome.text.erb</tt> would be used to generate the email. # - # Variables defined in the methods of your mailer model are accessible as instance variables in their + # Variables defined in the methods of your mailer model are accessible as instance variables in their # corresponding view. # # Emails by default are sent in plain text, so a sample view for our model example might look like this: @@ -178,7 +184,7 @@ module ActionMailer # # Sending attachment in emails is easy: # - # class ApplicationMailer < ActionMailer::Base + # class Notifier < ApplicationMailer # def welcome(recipient) # attachments['free_book.pdf'] = File.read('path/to/file.pdf') # mail(to: recipient, subject: "New account information") @@ -194,7 +200,7 @@ module ActionMailer # If you need to send attachments with no content, you need to create an empty view for it, # or add an empty body parameter like this: # - # class ApplicationMailer < ActionMailer::Base + # class Notifier < ApplicationMailer # def welcome(recipient) # attachments['free_book.pdf'] = File.read('path/to/file.pdf') # mail(to: recipient, subject: "New account information", body: "") @@ -206,7 +212,7 @@ module ActionMailer # You can also specify that a file should be displayed inline with other HTML. This is useful # if you want to display a corporate logo or a photo. # - # class ApplicationMailer < ActionMailer::Base + # class Notifier < ApplicationMailer # def welcome(recipient) # attachments.inline['photo.png'] = File.read('path/to/photo.png') # mail(to: recipient, subject: "Here is what we look like") @@ -245,7 +251,7 @@ module ActionMailer # Action Mailer provides some intelligent defaults for your emails, these are usually specified in a # default method inside the class definition: # - # class Notifier < ActionMailer::Base + # class Notifier < ApplicationMailer # default sender: 'system@example.com' # end # @@ -263,7 +269,7 @@ module ActionMailer # As you can pass in any header, you need to either quote the header as a string, or pass it in as # an underscored symbol, so the following will work: # - # class Notifier < ActionMailer::Base + # class Notifier < ApplicationMailer # default 'Content-Transfer-Encoding' => '7bit', # content_description: 'This is a description' # end @@ -271,7 +277,7 @@ module ActionMailer # Finally, Action Mailer also supports passing <tt>Proc</tt> objects into the default hash, so you # can define methods that evaluate as the message is being generated: # - # class Notifier < ActionMailer::Base + # class Notifier < ApplicationMailer # default 'X-Special-Header' => Proc.new { my_method } # # private @@ -296,7 +302,7 @@ module ActionMailer # This may be useful, for example, when you want to add default inline attachments for all # messages sent out by a certain mailer class: # - # class Notifier < ActionMailer::Base + # class Notifier < ApplicationMailer # before_action :add_inline_attachment! # # def welcome @@ -703,7 +709,7 @@ module ActionMailer # The main method that creates the message and renders the email templates. There are # two ways to call this method, with a block, or without a block. # - # It accepts a headers hash. This hash allows you to specify + # It accepts a headers hash. This hash allows you to specify # the most used headers in an email message, these are: # # * +:subject+ - The subject of the message, if this is omitted, Action Mailer will diff --git a/actionmailer/lib/rails/generators/mailer/mailer_generator.rb b/actionmailer/lib/rails/generators/mailer/mailer_generator.rb index d5bf864595..094ec85114 100644 --- a/actionmailer/lib/rails/generators/mailer/mailer_generator.rb +++ b/actionmailer/lib/rails/generators/mailer/mailer_generator.rb @@ -8,6 +8,7 @@ module Rails def create_mailer_file template "mailer.rb", File.join('app/mailers', class_path, "#{file_name}.rb") + template "application_mailer.rb", 'app/mailers/application_mailer.rb' end hook_for :template_engine, :test_framework diff --git a/actionmailer/lib/rails/generators/mailer/templates/application_mailer.rb b/actionmailer/lib/rails/generators/mailer/templates/application_mailer.rb new file mode 100644 index 0000000000..d25d8892dd --- /dev/null +++ b/actionmailer/lib/rails/generators/mailer/templates/application_mailer.rb @@ -0,0 +1,4 @@ +class ApplicationMailer < ActionMailer::Base + default from: "from@example.com" + layout 'mailer' +end diff --git a/actionmailer/lib/rails/generators/mailer/templates/mailer.rb b/actionmailer/lib/rails/generators/mailer/templates/mailer.rb index edcfb4233d..bce64a5e6e 100644 --- a/actionmailer/lib/rails/generators/mailer/templates/mailer.rb +++ b/actionmailer/lib/rails/generators/mailer/templates/mailer.rb @@ -1,6 +1,5 @@ <% module_namespacing do -%> -class <%= class_name %> < ActionMailer::Base - default from: "from@example.com" +class <%= class_name %> < ApplicationMailer <% actions.each do |action| -%> # Subject can be set in your I18n file at config/locales/en.yml diff --git a/actionmailer/test/fixtures/url_test_mailer/exercise_url_for.erb b/actionmailer/test/fixtures/url_test_mailer/exercise_url_for.erb new file mode 100644 index 0000000000..0322c1191e --- /dev/null +++ b/actionmailer/test/fixtures/url_test_mailer/exercise_url_for.erb @@ -0,0 +1 @@ +<%= url_for(@options) %> <%= @url %> diff --git a/actionmailer/test/url_test.rb b/actionmailer/test/url_test.rb index be7532d42f..7928fe9542 100644 --- a/actionmailer/test/url_test.rb +++ b/actionmailer/test/url_test.rb @@ -23,9 +23,32 @@ class UrlTestMailer < ActionMailer::Base mail(to: recipient, subject: "[Signed up] Welcome #{recipient}", from: "system@loudthinking.com", date: Time.local(2004, 12, 12)) end + + def exercise_url_for(options) + @options = options + @url = url_for(@options) + mail(from: 'from@example.com', to: 'to@example.com', subject: 'subject') + end end class ActionMailerUrlTest < ActionMailer::TestCase + class DummyModel + def self.model_name + OpenStruct.new(route_key: 'dummy_model') + end + + def persisted? + false + end + + def model_name + self.class.model_name + end + + def to_model + self + end + end def encode( text, charset="UTF-8" ) quoted_printable( text, charset ) @@ -40,10 +63,47 @@ class ActionMailerUrlTest < ActionMailer::TestCase mail end + def assert_url_for(expected, options, relative = false) + expected = "http://www.basecamphq.com#{expected}" if expected.start_with?('/') && !relative + urls = UrlTestMailer.exercise_url_for(options).body.to_s.chomp.split + + assert_equal expected, urls.first + assert_equal expected, urls.second + end + def setup @recipient = 'test@localhost' end + def test_url_for + UrlTestMailer.delivery_method = :test + + AppRoutes.draw do + get ':controller(/:action(/:id))' + get '/welcome' => 'foo#bar', as: 'welcome' + get '/dummy_model' => 'foo#baz', as: 'dummy_model' + end + + # string + assert_url_for 'http://foo/', 'http://foo/' + + # symbol + assert_url_for '/welcome', :welcome + + # hash + assert_url_for '/a/b/c', controller: 'a', action: 'b', id: 'c' + assert_url_for '/a/b/c', {controller: 'a', action: 'b', id: 'c', only_path: true}, true + + # model + assert_url_for '/dummy_model', DummyModel.new + + # class + assert_url_for '/dummy_model', DummyModel + + # array + assert_url_for '/dummy_model' , [DummyModel] + end + def test_signed_up_with_url UrlTestMailer.delivery_method = :test |