actionmailer_inline_css 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +6 -0
- data/README.md +93 -0
- data/Rakefile.rb +19 -0
- data/actionmailer_inline_css.gemspec +18 -0
- data/lib/action_mailer/inline_css_helper.rb +20 -0
- data/lib/action_mailer/inline_css_hook.rb +25 -0
- data/lib/actionmailer_inline_css.rb +13 -0
- metadata +91 -0
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
# ActionMailer Inline CSS
|
2
|
+
|
3
|
+
Seamlessly integrate [Alex Dunae's premailer](http://premailer.dialect.ca/) gem with ActionMailer.
|
4
|
+
|
5
|
+
|
6
|
+
## Problem?
|
7
|
+
|
8
|
+
The [Guide to CSS support in email](http://www.campaignmonitor.com/css/) from
|
9
|
+
[campaignmonitor.com](http://www.campaignmonitor.com) shows that Gmail doesn't
|
10
|
+
support `<style>` tags.
|
11
|
+
|
12
|
+
Thus, CSS is really only cross-plaform when it is inlined for each element.
|
13
|
+
|
14
|
+
|
15
|
+
### [Email Client Popularity](http://www.campaignmonitor.com/stats/email-clients/):
|
16
|
+
|
17
|
+
| Outlook | 27.62% |
|
18
|
+
|------:|:------------|
|
19
|
+
| iOS Devices | 16.01% |
|
20
|
+
| Hotmail | 12.14% |
|
21
|
+
| Apple Mail | 11.13% |
|
22
|
+
| Yahoo! Mail | 9.54% |
|
23
|
+
| Gmail | 7.02% |
|
24
|
+
|
25
|
+
Gmail may only make up 7% of all email clients, but it's a percentage you can't ignore!
|
26
|
+
|
27
|
+
|
28
|
+
## Solution
|
29
|
+
|
30
|
+
Inlining CSS is a pain to do by hand, and that's where the
|
31
|
+
[premailer](http://premailer.dialect.ca/) gem comes in.
|
32
|
+
|
33
|
+
From http://premailer.dialect.ca/:
|
34
|
+
|
35
|
+
* CSS styles are converted to inline style attributes.
|
36
|
+
Checks style and link[rel=stylesheet] tags and preserves existing inline attributes.
|
37
|
+
* Relative paths are converted to absolute paths.
|
38
|
+
Checks links in href, src and CSS url('')
|
39
|
+
|
40
|
+
|
41
|
+
The <tt>actionmailer_inline_css</tt> gem is a tiny integration between ActionMailer and premailer.
|
42
|
+
|
43
|
+
Inspiration comes from [@fphilipe](https://github.com/fphilipe)'s
|
44
|
+
[premailer-rails3](https://github.com/fphilipe/premailer-rails3) gem, but I wasn't
|
45
|
+
completely happy with it's conventions.
|
46
|
+
|
47
|
+
|
48
|
+
## Installation & Usage
|
49
|
+
|
50
|
+
To use this in your Rails app, simply add `gem "actionmailer_inline_css"` to your `Gemfile`.
|
51
|
+
|
52
|
+
* If you already have an HTML email template, all CSS will be automatically inlined.
|
53
|
+
* If you don't include a text email template, <tt>premailer</tt> will generate one from the HTML part.
|
54
|
+
(Having said that, it is recommended that you write your text templates by hand.)
|
55
|
+
|
56
|
+
|
57
|
+
### Additional Helpers
|
58
|
+
|
59
|
+
Rails does not provide any helpers for adding 'embedded' CSS to your layouts (and rightly so!),
|
60
|
+
but the following helper is now available for your mail layouts:
|
61
|
+
|
62
|
+
<tt>embedded_style_tag(file = mailer.mailer_name)</tt>
|
63
|
+
|
64
|
+
* Embeds CSS loaded from a file, in a <tt>style</tt> tag.
|
65
|
+
* File can be given with or without .css extension
|
66
|
+
* Default path for mailer css files is <tt>public/stylesheets/mailers/#{mailer_name}.css</tt>
|
67
|
+
|
68
|
+
#### Example
|
69
|
+
|
70
|
+
Given a mailer called <tt>BuildMailer</tt>, you can add the following
|
71
|
+
line to the `<head>` section of <tt>app/views/layouts/build_mailer.html.erb</tt>:
|
72
|
+
|
73
|
+
<%= embedded_style_tag %>
|
74
|
+
|
75
|
+
This will embed the CSS found at <tt>public/stylesheets/mailers/build_mailer.css</tt>.
|
76
|
+
|
77
|
+
--------------------------
|
78
|
+
|
79
|
+
If you wanted to include different CSS for each mail template, you could do something like this:
|
80
|
+
|
81
|
+
<% content_for 'head' do %>
|
82
|
+
<%= embedded_style_tag 'error_notification' %>
|
83
|
+
<% end %>
|
84
|
+
|
85
|
+
|
86
|
+
## Other Notes
|
87
|
+
|
88
|
+
It may seem like a waste of resources to generate HTML, then parse it with Nokogiri,
|
89
|
+
alter it, and finally re-render it. However, there is simply no other way to do it.
|
90
|
+
ERB templates contain HTML tags in plain text, so the output must be parsed.
|
91
|
+
On-the-fly CSS inlining could theoretically be built for Haml templates,
|
92
|
+
but it would be far too much effort for such a small use-case.
|
93
|
+
|
data/Rakefile.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
$:.unshift File.expand_path('../lib', __FILE__)
|
2
|
+
|
3
|
+
require 'rake'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rake/rdoctask'
|
6
|
+
require 'rake/packagetask'
|
7
|
+
require 'rake/gempackagetask'
|
8
|
+
|
9
|
+
def gemspec
|
10
|
+
@gemspec ||= begin
|
11
|
+
file = File.expand_path('../actionmailer_inline_css.gemspec', __FILE__)
|
12
|
+
eval(File.read(file), binding, file)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
Rake::GemPackageTask.new(gemspec) do |pkg|
|
17
|
+
pkg.need_tar = true
|
18
|
+
end
|
19
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "actionmailer_inline_css"
|
3
|
+
s.version = "1.0.0"
|
4
|
+
s.date = Time.now.strftime('%Y-%m-%d')
|
5
|
+
s.summary = "Always send HTML e-mails with inline CSS, using the 'premailer' gem"
|
6
|
+
s.email = "nathan.f77@gmail.com"
|
7
|
+
s.homepage = "http://premailer.dialect.ca/"
|
8
|
+
s.description = "Module for ActionMailer to improve the rendering of HTML emails by using the 'premailer' gem, which inlines CSS and makes relative links absolute."
|
9
|
+
s.has_rdoc = false
|
10
|
+
s.author = "Nathan Broadbent"
|
11
|
+
s.files = `git ls-files`.split("\n")
|
12
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
13
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
14
|
+
s.add_dependency('actionmailer', '>= 3.0.0')
|
15
|
+
s.add_dependency('premailer', '>= 1.7.1')
|
16
|
+
s.add_dependency('nokogiri', '>= 1.4.4')
|
17
|
+
end
|
18
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module ActionMailer
|
2
|
+
module InlineCssHelper
|
3
|
+
# Embed CSS loaded from a file in a 'style' tag.
|
4
|
+
# CSS file can be given with or without .css extension,
|
5
|
+
# and will be searched for in "#{Rails.root}/public/stylesheets/mailers" by default.
|
6
|
+
def embedded_style_tag(file = mailer.mailer_name)
|
7
|
+
['.css', ''].each do |ext|
|
8
|
+
[Rails.root.join("public", "stylesheets", "mailers"), Rails.root].each do |parent_path|
|
9
|
+
guessed_path = parent_path.join(file+ext).to_s
|
10
|
+
if File.exist?(guessed_path)
|
11
|
+
return content_tag(:style, File.read(guessed_path), {:type => "text/css"}, false)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#
|
2
|
+
# Always inline CSS for HTML emails
|
3
|
+
#
|
4
|
+
module ActionMailer
|
5
|
+
class InlineCssHook
|
6
|
+
def self.delivering_email(message)
|
7
|
+
if html_part = (message.html_part || (message.content_type =~ /text\/html/ && message))
|
8
|
+
premailer = Premailer.new(html_part.body.to_s, :with_html_string => true)
|
9
|
+
existing_text_part = message.text_part && message.text_part.body.to_s
|
10
|
+
# Reset the body
|
11
|
+
message.body = nil
|
12
|
+
# Add an HTML part with CSS inlined.
|
13
|
+
message.html_part do
|
14
|
+
content_type "text/html; charset=utf-8"
|
15
|
+
body premailer.to_inline_css
|
16
|
+
end
|
17
|
+
# Add a text part with either the pre-existing text part, or one generated with premailer.
|
18
|
+
message.text_part do
|
19
|
+
body existing_text_part || premailer.to_plain_text
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'premailer'
|
2
|
+
require 'nokogiri'
|
3
|
+
require 'action_mailer/inline_css_hook'
|
4
|
+
require 'action_mailer/inline_css_helper'
|
5
|
+
|
6
|
+
require 'rails'
|
7
|
+
class InlineCssRailtie < Rails::Railtie
|
8
|
+
config.after_initialize do
|
9
|
+
ActionMailer::Base.register_interceptor ActionMailer::InlineCssHook
|
10
|
+
ActionMailer::Base.send :helper, ActionMailer::InlineCssHelper
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: actionmailer_inline_css
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Nathan Broadbent
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-09-13 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: actionmailer
|
16
|
+
requirement: &20522380 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.0.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *20522380
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: premailer
|
27
|
+
requirement: &20521760 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.7.1
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *20521760
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: nokogiri
|
38
|
+
requirement: &20521040 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 1.4.4
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *20521040
|
47
|
+
description: Module for ActionMailer to improve the rendering of HTML emails by using
|
48
|
+
the 'premailer' gem, which inlines CSS and makes relative links absolute.
|
49
|
+
email: nathan.f77@gmail.com
|
50
|
+
executables: []
|
51
|
+
extensions: []
|
52
|
+
extra_rdoc_files: []
|
53
|
+
files:
|
54
|
+
- Gemfile
|
55
|
+
- README.md
|
56
|
+
- Rakefile.rb
|
57
|
+
- actionmailer_inline_css.gemspec
|
58
|
+
- lib/action_mailer/inline_css_helper.rb
|
59
|
+
- lib/action_mailer/inline_css_hook.rb
|
60
|
+
- lib/actionmailer_inline_css.rb
|
61
|
+
homepage: http://premailer.dialect.ca/
|
62
|
+
licenses: []
|
63
|
+
post_install_message:
|
64
|
+
rdoc_options: []
|
65
|
+
require_paths:
|
66
|
+
- lib
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
69
|
+
requirements:
|
70
|
+
- - ! '>='
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
segments:
|
74
|
+
- 0
|
75
|
+
hash: 1622860331103821556
|
76
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
|
+
none: false
|
78
|
+
requirements:
|
79
|
+
- - ! '>='
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
segments:
|
83
|
+
- 0
|
84
|
+
hash: 1622860331103821556
|
85
|
+
requirements: []
|
86
|
+
rubyforge_project:
|
87
|
+
rubygems_version: 1.8.8
|
88
|
+
signing_key:
|
89
|
+
specification_version: 3
|
90
|
+
summary: Always send HTML e-mails with inline CSS, using the 'premailer' gem
|
91
|
+
test_files: []
|