#312 Sending HTML Email
- Download:
- source codeProject Files in Zip (41.6 KB)
- mp4Full Size H.264 Video (16 MB)
- m4vSmaller H.264 Video (9.19 MB)
- webmFull Size VP8 Video (8.07 MB)
- ogvFull Size Theora Video (23.3 MB)
Supongamos que queremos enviar correos en en formato HTML. Codificamos nuestro HTML como de costumbre, usando posicionamiento y flotaciones CSS para que tenga el aspecto que queremos tras lo cual lo probamos en un navegador y todo parece correcto.
Tras lo cual decidimos enviárselo a nuestros miles de suscriptores sólo para descubrir que el correo se ve fatal en ciertos clientes. ¿Qué podemos hacer?
Por suerte hay mucho material acerca de cuáles son las mejores prácticas para enviar correos en HTML que se pueden encontrar con una sencilla búsqueda de Google, como este por ejemplo. Un punto importante que toca es que los contenidos se deben disponer usando tablas en lugar de CSS, lo que quiere decir que tendremos que despedirnos de nuestro bonito HTML semántico y utilizar tablas como en los viejos tiempos. No es algo especialmente bonito pero funcionará.
Otro punto importante del artículo es que cuando usamos CSS en nuestros correos deberíamos incluir los estilos en línea porque muchos clientes web ignoran los contenidos de la etiqueta head
, lo que significa que todas las hojas CSS que usemos deben estar en atributos de estilo dentro de los propios elementos HTML. Esto puede dar muchos dolores de cabeza a la hora del mantenimiento pero por suerte hay algunas herramientas que nos pueden ser de ayuda. Por ejemplo Mailchimp proporciona una aplicación Web donde podemos pegar código HTML y CSS y lo podemos convertir de forma que los estilos aparezcan en línea.
Hay varias herramientas que hacen esto por nosotros si tenemos que enviar correos de HTML desde una aplicación Rails. Una de ellas es la gema Premailer Rails 3 que a su vez utiliza la gema Premailer gem. Otra gema para esto es Roadie, que parte de MailStyle. Son sencillas de configurar y para verlo crearemos una nueva aplicación llamada mailit
y crearemos un nuevo mailer llamado newsletter_mailer
.
$ rails new mailit $ cd mailit $ rails g mailer newsletter_mailer weekly create app/mailers/newsletter_mailer.rb invoke erb create app/views/newsletter_mailer create app/views/newsletter_mailer/weekly.text.erb invoke test_unit create test/functional/newsletter_mailer_test.rb
He aquí el código generado de newsletter_mailer
.
class NewsletterMailer < ActionMailer::Base default from: "from@example.com" # Subject can be set in your I18n file at config/locales/en.yml # with the following lookup: # # en.newsletter_mailer.weekly.subject # def weekly @greeting = "Hi" mail to: "to@example.org" end end
Modificaremos la acción weekly
para que podamos pasar una dirección de correo y estableceremos el asunto.
def weekly(email) @greeting = "Hi" mail to: email, subject: "RailsCasts Weekly" end
Siempre es buena idea disponer de una versión de texto plano de los correos que enviemos, y ya tenemos una plantilla para ello.
RailsCasts - Ruby on Rails Screencasts Weekly Episodes --------------------------------------------- Episode 310: Getting Started with Rails Learning Ruby on Rails can be overwhelming, especially if you are new to programming. Here I will take you on a tour through various resources to help get started with Rails. Watch Episode (7 minutes): http://railscasts.com/episodes/310-getting-started-with-rails --------------------------------------------- (se omite el resto del archivo)
A continuación escribiremos la versión HTML.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>RailsCasts Weekly</title> <style type="text/css"> body, td { color:#000000; font-size:14px; font-family:Verdana,Helvetica,Arial; } .divider { background-color:#555555; height:2px; } .episode h2 { margin-top:0; margin-bottom:8px; font-size:18px; } .episode p { margin:8px 0; } .episode img { border:solid 1px #777777; } .episode .duration { font-size:11px;color:#555555; } #footer { font-size:11px; color:#555555; } #footer a { color:#555555;} </style> </head> <body> <table width="100%" id="background" border="0" cellpadding="0" cellspacing="0"> <tr><td align="center" valign="top"> <table width="650" id="main" border="0" cellpadding="0" cellspacing="20"> <tr> <td id="header" colspan="2"> <a href="http://railscasts.com/"><img src="http://railscasts.com/images/railscasts_logo.png" width="423" height="56" alt="RailsCasts"></a> </td> </tr> <tr> <td class="divider" colspan="2" bgcolor="#555555" height="2"></td> </tr> <tr class="episode"> <td> <a href="#"><img src="http://railscasts.com/assets/episodes/stills/310-getting-started-with-rails.png" width="200" height="125" alt="#310 Getting Started with Rails"></a> </td> <td valign="top"> <h2>#310 Getting Started with Rails</h2> <p>Learning Ruby on Rails can be overwhelming, especially if you are new to programming. Here I will take you on a tour through various resources to help get started with Rails.</p> <p> <a href="#">Watch Episode</a> <span class="duration">(7 minutes)</span> </p> </td> </tr> <tr> <td class="divider" colspan="2" bgcolor="#555555" height="2"></td> </tr> <tr> <td id="footer" colspan="2" align="center"> <p><a href="#">Unsubscribe</a> if you do not wish to receive these emails in the future.</p> <p>©2011 RailsCasts</p> </td> </tr> </table> </td></tr> </table> </body> </html>
Obsérvese que hemos dado estilos a la versión HTML con una etiqueta style
en la cabecera. Estos estilos pasarán a ser en línea dinámicamente cuando utilicemos Premailer o Roadie. También podríamos usar una hoja externa de estilos con un enlace normal y tendríamos el mismo resultado. Para que esto ocurra tenemos que añadir una de estas dos gemas a nuestra aplicación. En el caso de Premailer tendremos que añadir la propia gema y Nokogiri o Hpricot, pues necesita de una de las dos.
gem 'hpricot' gem 'premailer-rails3'
Como vamos a usar roadie lo añadiremos y luego ejecutaremos bundle
para instalarlo.
gem 'roadie'
Para hacer pruebas en nuestro entorno de desarrollo tendremos que ajustar ciertas configuraciones del correo en el fichero de config/environments/development.rb
.
Mailit::Application.configure do config.action_mailer.default_url_options = { host: "railscasts.com" } config.action_mailer.raise_delivery_errors = true config.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = { address: "smtp.gmail.com", port: 587, domain: "railscasts.com", authentication: "plain", enable_starttls_auto: true, user_name: ENV["GMAIL_USERNAME"], password: ENV["GMAIL_PASSWORD"] } # Rest of file omitted. end
Aquí hacemos varias cosas. Establecemos la opción default_url_options
en nuestro dominio; nos aseguramos de que se muestran los errores de entrega para poder verlos si tenemos algún problema enviando los correos y establecemos el método de envió a SMTP para añadir la configuración adecuada de nuestro servidor de correo. Utilizamos variables de entorno para nuestro usuario y clave pero si quisiéramos podríamos establecerlas directamente.
Con nuestro gestor de envíos configurado podemos hacer una prueba con la consola de Rails. Al hacerlo puede ser que veamos una advertencia de la gema CSS Parser, pero no hay nada que podamos hacer en este caso. De todas formas esto no debería causar problemas (y es de suponer que será corregido pronto). Podemos enviar un correo de prueba.
> NewsletterMailer.weekly("railscasts.example@gmail.com").deliver
Tras hacer esto vemos que se envía nuestro correo y tiene buen aspecto.
Los que vayan a usar una de estas gemas deberían leer bien la documentación disponible en las páginas de GitHub porque no lo hemos visto todo en este episodio. Por ejemplo con la gema Roadie se puede pasar una opción css
al método de correo para especificar qué ficheros se deberían incluir en línea.