Markdown to text/plain and text/html for multipart email
I’m looking for a solution to send DRY multipart emails in Rails. With DRY I mean that the content for the mail is only defined once.
I’ve thought about some possible solutions but ha开发者_JAVA技巧ven’t found any existing implementations.
The solutions I’ve thought about are:
- load the text from I18n and apply Markdown for the html mail and apply Markdown with a special output type for the text mail where
- links are put in parenthesis after the link text
- bold, italic and other formatting that doesn't make sense are removed
- ordered and unordered lists are maintained
- generate only the html mail and convert that to text according to the above conditions
Is there any available solution out there? Which one is probably the better way to do it?
In Chapter 4 of Crafting Rails Applications, Jóse Valim walks you through how to make a "merb" handler that uses markdown with interspersed erb and can compile to text and html. Then you make a mailer generator that generates a single merb template for each of your mail actions.
You can read an excerpt from that chapter on the page I linked you to. I highly recommend buying the book.
If you're interested in using my sorry version of what he describes in that book, you can slap this in your Gemfile:
gem 'handlers', :git => "git://github.com/chadoh/handlers.git"
Be warned that I barely know what I'm doing, that I'm not versioning that gem, and that I probably won't really even maintain it. Frankly, I wish I could find someone else who was doing a better job, but I've been unsuccessful in doing so. If you want to fork my project and be the person doing that better job, go for it!
This is a PITA, but is the only way to DRY mail such that you can support both HTML (multipart) & plaintext:
Put the html email copy in a partial file in your ActionMailer view directory with the following extension: _action.html.erb
Replace "action" with whatever action name you are using.
Then create 2 more files in the same directory: action.text.html.erb and action.text.plain.erb
In the text.html partial:
<%= render "action.html", :locals => {:html => true} %>
In the text.plain partial:
<% content = render "action.html", :locals => {:html => false} %>
<%= strip_tags(content) %>
That works for me, though it certainly makes me want to pay the monthly service for madmimi
Use the maildown
gem.
This gems does the heavy lifting of allowing you to use email.md.erb
instead of email.html.erb
and email.text.erb
. Write it once in a sane format and have it automatically display in HTML and in Plain Text. Win.
There are some intricacies here that you'll want to look at based on your use-case, but here's some of what we did to get it working well:
Create a maildown.rb
initializer to setup some sane defaults:
Maildown.allow_indentation = true # Prevents code blocks from forming when using indentiation in markdown emails.
Maildown::MarkdownEngine.set_text do |text|
text.gsub( /{:.*}\n?/, "" ) # Removes Kramdown annotations that apply classes, etc. with `{: .class }`.
This allows you to use indents in your blocks, etc. But also precludes the ability to add indents in your Plain Text. It also removes Kramdown-specific annotation from Plain Text.
Then just replace your HTML and Plain Text files with a single .md.erb
file and test it out to make sure it looks good in both versions.
Note, until you remove the .html.erb
and .text.erb
files, it will show those first before looking for a .md.erb
file. This may actually be a nice feature if you ever needed to write separate formats for a specific email (maybe a marketing one that requires more complex formatting than Markdown can provide) without having to specify anything anywhere.
Works a treat.
精彩评论