Security News
Fluent Assertions Faces Backlash After Abandoning Open Source Licensing
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Email clients are not web browsers. They render html all funny, to put it politely. In general, the best practices for writing HTML that will look good in an email are the exact inverse from those that you should use for a web page. Remembering all those differences sucks.
With muddle, we're trying to make it so that the only thing you have to know is to use tables in your emails. Muddle will take care of the rest. It uses ideas from HTML Email Boilerplate to help you get your emails in line without having to know tons about how clients render it.
_target
set, etc.div
).Add this line to your application's Gemfile
:
gem 'muddle'
And then execute:
$ bundle
Or install it yourself with:
$ gem install muddle
However you're sending email, you'll want to get what you intend to be the html body of your email into a variable. How you do that is up to you. Say you have a SLIM template and you're using Mail to build and send your emails:
require 'muddle'
require 'slim'
require 'mail'
body = Slim::Template('path/to/welcome_email.html.slim').render
# This is really the only thing Muddle is involved in.
muddled_body = Muddle.parse(body)
email = Mail.new do
to 'some_new_customer@gmail.com'
from 'welcome@awesome_web_service.com'
subject 'Welcome!!!!!!!!!!1!!!!one!!!'
html_part do
body muddled_body
content_type 'text/html; charset=UTF-8'
end
end
If you're using ActionMailer
, you could do like this:
class UserMailer < ActionMailer::Base
def welcome_email
mail(
to: 'some_new_customer@gmail.com',
from: 'welcome@awesome_web_service.com',
subject: 'Welcome!!!!!!!!!!1!!!!one!!!'
) do |format|
format.html { Muddle.parse(render) }
end
end
end
You can configure Muddle with a block. Maybe throw this in an initializer of some sort. Here are all the defaults:
Muddle.configure do |config|
config.parse_with_premailer = true
config.insert_boilerplate_styles = true
config.insert_boilerplate_css = true
config.insert_boilerplate_attributes = true
config.validate_html = true
config.generate_plain_text = false
config.logger = nil
config.premailer_options = {
:remove_comments => true,
:with_html_string => true,
:adapter => :hpricot
}
end
For best results, just start writing your email with a table tag and move in
from there. Muddler will handle putting the xmlns
and DOCTYPE
and a bunch
of stuff into the <head>
, then open the <body>
for you. It will also close
these tags at the end.
For example, if you have a template the ends up like this:
<html>
<body>
<table>
<tbody>
<tr>
<td><h1>Welcome to our AWESOME NEW WEB SERVICE!</h1></td>
</tr>
<tr>
<td><p>You should come <a href="http://awesome_web_service.com">check us out</a>.</p></td>
</tr>
</tbody>
</table>
</body>
</html>
Muddle will spit out this:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body style="width: 100% !important; margin: 0; padding: 0; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%;">
<table cellpadding="0" cellspacing="0" border="0" align="center">
<tbody>
<tr>
<td valign="top"><h1 style="color: black !important;">Welcome to our AWESOME NEW WEB SERVICE!</h1></td>
</tr>
<tr>
<td valign="top"><p style="margin: 1em 0;">You should <a href="http://awesome_web_service.com" style="color: blue;" target="_blank">check us out</a>.</p></td>
</tr>
</tbody>
</table>
<style type="text/css">
/* Boilerplate CSS for BODY */
#outlook a {padding:0;}
#backgroundTable {margin:0; padding:0; width:100% !important; line-height: 100% !important;}
.ExternalClass {width:100%;}
.ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {line-height: 100%;}
.image_fix {display:block;}
h1 a:active, h2 a:active, h3 a:active, h4 a:active, h5 a:active, h6 a:active {color: red !important;}
h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited {color: purple !important;}
@media only screen and (max-device-width: 480px) {
a[href^="tel"], a[href^="sms"] {
text-decoration: none;
color: blue;
pointer-events: none;
cursor: default;
}
.mobile_link a[href^="tel"], .mobile_link a[href^="sms"] {
text-decoration: default;
color: orange !important;
pointer-events: auto;
cursor: default;
}
}
@media only screen and (min-device-width: 768px) and (max-device-width: 1024px) {
a[href^="tel"], a[href^="sms"] {
text-decoration: none;
color: blue;
pointer-events: none;
cursor: default;
}
.mobile_link a[href^="tel"], .mobile_link a[href^="sms"] {
text-decoration: default;
color: orange !important;
pointer-events: auto;
cursor: default;
}
}
</style>
<style type="text/css">
body { width: 100% !important; -webkit-text-size-adjust: 100% !important; -ms-text-size-adjust: 100% !important; margin: 0 !important; padding: 0 !important; }
img { outline: none !important; text-decoration: none !important; -ms-interpolation-mode: bicubic !important; }
</style>
</body>
</html>
$ git checkout -b my-new-feature
)$ git commit -am 'Added some feature'
)$ git push origin my-new-feature
)FAQs
Unknown package
We found that muddle demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Research
Security News
Socket researchers uncover the risks of a malicious Python package targeting Discord developers.
Security News
The UK is proposing a bold ban on ransomware payments by public entities to disrupt cybercrime, protect critical services, and lead global cybersecurity efforts.