Created
May 2, 2012 20:49
-
-
Save coryschires/2580384 to your computer and use it in GitHub Desktop.
html-email-styles.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<h1>A better way to manage HTML emails with Ruby on Rails</h1> | |
<p>With Transis Planner nearly completed, we're starting to focus on the finer details, making sure everything's nicely polished and ready for launch. Among other things, this means creating great looking HTML emails. After all, Planner is a collaboration tool. Our users will be working together to hammer out effective media plans, and that means we'll be sending lots of media briefs, insertion orders, and so on.</p> | |
<p>Sending multipart emails (i.e. HTML and plain text) with Rails is very straight forward. Just write a mailer action and create two corresponding view templates — one with an `.html` extension and one with a `.text` extension. But this method has a few shortcomings:</p> | |
<ul> | |
<li>You end up duplicating text (and probably logic) since you need to create both a `.text` and `.html` template.</li> | |
<li>Emails are a total pain to style. In the process, you'll lay waste to all sorts of web standards — using table-based layouts, writing inline styles, etc.</li> | |
<li>It's tedious to test email styles since checking every tweak means manually sending an email, checking your inbox, etc.</li> | |
</ul> | |
<p>Can we leverage Ruby to solve these problems?</p> | |
<h3>There's a gem for everything.</h3> | |
<p>Actually there's two gems. Let's add them to our `Gemfile`:</p> | |
<pre> | |
gem 'premailer-rails3' | |
gem 'rails_email_preview', git: "git://github.com/glebm/rails_email_preview.git", ref: '7b19d432f0' | |
</pre> | |
<p>We'll start with <a href="https://github.com/fphilipe/premailer-rails3">premailer-rails3</a> since it requires almost no configuration. This gem solves our first two problems:</p> | |
<ol> | |
<li>It automatically creates plain/text emails based on HTML templates — no more duplication.</li> | |
<li>If you create an `email.css` file, it will automatically translate the CSS rules into old school inline styles.</li> | |
</ol> | |
<p>Next, we'd like to somehow preview our emails in a web browser rather than having to check our inbox every time we change the font size or whatever. This is where <a href="https://github.com/glebm/rails_email_preview">rails_email_preview</a> comes in. It's a small mountable engine that provides a simple user interface for viewing emails in the browser.</p> | |
<p>First, you'll need to add the engine to your `routes.rb`:</p> | |
<pre> | |
mount RailsEmailPreview::Engine, :at => 'email_preview' if Rails.env.development? | |
</pre> | |
<p>Next, you need to create a configuration file called `config/initializers/rails_email_preview.rb`. It should look something like:</p> | |
<pre> | |
require 'rails_email_preview' | |
RailsEmailPreview.setup do |config| | |
# Ensure that mail previewer plays nice with +premailer-rails3+. | |
config.before_render do |message| | |
PremailerRails::Hook.delivering_email(message) | |
end | |
# Register mailer preview classes. | |
config.preview_classes = [ YourMailer::Preview ] | |
end | |
</pre> | |
<p>Notice that `before_render` hook. That ties our two gems together, ensuring that our previews enjoy the same premailer goodness that they would if they were actually being delivered.</p> | |
<p>Finally, you need to do a little work in order to create the actual email previews. In `app/mailers/your_mailer.rb`</p> | |
<pre> | |
class YourMailer < ActionMailer::Base | |
def signup_confirmation(user) | |
@user = user | |
mail( | |
from: '[email protected]', | |
to: @user.email, | |
subject: "Thanks for signing up!" | |
) | |
end | |
class Preview | |
def signup_confirmation | |
YourMailer.signup_confirmation(User.first) | |
end | |
end | |
end | |
</pre> | |
<p>This is a vanilla `signup_confirmation` action. Notice, however, we've included a nested `Preview` class. (You might have also noticed that we registered this class as part of our initializer.) The instance methods map directly to our actual mailer actions and must return a `Mail` object. Beyond that, it's pretty wide open. For example, you could've created that user with a fixture, a factory, whatever.</p> | |
<p>And, finally, the best part. Visit `http://localhost:3000/email_preview` and make your emails lovely.</p> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment