Daniel Doubrovkine bio photo

Daniel Doubrovkine

aka dB., @awscloud, former CTO @artsy, +@vestris, NYC

Email Twitter LinkedIn Github Strava
Creative Commons License

Last time we added custom editable mail templates to our mailers and made them Markdown format [read first]. Awesome. Let’s add a preview to the templates with 37-signals mail_view. I don’t know how we lived without this before!

Gemfile

gem "mail_view", :git => "https://github.com/37signals/mail_view"

Routes

Remember how we pre-declared our mailers in a hash. This is going to come in handy for config/routes.rb.

Mailers::ALL.each_pair do |klass, method_names|
  mount "#{klass.gsub('::', '')}::Preview".constantize => "mail_templates/#{klass.underscore}/preview"
end

Now we have a mail_templates/devise/mailer/preview/reset_password_instructions path for a Devise::Mailer mailer!

Preview

This needs to route somewhere. Let’s add a preview into our overridden DeviseMailer.

class DeviseMailer < Devise::Mailer
  def template_paths
    "devise/mailer"
  end

  def devise_mail(record, action)
    ...
  end

  class Preview < MailView
    def invitation_instructions
      DeviseMailer.devise_mail(
        User.new({email: 'chuck@example.com',
            name: 'Chuck Norris',
            invitation_token: 'invitation-token'}),
        :invitation_instructions)
    end
  end
end

Why Chuck Norris? I’ve been enjoying the Chuck Norris Jenkins Plugin too much lately. Chuck Norris can preview mail templates in PDF!

Here’s our mail templates admin page with a link to the preview (mail_templates/index.html.haml).

%h1 Mail Templates

%table
  %tr
    %th Class Name
    %th Method Name
    %th Subject
    %th
    %th

  - @mail_templates.each do |mail_template|
    %tr
      %td= mail_template.class_name
      %td= mail_template.method_name
      %td= mail_template.subject
      %td.admin_actions= link_to 'Edit', edit_mail_template_path(mail_template)
      %td.admin_actions= link_to 'Preview',
        "/admin/mail_templates/#{mail_template.class_name.underscore}/preview/#{mail_template.method_name}",
        :target => '_blank'

Well, that’s it. You need to add a Preview class for every mailer.

Screenshot

reset-password