Responsive Emails in Rails with Ink

Joyce Echessa
Tweet

Screenshot 2014-02-08 13.59.35

Why Responsive?

These days, a lot of users read their emails through their mobile devices (about 48% according to this statistic) and if you want to provide a good user experience to your subscribers you should consider responsive email design.

There are several ways to approach this. You could build the emails yourself from scratch and use media queries to cater for different screens or you could use premium and non-premium templates that are available online and modify them to suit your needs. The problem with these solutions is getting a consistent look of your emails in all email clients. One email client that is especially hard to work with when it comes to responsive emails is Outlook because of its limited CSS support.

What is the Solution?

Zurb, the same company that came up with the Foundation framework released an Email framework named Ink. According to them, Ink enables you to ‘Quickly create responsive HTML emails that work on any device & client. Even Outlook.’. And that is what we will work with in this tutorial. We are going to create a Rails application that sends an email to a user after they sign up for an account.

ink

First we’ll create a new application called rails_ink.

rails new rails_ink

For demonstration purposes, we won’t be building a large application. I used the scaffold command to generate a User model and its related views and controllers.

rails generate scaffold user name:string email:string

Migrate the database after that.

rake db:migrate

Next we’ll generate the mailer.

rails generate mailer UserMailer

This will create a mailer class, view directory, and a test file.

Next, we’ll add a configuration file to the config/initializers directory. This will hold the mailer configuration settings. For testing, we’ll be using Gmail’s smtp server. In production, you might be using another delivery method, like sendmail with your local server.

Create a file called mailer_settings inside the config/initializers directory and insert the following code, making changes as necessary.

ActionMailer::Base.smtp_settings = {
  :address => "smtp.gmail.com",
  :port => 587,
  :user_name => ENV['GMAIL_USERNAME'],
  :password => ENV['GMAIL_PASSWORD'],
  :authentication => "plain"
}

We need to add a method called registration_email to the app/mailers/user_mailer.rb file. This method will send an email to a user who registers. The method will take in a User object and assign it to an instance variable so that it’s available to our view. Since our email will have an image in the banner, we have to include this as an inline attachment in mailer.

class UserMailer < ActionMailer::Base
  default from: 'example@sitepoint.com'

  def registration_email(user)
    @user = user
    attachments.inline['banner.jpeg'] = File.read("#{Rails.root}/app/assets/images/banner.jpeg")
    mail(to: user.email, subject: 'Registration Confirmation')
  end
end

We now need to create a view file for our email. This will be located in the app/views/user_mailer directory and has to have the same name as the corresponding method in the UserMailer class.

Create a file named registration_email.html.erb inside app/views/user_mailer.

We are going to use one of the templates on the Ink website. I am using the Basic template for this demonstration.

template

For simplicity, during testing, I prefer just working with the HTML and CSS, running it directly in the browser instead of running it from the Rails application. When I am done, I will then transfer the code to my Rails app.

You can link the ‘ink.css’ file in the email but this should only be done for testing purposes. When you are satisfied with the result, copy the css and paste it into the HTML document between style tags. Then you should run your email content through an inliner. An inliner brings all your styles inline, which is important, as some email clients tend to strip out the CSS in the style tag. There are several online inliners, but we’ll use the Ink Inliner.

inliner

Don’t place any ERB code in the HTML file because the inliner won’t understand it and, thus, won’t output the correct HTML. We’ll have to search for and replace the static text with the necessary variables. Here I will be replacing the banner image and the name of the recipient (Susan Calvin) with the name of the registered user.

Once we have the email output, paste this code into the mailer view template app/views/user_mailer/registration_email.html.erb and insert any needed variables. Here, we will search for the string Susan Calvin and replace it with the following:

<%= @user.name %>

user_name_callout

Now, search for the img tag to the image we want to replace and insert the corresponding image_tag. Be sure to include the css styles and attributes that the inliner inserted in the tag.

I changed it from this:

<img src="http://placehold.it/200x50" style="outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; width: auto; max-width: 100%; float: left; clear: both; display: block;" align="left" />

To this:

<%= image_tag attachments['banner.jpeg'].url, :style => "outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; width: auto; max-width: 100%; float: left; clear: both; display: block;", :align=>"left" %></td>

image_tag_callout

In the UsersController, after saving the user, we call UserMailer.registration_email and pass it the User object.

def create
  @user = User.new(user_params)

  respond_to do |format|
    if @user.save
      UserMailer.registration_email(@user).deliver
      format.html { redirect_to @user, notice: 'User was successfully created.' }
      format.json { render action: 'show', status: :created, location: @user }
    else
      format.html { render action: 'new' }
      format.json { render json: @user.errors, status: :unprocessable_entity }
    end
  end
end

The UserMailer.registration_email(@user).deliver sends our email.

And that’s it. Register a user and test out the email on different clients.

Conclusion

If you want to send responsive emails to your users without spending money on a template or writing the code from scratch, give Ink a try. It can be used with any language you choose for your app and it also works well with Email Service Providers like Mailchimp and Campaign Monitor.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • jokham

    Thanks! Glad you liked it.