Link to stylesheet from HTML email?

I am using actionMailer to send out an HTML email. This is working fine. I need to style it though...

Is there a way to link to a remote stylesheet I have in my public/ stylesheets Dir?

Thanks, Elliott

For best compatibility with email clients and other client factors its best to put the styles in the email. This way the client can't deny the download of the stylesheet... If you have images you might be sol but that's a risk you have to take. Styling your email so that it looks good with/without images is a good practice

heimdull wrote:

For best compatibility with email clients and other client factors its best to put the styles in the email.

[...]

Better yet, don't use HTML e-mail. Generally speaking, e-mail works better the closer it stays to plain text.

Best,

I appreciate with Marnen Laibow-Koser, if the requirements concern you can give remote path to your images and stylesheet.

heimdull wrote:

For best compatibility with email clients and other client factors its best to put the styles in the email. This way the client can't deny the download of the stylesheet... If you have images you might be sol but that's a risk you have to take. Styling your email so that it looks good with/without images is a good practice

In the space provided ->

...please explain why Rails can't share a partial between an email and a view.

(Or, uh, do I misunderstand the system?)

I hear what you guys are saying on staying away from HTML emails... However if I do want to link to an image or stylesheet in /public/* from the email how would I do that?

Thanks again, Elliott

You would just link to images or stylesheets in your ActionMailer view in the same way as you usually would.

And I know you say you want to, but bear in mind that linking in an external stylesheet will fail for most email clients. At the very minimum you will need to include the CSS inside a <style> tag within the email, and for clients including GMail and Outlook you will actually have to include the CSS within the style attribute of the HTML tags.

-Matt

Matt is right on the money. Images are not a big deal, simply link them as you would for any html using the full http://mysite.com/images/picture.jpg path.

And make sure (as stated above) that the email still is representable without the images because they do not load by default for a large majority of the recipients.

Thanks a ton for the info and insight guys!

Elliott

One more question for you guys...

This is the first time I have used actionMailer and the corresponding templates. In my case I was noticing that email would not be sent out as expected unless I had both an "email_view.text.html.erb" and "email_view.text.plain.erb" view file in the app. Is this really how it works?

Is the flow something like this...?

If the email client doesn't support the HTML version is Rails smart enough to serve the plain text version instead?

Thanks

My app sends multipart/alternative html (with embedded images) and text emails and lets the client choose.

Here's how I set things up. I take no credit for this - it's a combo of ideas I found while searching for a solution. On the shoulders of giants and all that.

I'm running 2.3.2.

Install Google Code Archive - Long-term storage for Google Code Project Hosting.

I ended up creating lib/premailer/ and putting the files in there since they need to be edited a little.

In premailer.rb, change initialize to take an HTML string instead of a URL.

class UserNotify < ActionMailer::Base   public   def portfolio_data(user,portfolios)

     # ... set up your subject, target, etc ...

      content_type "multipart/alternative"

      part "text/plain" do |p|         p.body = render_message('portfolio_data.text.plain.erb',@body)         p.transfer_encoding = "base64" # VERY IMPORTANT       end

      @parts << UserNotify.create_portfolio_html_data(@body)    end

# embed images in the email. # convert HTML with stylesheets to HTML with style attributes def portfolio_html_data(body)     content_type "multipart/related"

    yahoo_cid = Time.now.sec.to_s + "_yahoo"     google_cid = Time.now.sec.to_s + "_google"

    part "text/html" do |p|       pm = Premailer.new(render_message ('portfolio_data.text.html.erb',body))       m = pm.to_inline_css       pm.warnings.each do |warning|         clients = (warning[:clients] && (" (" << warning[:clients] << ")")) || ""         RAILS_DEFAULT_LOGGER.warn("Premailer warning: #{warning [:level]}: #{warning[:message]}#{clients}")       end       # RAILS_DEFAULT_LOGGER.debug("\n\n\nm:\n#{m}\n\n")       m.gsub!(/src="#{PortfolioHelper::YAHOO_IMG}[^"]*"/,"src=\"cid:# {yahoo_cid}\"")       m.gsub!(/src="#{PortfolioHelper::GOOGLE_IMG}[^"]*"/,"src=\"cid:# {google_cid}\"")       p.body = m       p.transfer_encoding = "base64" # VERY IMPORTANT     end

    f = File.open("#{RAILS_ROOT}/public# {PortfolioHelper::YAHOO_IMG}","rb")     inline_attachment :content_type => "image/gif",     :body => f.read,     :filename => "yahoo.gif",     :cid => "<#{yahoo_cid}>"     f.close

    f = File.open("#{RAILS_ROOT}/public# {PortfolioHelper::GOOGLE_IMG}","rb")     inline_attachment :content_type => "image/gif",     :body => f.read,     :filename => "google.gif",     :cid => "<#{google_cid}>"     f.close   end

end

portfolio_data.text.html.erb looks roughly like this:

<html>   <head>     <style>   <%=File.read("#{RAILS_ROOT}/public/stylesheets/porb.css")-%>    </style>   </head> ... </html>

This works well for me. Images embed, css gets inlined, client gets to choose whether it wants text or html. I ought to do the next step and use the html_to_text stuff in premailer but I already had the text template written.

If there's a better way to pull all this stuff together I'm all ears.

-Chris

Thanks Chris.

I'll have to look into that in depth.

Ellliott