mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Added initial documentation for the new API
This commit is contained in:
parent
9cb3ca1d29
commit
4a6eba3232
3 changed files with 201 additions and 118 deletions
|
@ -1,5 +1,7 @@
|
|||
*Rails 3.0 (pending)*
|
||||
|
||||
* Whole new API added with tests. See base.rb for full details. Old API is deprecated.
|
||||
|
||||
* The Mail::Message class has helped methods for all the field types that return 'common' defaults for the common use case, so to get the subject, mail.subject will give you a string, mail.date will give you a DateTime object, mail.from will give you an array of address specs (mikel@test.lindsaar.net) etc. If you want to access the field object itself, call mail[:field_name] which will return the field object you want, which you can then chain, like mail[:from].formatted
|
||||
|
||||
* Mail#content_type now returns the content_type field as a string. If you want the mime type of a mail, then you call Mail#mime_type (eg, text/plain), if you want the parameters of the content type field, you call Mail#content_type_parameters which gives you a hash, eg {'format' => 'flowed', 'charset' => 'utf-8'}
|
||||
|
|
|
@ -5,51 +5,74 @@ are used to consolidate code for sending out forgotten passwords, welcome
|
|||
wishes on signup, invoices for billing, and any other use case that requires
|
||||
a written notification to either a person or another system.
|
||||
|
||||
Action Mailer is in essence a wrapper around Action Controller and the
|
||||
Mail gem. It provides a way to make emails using templates in the same
|
||||
way that Action Controller renders views using templates.
|
||||
|
||||
Additionally, an Action Mailer class can be used to process incoming email,
|
||||
such as allowing a weblog to accept new posts from an email (which could even
|
||||
have been sent from a phone).
|
||||
|
||||
== Sending emails
|
||||
|
||||
The framework works by setting up all the email details, except the body,
|
||||
in methods on the service layer. Subject, recipients, sender, and timestamp
|
||||
are all set up this way. An example of such a method:
|
||||
The framework works by initializing any instance variables you want to be
|
||||
available in the email template, followed by a call to +mail+ to deliver
|
||||
the email.
|
||||
|
||||
This can be as simple as:
|
||||
|
||||
class Notifier < ActionMailer::Base
|
||||
|
||||
delivers_from 'system@loudthinking.com'
|
||||
|
||||
def welcome(recipient)
|
||||
@recipient = recipient
|
||||
mail(:to => recipient,
|
||||
:subject => "[Signed up] Welcome #{recipient}")
|
||||
end
|
||||
|
||||
def signed_up(recipient)
|
||||
recipients recipient
|
||||
subject "[Signed up] Welcome #{recipient}"
|
||||
from "system@loudthinking.com"
|
||||
body :recipient => recipient
|
||||
end
|
||||
|
||||
The body of the email is created by using an Action View template (regular
|
||||
ERb) that has the content of the body hash parameter available as instance variables.
|
||||
ERb) that has the instance variables that are declared in the mailer action.
|
||||
|
||||
So the corresponding body template for the method above could look like this:
|
||||
|
||||
Hello there,
|
||||
|
||||
Mr. <%= @recipient %>
|
||||
|
||||
Thank you for signing up!
|
||||
|
||||
And if the recipient was given as "david@loudthinking.com", the email
|
||||
generated would look like this:
|
||||
|
||||
Date: Sun, 12 Dec 2004 00:00:00 +0100
|
||||
Date: Mon, 25 Jan 2010 22:48:09 +1100
|
||||
From: system@loudthinking.com
|
||||
To: david@loudthinking.com
|
||||
Message-ID: <4b5d84f9dd6a5_7380800b81ac29578@void.loudthinking.com.mail>
|
||||
Subject: [Signed up] Welcome david@loudthinking.com
|
||||
Mime-Version: 1.0
|
||||
Content-Type: text/plain;
|
||||
charset="US-ASCII";
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
Hello there,
|
||||
|
||||
Mr. david@loudthinking.com
|
||||
|
||||
You never actually call the instance methods like signed_up directly. Instead,
|
||||
you call class methods like deliver_* and create_* that are automatically
|
||||
created for each instance method. So if the signed_up method sat on
|
||||
ApplicationMailer, it would look like this:
|
||||
In previous version of rails you would call <tt>create_method_name</tt> and
|
||||
<tt>deliver_method_name</tt>. Rails 3.0 has a much simpler interface, you
|
||||
simply call the method and optionally call +deliver+ on the return value.
|
||||
|
||||
ApplicationMailer.create_signed_up("david@loudthinking.com") # => tmail object for testing
|
||||
ApplicationMailer.deliver_signed_up("david@loudthinking.com") # sends the email
|
||||
ApplicationMailer.new.signed_up("david@loudthinking.com") # won't work!
|
||||
Calling the method returns a Mail Message object:
|
||||
|
||||
message = Notifier.welcome #=> Returns a Mail::Message object
|
||||
message.deliver #=> delivers the email
|
||||
|
||||
Or you can just chain the methods together like:
|
||||
|
||||
Notifier.welcome.deliver # Creates the email and sends it immediately
|
||||
|
||||
== Receiving emails
|
||||
|
||||
|
@ -103,16 +126,13 @@ The Base class has the full list of configuration options. Here's an example:
|
|||
Action Mailer requires that the Action Pack is either available to be required immediately
|
||||
or is accessible as a GEM.
|
||||
|
||||
Additionally, Action Mailer requires the Mail gem, http://github.com/mikel/mail
|
||||
|
||||
== Bundled software
|
||||
|
||||
* tmail 0.10.8 by Minero Aoki released under LGPL
|
||||
Read more on http://i.loveruby.net/en/prog/tmail.html
|
||||
|
||||
* Text::Format 0.63 by Austin Ziegler released under OpenSource
|
||||
Read more on http://www.halostatue.ca/ruby/Text__Format.html
|
||||
|
||||
|
||||
== Download
|
||||
|
||||
The latest version of Action Mailer can be found at
|
||||
|
|
|
@ -16,46 +16,57 @@ module ActionMailer #:nodoc:
|
|||
#
|
||||
# $ script/generate mailer Notifier
|
||||
#
|
||||
# The generated model inherits from ActionMailer::Base. Emails are defined by creating methods within the model which are then
|
||||
# used to set variables to be used in the mail template, to change options on the mail, or
|
||||
# to add attachments.
|
||||
# The generated model inherits from ActionMailer::Base. Emails are defined by creating methods
|
||||
# within the model which are then used to set variables to be used in the mail template, to
|
||||
# change options on the mail, or to add attachments.
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# class Notifier < ActionMailer::Base
|
||||
# def signup_notification(recipient)
|
||||
# recipients recipient.email_address_with_name
|
||||
# bcc ["bcc@example.com", "Order Watcher <watcher@example.com>"]
|
||||
# from "system@example.com"
|
||||
# subject "New account information"
|
||||
# body :account => recipient
|
||||
# delivers_from 'system@example.com'
|
||||
#
|
||||
# def welcome(recipient)
|
||||
# @account = recipient
|
||||
# mail { :to => recipient.email_address_with_name,
|
||||
# :bcc => ["bcc@example.com", "Order Watcher <watcher@example.com>"],
|
||||
# :subject => "New account information" }
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# Mailer methods have the following configuration methods available.
|
||||
# Within the mailer method, you have access to the following methods:
|
||||
#
|
||||
# * <tt>recipients</tt> - Takes one or more email addresses. These addresses are where your email will be delivered to. Sets the <tt>To:</tt> header.
|
||||
# * <tt>subject</tt> - The subject of your email. Sets the <tt>Subject:</tt> header.
|
||||
# * <tt>from</tt> - Who the email you are sending is from. Sets the <tt>From:</tt> header.
|
||||
# * <tt>cc</tt> - Takes one or more email addresses. These addresses will receive a carbon copy of your email. Sets the <tt>Cc:</tt> header.
|
||||
# * <tt>bcc</tt> - Takes one or more email addresses. These addresses will receive a blind carbon copy of your email. Sets the <tt>Bcc:</tt> header.
|
||||
# * <tt>reply_to</tt> - Takes one or more email addresses. These addresses will be listed as the default recipients when replying to your email. Sets the <tt>Reply-To:</tt> header.
|
||||
# * <tt>sent_on</tt> - The date on which the message was sent. If not set, the header will be set by the delivery agent.
|
||||
# * <tt>content_type</tt> - Specify the content type of the message. Defaults to <tt>text/plain</tt>.
|
||||
# * <tt>headers</tt> - Specify additional headers to be set for the message, e.g. <tt>headers 'X-Mail-Count' => 107370</tt>.
|
||||
# * <tt>attachments[]=</tt> - Allows you to add attachments to your email in an intuitive
|
||||
# manner; <tt>attachments['filename.png'] = File.read('path/to/filename.png')</tt>
|
||||
# * <tt>headers[]=</tt> - Allows you to specify non standard headers in your email such
|
||||
# as <tt>headers['X-No-Spam'] = 'True'</tt>
|
||||
# * <tt>mail</tt> - Allows you to specify your email to send.
|
||||
#
|
||||
# When a <tt>headers 'return-path'</tt> is specified, that value will be used as the 'envelope from'
|
||||
# address. Setting this is useful when you want delivery notifications sent to a different address than
|
||||
# the one in <tt>from</tt>.
|
||||
# The hash passed to the mail method allows you to specify the most used headers in an email
|
||||
# message, such as <tt>Subject</tt>, <tt>To</tt>, <tt>From</tt>, <tt>Cc</tt>, <tt>Bcc</tt>,
|
||||
# <tt>Reply-To</tt> and <tt>Date</tt>. See the <tt>ActionMailer#mail</tt> method for more details.
|
||||
#
|
||||
# If you need other headers not listed above, use the <tt>headers['name'] = value</tt> method.
|
||||
#
|
||||
# The mail method, if not passed a block, will inspect your views and send all the views with
|
||||
# the same name as the method, so the above action would send the +welcome.plain.erb+ view file
|
||||
# as well as the +welcome.html.erb+ view file in a +multipart/alternate+ email.
|
||||
#
|
||||
# If you want to explicitly render only certain templates, pass a block:
|
||||
#
|
||||
# mail(:to => user.emai) do |format|
|
||||
# format.text
|
||||
# format.enriched, {:content_type => 'text/rtf'}
|
||||
# format.html
|
||||
# end
|
||||
#
|
||||
# = Mailer views
|
||||
#
|
||||
# Like Action Controller, each mailer class has a corresponding view directory
|
||||
# in which each method of the class looks for a template with its name.
|
||||
# To define a template to be used with a mailing, create an <tt>.erb</tt> file with the same name as the method
|
||||
# in your mailer model. For example, in the mailer defined above, the template at
|
||||
# <tt>app/views/notifier/signup_notification.erb</tt> would be used to generate the email.
|
||||
# Like Action Controller, each mailer class has a corresponding view directory in which each
|
||||
# method of the class looks for a template with its name.
|
||||
#
|
||||
# To define a template to be used with a mailing, create an <tt>.erb</tt> file with the same
|
||||
# name as the method in your mailer model. For example, in the mailer defined above, the template at
|
||||
# <tt>app/views/notifier/signup_notification.text.erb</tt> would be used to generate the email.
|
||||
#
|
||||
# Variables defined in the model are accessible as instance variables in the view.
|
||||
#
|
||||
|
@ -111,54 +122,13 @@ module ActionMailer #:nodoc:
|
|||
# Once a mailer action and template are defined, you can deliver your message or create it and save it
|
||||
# for delivery later:
|
||||
#
|
||||
# Notifier.deliver_signup_notification(david) # sends the email
|
||||
# mail = Notifier.create_signup_notification(david) # => a tmail object
|
||||
# Notifier.deliver(mail)
|
||||
# Notifier.welcome(david).deliver # sends the email
|
||||
# mail = Notifier.welcome(david) # => a Mail::Message object
|
||||
# mail.deliver # sends the email
|
||||
#
|
||||
# You never instantiate your mailer class. Rather, your delivery instance
|
||||
# methods are automatically wrapped in class methods that start with the word
|
||||
# <tt>deliver_</tt> followed by the name of the mailer method that you would
|
||||
# like to deliver. The <tt>signup_notification</tt> method defined above is
|
||||
# delivered by invoking <tt>Notifier.deliver_signup_notification</tt>.
|
||||
# You never instantiate your mailer class. Rather, you just call the method on the class itself.
|
||||
#
|
||||
#
|
||||
# = HTML email
|
||||
#
|
||||
# To send mail as HTML, make sure your view (the <tt>.erb</tt> file) generates HTML and
|
||||
# set the content type to html.
|
||||
#
|
||||
# class MyMailer < ActionMailer::Base
|
||||
# def signup_notification(recipient)
|
||||
# recipients recipient.email_address_with_name
|
||||
# subject "New account information"
|
||||
# from "system@example.com"
|
||||
# body :account => recipient
|
||||
# content_type "text/html"
|
||||
# end
|
||||
# end
|
||||
#
|
||||
#
|
||||
# = Multipart email
|
||||
#
|
||||
# You can explicitly specify multipart messages:
|
||||
#
|
||||
# class ApplicationMailer < ActionMailer::Base
|
||||
# def signup_notification(recipient)
|
||||
# recipients recipient.email_address_with_name
|
||||
# subject "New account information"
|
||||
# from "system@example.com"
|
||||
# content_type "multipart/alternative"
|
||||
# body :account => recipient
|
||||
#
|
||||
# part :content_type => "text/html",
|
||||
# :data => render_message("signup-as-html")
|
||||
#
|
||||
# part "text/plain" do |p|
|
||||
# p.body = render_message("signup-as-plain")
|
||||
# p.content_transfer_encoding = "base64"
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
# = Multipart Emails
|
||||
#
|
||||
# Multipart messages can also be used implicitly because Action Mailer will automatically
|
||||
# detect and use multipart templates, where each template is named after the name of the action, followed
|
||||
|
@ -170,11 +140,10 @@ module ActionMailer #:nodoc:
|
|||
# * signup_notification.text.xml.builder
|
||||
# * signup_notification.text.x-yaml.erb
|
||||
#
|
||||
# Each would be rendered and added as a separate part to the message,
|
||||
# with the corresponding content type. The content type for the entire
|
||||
# message is automatically set to <tt>multipart/alternative</tt>, which indicates
|
||||
# that the email contains multiple different representations of the same email
|
||||
# body. The same body hash is passed to each template.
|
||||
# Each would be rendered and added as a separate part to the message, with the corresponding content
|
||||
# type. The content type for the entire message is automatically set to <tt>multipart/alternative</tt>,
|
||||
# which indicates that the email contains multiple different representations of the same email
|
||||
# body. The same instance variables defined in the action are passed to all email templates.
|
||||
#
|
||||
# Implicit template rendering is not performed if any attachments or parts have been added to the email.
|
||||
# This means that you'll have to manually add each part to the email and set the content type of the email
|
||||
|
@ -182,31 +151,31 @@ module ActionMailer #:nodoc:
|
|||
#
|
||||
# = Attachments
|
||||
#
|
||||
# Attachments can be added by using the +attachment+ method.
|
||||
#
|
||||
# Example:
|
||||
# You can see above how to make a multipart HTML / Text email, to send attachments is just
|
||||
# as easy:
|
||||
#
|
||||
# class ApplicationMailer < ActionMailer::Base
|
||||
# # attachments
|
||||
# def signup_notification(recipient)
|
||||
# recipients recipient.email_address_with_name
|
||||
# subject "New account information"
|
||||
# from "system@example.com"
|
||||
# def welcome(recipient)
|
||||
# attachments['free_book.pdf'] = { :data => File.read('path/to/file.pdf') }
|
||||
# mail(:to => recipient, :subject => "New account information")
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# attachment :content_type => "image/jpeg",
|
||||
# :body => File.read("an-image.jpg")
|
||||
#
|
||||
# attachment "application/pdf" do |a|
|
||||
# a.body = generate_your_pdf_here()
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
# Which will (if it had both a <tt>.text.erb</tt> and <tt>.html.erb</tt> tempalte in the view
|
||||
# directory), send a complete <tt>multipart/mixed</tt> email with two parts, the first part being
|
||||
# a <tt>multipart/alternate</tt> with the text and HTML email parts inside, and the second being
|
||||
# a <tt>application/pdf</tt> with a Base64 encoded copy of the file.pdf book with the filename
|
||||
# +free_book.pdf+.
|
||||
#
|
||||
#
|
||||
# = Configuration options
|
||||
#
|
||||
# These options are specified on the class level, like <tt>ActionMailer::Base.template_root = "/my/templates"</tt>
|
||||
#
|
||||
# * <tt>delivers_from</tt> - Pass this the address that then defaults as the +from+ address on all the
|
||||
# emails sent. Can be overridden on a per mail basis by passing <tt>:from => 'another@address'</tt> in
|
||||
# the +mail+ method.
|
||||
#
|
||||
# * <tt>template_root</tt> - Determines the base from which template references will be made.
|
||||
#
|
||||
# * <tt>logger</tt> - the logger is used for generating information on the mailing run if available.
|
||||
|
@ -326,6 +295,9 @@ module ActionMailer #:nodoc:
|
|||
end
|
||||
end
|
||||
|
||||
# Delivers a mail object. This is actually called by the <tt>Mail::Message</tt> object
|
||||
# itself through a call back when you call <tt>:deliver</tt> on the Mail::Message,
|
||||
# calling +deliver_mail+ directly and passing an Mail::Message will do nothing.
|
||||
def deliver_mail(mail) #:nodoc:
|
||||
ActiveSupport::Notifications.instrument("action_mailer.deliver") do |payload|
|
||||
self.set_payload_for_mail(payload, mail)
|
||||
|
@ -374,6 +346,14 @@ module ActionMailer #:nodoc:
|
|||
process(method_name, *args) if method_name
|
||||
end
|
||||
|
||||
# Allows you to pass random and unusual headers to the new +Mail::Message+ object
|
||||
# which will add them to itself.
|
||||
#
|
||||
# headers['X-Special-Domain-Specific-Header'] = "SecretValue"
|
||||
#
|
||||
# The resulting Mail::Message will have the following in it's header:
|
||||
#
|
||||
# X-Special-Domain-Specific-Header: SecretValue
|
||||
def headers(args=nil)
|
||||
if args
|
||||
ActiveSupport::Deprecation.warn "headers(Hash) is deprecated, please do headers[key] = value instead", caller[0,2]
|
||||
|
@ -383,10 +363,91 @@ module ActionMailer #:nodoc:
|
|||
end
|
||||
end
|
||||
|
||||
# Allows you to add attachments to an email, like so:
|
||||
#
|
||||
# mail.attachments['filename.jpg'] = File.read('/path/to/filename.jpg')
|
||||
#
|
||||
# If you do this, then Mail will take the file name and work out the mime type
|
||||
# set the Content-Type, Content-Disposition, Content-Transfer-Encoding and
|
||||
# base64 encode the contents of the attachment all for you.
|
||||
#
|
||||
# You can also specify overrides if you want by passing a hash instead of a string:
|
||||
#
|
||||
# mail.attachments['filename.jpg'] = {:mime_type => 'application/x-gzip',
|
||||
# :content => File.read('/path/to/filename.jpg')}
|
||||
#
|
||||
# If you want to use a different encoding than Base64, you can pass an encoding in,
|
||||
# but then it is up to you to pass in the content pre-encoded, and don't expect
|
||||
# Mail to know how to decode this data:
|
||||
#
|
||||
# file_content = SpecialEncode(File.read('/path/to/filename.jpg'))
|
||||
# mail.attachments['filename.jpg'] = {:mime_type => 'application/x-gzip',
|
||||
# :encoding => 'SpecialEncoding',
|
||||
# :content => file_content }
|
||||
#
|
||||
# You can also search for specific attachments:
|
||||
#
|
||||
# # By Filename
|
||||
# mail.attachments['filename.jpg'] #=> Mail::Part object or nil
|
||||
#
|
||||
# # or by index
|
||||
# mail.attachments[0] #=> Mail::Part (first attachment)
|
||||
#
|
||||
def attachments
|
||||
@_message.attachments
|
||||
end
|
||||
|
||||
# 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.
|
||||
#
|
||||
# Both methods accept a headers hash. This hash allows you to specify the most used headers
|
||||
# in an email message, these are:
|
||||
#
|
||||
# * <tt>:subject</tt> - The subject of the message, if this is omitted, ActionMailer will
|
||||
# ask the Rails I18n class for a translated <tt>:subject</tt> in the scope of
|
||||
# <tt>[:actionmailer, mailer_scope, action_name]</tt> or if this is missing, will translate the
|
||||
# humanized version of the <tt>action_name</tt>
|
||||
# * <tt>:to</tt> - Who the message is destined for, can be a string of addresses, or an array
|
||||
# of addresses.
|
||||
# * <tt>:from</tt> - Who the message is from, if missing, will use the <tt>:delivers_from</tt>
|
||||
# value in the class (if it exists)
|
||||
# * <tt>:cc</tt> - Who you would like to Carbon-Copy on this email, can be a string of addresses,
|
||||
# or an array of addresses.
|
||||
# * <tt>:bcc</tt> - Who you would like to Blind-Carbon-Copy on this email, can be a string of
|
||||
# addresses, or an array of addresses.
|
||||
# * <tt>:reply_to</tt> - Who to set the Reply-To header of the email to.
|
||||
# * <tt>:date</tt> - The date to say the email was sent on.
|
||||
#
|
||||
# If you need other headers not listed above, use the <tt>headers['name'] = value</tt> method.
|
||||
#
|
||||
# When a <tt>:return_path</tt> is specified, that value will be used as the 'envelope from'
|
||||
# address for the Mail message. Setting this is useful when you want delivery notifications
|
||||
# sent to a different address than the one in <tt>:from</tt>. Mail will actually use the
|
||||
# <tt>:return_path</tt> in preference to the <tt>:sender</tt> in preference to the <tt>:from</tt>
|
||||
# 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.
|
||||
#
|
||||
# If you do pass a block, you can render specific templates of your choice:
|
||||
#
|
||||
# mail(:to => 'mikel@test.lindsaar.net') do |format|
|
||||
# format.text
|
||||
# format.html
|
||||
# end
|
||||
#
|
||||
# You can even render text directly without using a template:
|
||||
#
|
||||
# mail(:to => 'mikel@test.lindsaar.net') do |format|
|
||||
# format.text { render :text => "Hello Mikel!" }
|
||||
# format.html { render :text => "<h1>Hello Mikel!</h1>" }
|
||||
# end
|
||||
#
|
||||
# Which will render a <tt>multipart/alternate</tt> email with <tt>text/plain</tt> and
|
||||
# <tt>text/html</tt> parts.
|
||||
def mail(headers={}, &block)
|
||||
# Guard flag to prevent both the old and the new API from firing
|
||||
# Should be removed when old API is removed
|
||||
|
|
Loading…
Reference in a new issue