awesomemailer 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +6 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +8 -0
- data/README.md +69 -65
- data/VERSION +1 -1
- data/awesomemailer.gemspec +2 -2
- data/lib/awesome_mailer/renderer.rb +43 -22
- metadata +2 -2
data/CHANGELOG
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
0.1.2
|
2
|
+
* Added support for @media queries and vendor prefixes
|
3
|
+
in the header. Should solve most issues w/CSS3 in
|
4
|
+
emails. Obviously it won't fix Outlook. Nothing can fix
|
5
|
+
Outlook.
|
6
|
+
|
1
7
|
0.1.0
|
2
8
|
* Full test coverage and moved to Nokogiri from Hpricot. Also
|
3
9
|
added autoload so the gem is there when you need it but won't
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -22,6 +22,7 @@ GEM
|
|
22
22
|
multi_json (~> 1.0)
|
23
23
|
addressable (2.3.2)
|
24
24
|
builder (3.0.4)
|
25
|
+
coderay (1.0.9)
|
25
26
|
css_parser (1.2.6)
|
26
27
|
addressable
|
27
28
|
rdoc
|
@@ -47,10 +48,15 @@ GEM
|
|
47
48
|
i18n (>= 0.4.0)
|
48
49
|
mime-types (~> 1.16)
|
49
50
|
treetop (~> 1.4.8)
|
51
|
+
method_source (0.8.1)
|
50
52
|
mime-types (1.19)
|
51
53
|
multi_json (1.3.7)
|
52
54
|
nokogiri (1.5.6)
|
53
55
|
polyglot (0.3.3)
|
56
|
+
pry (0.9.12)
|
57
|
+
coderay (~> 1.0.5)
|
58
|
+
method_source (~> 0.8)
|
59
|
+
slop (~> 3.4)
|
54
60
|
rack (1.4.1)
|
55
61
|
rack-cache (1.2)
|
56
62
|
rack (>= 0.4)
|
@@ -71,6 +77,7 @@ GEM
|
|
71
77
|
multi_json (~> 1.0)
|
72
78
|
simplecov-html (~> 0.7.1)
|
73
79
|
simplecov-html (0.7.1)
|
80
|
+
slop (3.4.4)
|
74
81
|
sprockets (2.1.3)
|
75
82
|
hike (~> 1.2)
|
76
83
|
rack (~> 1.0)
|
@@ -91,5 +98,6 @@ DEPENDENCIES
|
|
91
98
|
guard-rspec
|
92
99
|
jeweler
|
93
100
|
nokogiri (>= 1.5.6)
|
101
|
+
pry
|
94
102
|
rspec
|
95
103
|
simplecov
|
data/README.md
CHANGED
@@ -8,90 +8,96 @@ Add this to your Gemfile:
|
|
8
8
|
|
9
9
|
gem 'awesomemailer'
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
gem install awesomemailer
|
14
|
-
|
15
|
-
Then `require 'awesome_mailer'` and follow the example below.
|
11
|
+
Then bundle. And some chips. And a soda.
|
16
12
|
|
17
13
|
## Example
|
18
14
|
|
19
15
|
Suppose you have the following mailer:
|
20
16
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
17
|
+
```ruby
|
18
|
+
class UserMailer < ActionMailer::Base
|
19
|
+
def signup(user_id)
|
20
|
+
@user = User.find(user_id)
|
21
|
+
mail(:to => @user.email, :from => "no-reply@example.com")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
```
|
27
25
|
|
28
26
|
... and you have a template `app/views/user_mailer/signup.html.erb`. It might look something like this:
|
29
27
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
28
|
+
```html
|
29
|
+
<html>
|
30
|
+
<%= stylesheet_link_tag 'email' %>
|
31
|
+
<body>
|
32
|
+
<div id="header"><%= link_to raw(image_tag('logo.png')), root_url %></div>
|
33
|
+
<div id="content">
|
34
|
+
<p>Welcome to AwesomeMailer, <%= @user.name %>! We think you might be neat.</p>
|
35
|
+
</div>
|
36
|
+
<div id="footer">
|
37
|
+
Copyright © 2013 <a href="http://www.delightfulwidgets.com">Delightful Widgets</a>
|
38
|
+
</div>
|
39
|
+
</body>
|
40
|
+
</html>
|
41
|
+
```
|
42
42
|
|
43
43
|
... and your style sheet (email.css) might be kinda like this:
|
44
44
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
45
|
+
```css
|
46
|
+
body {
|
47
|
+
background: #f0f0f0;
|
48
|
+
font: 12pt Arial normal;
|
49
|
+
}
|
49
50
|
|
50
|
-
|
51
|
-
|
52
|
-
|
51
|
+
a img {
|
52
|
+
border-width: 0;
|
53
|
+
}
|
53
54
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
55
|
+
#header {
|
56
|
+
border-bottom: 1px solid black;
|
57
|
+
margin-bottom: 1em;
|
58
|
+
}
|
58
59
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
60
|
+
#content {
|
61
|
+
font-family: Helvetica;
|
62
|
+
padding: 1em 0;
|
63
|
+
}
|
63
64
|
|
64
|
-
|
65
|
-
|
66
|
-
|
65
|
+
#content p {
|
66
|
+
line-height: 1.3em;
|
67
|
+
}
|
67
68
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
69
|
+
#footer {
|
70
|
+
border-top: 1px dotted orange;
|
71
|
+
font-size: 10pt;
|
72
|
+
}
|
73
|
+
```
|
72
74
|
|
73
75
|
... you might be unhappy because most mail viewers couldn't care less that you included a stylesheet. But wait!
|
74
76
|
There's AwesomeMailer! Just change your mailer to look like this:
|
75
77
|
|
76
|
-
|
78
|
+
```ruby
|
79
|
+
class UserMailer < AwesomeMailer::Base
|
80
|
+
```
|
77
81
|
|
78
82
|
... and voila! Now your templates will render like this:
|
79
83
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
84
|
+
```html
|
85
|
+
<html>
|
86
|
+
<body style="background: #f0f0f0; font: 12pt Arial normal;">
|
87
|
+
<div id="header" style="border-bottom: 1px solid black; margin-bottom: 1em;">
|
88
|
+
<a href="http://www.delightfulwidgets.com/">
|
89
|
+
<img src="http://www.delightfulwidgets.com/assets/logo.png" style="border-width: 0;" />
|
90
|
+
</a>
|
91
|
+
</div>
|
92
|
+
<div id="content" style="font-family: Helvetica; padding: 1em 0;">
|
93
|
+
<p style="line-height: 1.3em;">Welcome to AwesomeMailer, <%= @user.name %>! We think you might be neat.</p>
|
94
|
+
</div>
|
95
|
+
<div id="footer" style="border-top: 1px dotted orange; font-size: 10pt;">
|
96
|
+
Copyright © 2012 <a href="http://www.delightfulwidgets.com">Delightful Widgets</a>
|
97
|
+
</div>
|
98
|
+
</body>
|
99
|
+
</html>
|
100
|
+
```
|
95
101
|
|
96
102
|
WOW!
|
97
103
|
|
@@ -118,8 +124,6 @@ File bugs using the issues tab in Github. **Don't** e-mail me. _Please_.
|
|
118
124
|
|
119
125
|
## LEGAL FUNSIES
|
120
126
|
|
121
|
-
AwesomeMailer is copyright (c)
|
127
|
+
AwesomeMailer is copyright (c) 2013 Delightful Widgets Inc.
|
122
128
|
|
123
|
-
It was built by Flip Sasser
|
124
|
-
([https://github.com/alexdunae/css_parser](https://github.com/alexdunae/css_parser)) and, as far as I know, Nick Sieger
|
125
|
-
([https://github.com/hpricot/hpricot](https://github.com/hpricot/hpricot)). Those guys are AWESOME. Be their friends.
|
129
|
+
It was built by [Flip Sasser](http://www.inthebackforty.com/). CSS parsing is courtesy of ([css_parser](https://github.com/alexdunae/css_parser)) by Alex Dunae. Thanks, b.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.2
|
data/awesomemailer.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "awesomemailer"
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Flip Sasser"]
|
12
|
-
s.date = "2013-
|
12
|
+
s.date = "2013-04-12"
|
13
13
|
s.description = "\n AwesomeMailer embeds your e-mail CSS inline, allowing you to write e-mail templates without worrying too much about stylesheets\n "
|
14
14
|
s.email = "flip@x451.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -17,21 +17,42 @@ module AwesomeMailer
|
|
17
17
|
end
|
18
18
|
|
19
19
|
private
|
20
|
-
def
|
21
|
-
|
20
|
+
def append_styles_to_body!(document, selector, declarations)
|
21
|
+
declarations = "#{declarations.join('; ')};"
|
22
|
+
document.search(selector).each do |element|
|
23
|
+
element['style'] = [element['style'], declarations].compact.join(';')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def append_styles_to_head!(document, selector, declarations, media = nil)
|
28
|
+
selector_and_declarations = "#{selector} { #{declarations.join('; ')}; }"
|
29
|
+
if media != :all
|
30
|
+
selector_and_declarations = "@media #{media} { #{selector_and_declarations} }"
|
31
|
+
end
|
32
|
+
header_stylesheet.inner_html += "#{selector_and_declarations}\n"
|
22
33
|
end
|
23
34
|
|
24
35
|
def apply_css!(document)
|
25
|
-
css_parser.
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
36
|
+
css_parser.rules_by_media_query.each do |media_query, rules|
|
37
|
+
rules.each do |rule|
|
38
|
+
rule.each_selector do |selector, declarations, specificity|
|
39
|
+
# Rewrite relative URLs to match their parent CSS's URL path
|
40
|
+
rewrite_relative_urls(declarations) if host
|
41
|
+
declarations = declarations.split(';').map(&:strip)
|
42
|
+
if media_query != :all || selector =~ /(^@|:|moz)/
|
43
|
+
# Include difficult styles in the head
|
44
|
+
append_styles_to_head!(document, selector, declarations, media_query)
|
45
|
+
else
|
46
|
+
# Strip vendor prefix styles and append them to the header
|
47
|
+
vendor_specific_declarations = declarations.select {|declaration| declaration =~ /^-/ }
|
48
|
+
if vendor_specific_declarations.any?
|
49
|
+
declarations -= vendor_specific_declarations
|
50
|
+
append_styles_to_head!(document, selector, vendor_specific_declarations, media_query)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Include regular styles inline
|
54
|
+
append_styles_to_body!(document, selector, declarations)
|
55
|
+
end
|
35
56
|
end
|
36
57
|
end
|
37
58
|
end
|
@@ -39,13 +60,7 @@ module AwesomeMailer
|
|
39
60
|
|
40
61
|
def asset_pipeline_path
|
41
62
|
return false unless sprockets?
|
42
|
-
/^#{Regexp.escape(Rails.configuration.assets
|
43
|
-
end
|
44
|
-
|
45
|
-
def css_host
|
46
|
-
if host = AwesomeMailer::Base.default_url_options[:host]
|
47
|
-
Addressable::URI.heuristic_parse(host, scheme: 'http')
|
48
|
-
end
|
63
|
+
/^#{Regexp.escape(Rails.configuration.assets[:prefix])}\//
|
49
64
|
end
|
50
65
|
|
51
66
|
def css_parser
|
@@ -66,13 +81,19 @@ module AwesomeMailer
|
|
66
81
|
end
|
67
82
|
end
|
68
83
|
|
84
|
+
def host
|
85
|
+
if host = AwesomeMailer::Base.default_url_options[:host]
|
86
|
+
Addressable::URI.heuristic_parse(host, scheme: 'http')
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
69
90
|
def load_stylesheet(stylesheet)
|
70
91
|
stylesheet_path = stylesheet['href'].split('?').shift
|
71
|
-
stylesheet_path.gsub!(/^#{Regexp.escape(
|
92
|
+
stylesheet_path.gsub!(/^#{Regexp.escape(host)}/, '') if host
|
72
93
|
case stylesheet_path
|
73
94
|
when asset_pipeline_path
|
74
95
|
if asset = read_asset_pipeline_asset(stylesheet_path)
|
75
|
-
css_parser.add_block!(asset.to_s
|
96
|
+
css_parser.add_block!(asset.to_s)
|
76
97
|
end
|
77
98
|
when /^\//
|
78
99
|
local_path = rails? && Rails.root.join('public', stylesheet_path.gsub(/^\//, '')).to_s
|
@@ -96,7 +117,7 @@ module AwesomeMailer
|
|
96
117
|
def rewrite_relative_urls(css_declarations)
|
97
118
|
css_declarations.scan(/(url\s*\(?["']+(.[^'"]*)["']\))/i).each do |url_command, item|
|
98
119
|
next if item =~ /^http(s){0,1}:\/\//
|
99
|
-
item_url =
|
120
|
+
item_url = host.dup
|
100
121
|
item_url.path = File.join(item_url.path, item)
|
101
122
|
new_url_command = url_command.gsub(item, item_url.to_s)
|
102
123
|
css_declarations[url_command] = new_url_command
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: awesomemailer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-04-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionmailer
|