Originally published on https://ali-ilman.com/blog/specifying-a-template-and-a-layout-through-action-mailer-mail-function.
Photo by Mikaela Wiedenhoff.
In this article, we'll take a look at one of the lesser-known features within Action Mailer, that is specifying a template and a layout through the mail function. This can come in handy if we want to display specific content for certain emails without creating unnecessary mailers. 🧠
Specifying a template
There are a few ways to specify a template through the mail function. The mail function accepts keyword arguments called template_path and template_name.
template_path
template_path is for telling Action Mailer which folder to use to look for a template. template_path can either be a string or an array.
Action Mailer will start looking for the specified template_path from within app/views folder. Let's say, our template_path is set to invitations. Then, Action Mailer will look for app/views/invitations folder.
template_name
template_name is for telling Action Mailer the name of the template that we want to use.
Examples
The first example here shows how we can use a template called welcome that sits inside of app/views/mailers/user_mailer/special folder. The template_path here is a string.
class UserMailer < ApplicationMailer
def welcome(user)
email = user.email
mail(to: email, template_path: 'mailers/user_mailer/special')
end
end
The second example here is similar to the above, but template_path is an array. It's an array of path to folders. Action Mailer will look for the welcome template by starting on the first folder, app/views/mailers/user_mailer/non-special. If the template is not found, Action Mailer will move onto the next folder, app/views/mailers/user_mailer/special, which is where our template sits. Here, Action Mailer will stop looking for the template folder and send the email.
class UserMailer < ApplicationMailer
def welcome(user)
email = user.email
mail(
to: email,
template_path: ['mailers/user_mailer/non-special', 'mailers/user_mailer/special', 'mailers']
)
end
end
The third example here shows how we can use a template called special_welcome instead of welcome. special_welcome sits inside of app/views/mailers/user_mailer folder
class UserMailer < ApplicationMailer
def welcome(user)
email = user.email
mail(to: email, template_name: 'special_welcome')
end
end
The fourth example here shows that we can specify both template_name and template_path! This will look for a template called special_welcome inside of app/views/mailers/user_mailer/international_launch folder.
class UserMailer < ApplicationMailer
def welcome(user)
email = user.email
mail(
to: email,
template_name: 'special_welcome',
template_path: 'mailers/user_mailer/international_launch'
)
end
end
The fifth and last example here shows that we can specify the name and location of the template by passing a block to the mail function. Within the block, we can determine what to render for html, which is basically the content of the email.
One of the keyword arguments accepted by render is template.
class UserMailer < ApplicationMailer
def welcome(user)
email = user.email
mail(to: email) do |format|
format.html do
render template: 'mailers/user_mailer/international_launch/special-welcome'
end
end
end
end
Specifying a Layout
Another keyword argument accepted by render is layout.
Example
The example here shows how we can use a layout called yet-another-layout. Action Mailer will look for the layout from within app/layouts folder.
class UserMailer < ApplicationMailer
def welcome(user)
email = user.email
mail(to: email) do |format|
format.html { render layout: 'yet-another-layout' }
end
end
end
Specifying both the layout and template at once
Yup! We can specify both of them. 😉
Example
The example here will use a layout called yet-another-layout in app/layouts folder and a template called yet-another-template in app/views/mailers folder.
class UserMailer < ApplicationMailer
def welcome(user)
email = user.email
mail(to: email) do |format|
format.html do
render layout: 'yet-another-layout', template: 'mailers/yet-another-template'
end
end
end
end
Cheers for reading! 🤓
Top comments (0)