actionmailer-instyle4 0.5.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +20 -0
- data/.rspec +1 -0
- data/Gemfile +9 -0
- data/Guardfile +17 -0
- data/LICENSE +22 -0
- data/README.md +147 -0
- data/Rakefile +7 -0
- data/actionmailer-instyle4.gemspec +34 -0
- data/config.ru +7 -0
- data/lib/action_mailer/in_style.rb +21 -0
- data/lib/action_mailer/in_style/premailer.rb +45 -0
- data/lib/action_mailer/in_style/processor.rb +90 -0
- data/lib/action_mailer/in_style/version.rb +5 -0
- data/lib/action_mailer/instyle.rb +1 -0
- data/lib/actionmailer-instyle.rb +3 -0
- data/spec/internal/app/assets/stylesheets/notification_mailer.css.scss +9 -0
- data/spec/internal/app/mailers/notification_mailer.rb +18 -0
- data/spec/internal/app/mailers/notification_mailer_no_layout.rb +9 -0
- data/spec/internal/app/views/layouts/notification_mailer.html.erb +14 -0
- data/spec/internal/app/views/layouts/notification_mailer_without_style.html.erb +11 -0
- data/spec/internal/app/views/notification_mailer/email_with_html_only.html.erb +9 -0
- data/spec/internal/app/views/notification_mailer/welcome_html_email.html.erb +7 -0
- data/spec/internal/app/views/notification_mailer/welcome_html_email.text.erb +1 -0
- data/spec/internal/app/views/notification_mailer_no_style/email_with_no_style.html.erb +8 -0
- data/spec/internal/config/database.yml +3 -0
- data/spec/internal/config/routes.rb +3 -0
- data/spec/internal/db/schema.rb +3 -0
- data/spec/internal/log/.gitignore +1 -0
- data/spec/internal/public/favicon.ico +0 -0
- data/spec/lib/action_mailer/inline/css_helper_spec.rb +9 -0
- data/spec/lib/action_mailer/inline/premailer_spec.rb +7 -0
- data/spec/lib/action_mailer/inline/processor_spec.rb +73 -0
- data/spec/lib/action_mailer/inline_spec.rb +48 -0
- data/spec/spec_helper.rb +24 -0
- metadata +253 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: bed2dc5bf38bccca1043659710f307f347642067
|
4
|
+
data.tar.gz: ba60105a79fbd03700368ef8a8fb95fb6730690d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f7c46b94b8aec01280516b0f1140a2e32481948a283fdc943e92b54f234942b577ed12970ca7c535e7341b685fe6d6a9932d7b07c38beb4c8deec21435fe003e
|
7
|
+
data.tar.gz: c668ab18ff1412588c9862282eeac6ffec63bc461358172575ba79d2261d32fe2e9b86940392f47efb4d0b774fee7eb19dcea4584e382f93f63eb76f06399687
|
data/.gitignore
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
.sass-cache
|
19
|
+
|
20
|
+
spec/internal/db/combustion_test.sqlite
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color -f d
|
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard 'rspec', :version => 2 do
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
6
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
8
|
+
|
9
|
+
# Rails example
|
10
|
+
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
11
|
+
watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
|
12
|
+
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
|
13
|
+
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Ivan Vanderbyl
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
# ActionMailer::InStyle
|
2
|
+
|
3
|
+
Forked From [testpilot/actionmailer-instyle](https://github.com/testpilot/actionmailer-instyle). He did most of the hard work.
|
4
|
+
|
5
|
+
HTML Emails can be a PITN, especially when you want maximum email client compatibility, of which the best way to achieve this is inline CSS. Unfortunately nobody actually wants to be forced into writing crap like that so we've created **InStyle**, it will automatically intercept your emails and look for a `stylesheet` linking to something inside your assets folder, extract all the styles, and convert them to inline styles on the fly.
|
6
|
+
|
7
|
+
_There are a couple of other projects which do this, some have not been updated for a while and none of them work with the Rails 3.1 asset pipeline._ *InStyle* uses Sprockets to render CSS which means you can use Sass, Compass, and any other CSS hackery you desire, including using stylesheets you would usually only use within your views e.g If you want to email an activity digest and make it look the same as what the user is used to seeing within your application (think Yammer).
|
8
|
+
|
9
|
+
## Requirements
|
10
|
+
|
11
|
+
This gem is built to take advantage of the Rails 3.1 *(and above)* Asset Pipeline, as such you must be using Rails ~>3.1 and have the Asset Pipeline enabled (default)
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
|
15
|
+
Add this line to your application's Gemfile:
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
gem 'actionmailer-instyle4', :require => 'action_mailer/in_style'
|
19
|
+
```
|
20
|
+
|
21
|
+
And then execute:
|
22
|
+
|
23
|
+
```bash
|
24
|
+
$ bundle install
|
25
|
+
```
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
Once installed it will add the required hooks out of the box to intercept each email being sent.
|
30
|
+
|
31
|
+
**Stylesheets**
|
32
|
+
|
33
|
+
As with all your other stylesheets, put them in `app/assets/stylesheets` and include them into your mailer
|
34
|
+
template using `stylesheet_link_tag "account_mailer"`, where `account_mailer` is the filename less the extension of the stylesheet you want to use.
|
35
|
+
|
36
|
+
Everything runs through the Asset Pipeline so you can use Sass simply by adding the `.scss` extension as you would with all other stylesheets.
|
37
|
+
|
38
|
+
**Compass**
|
39
|
+
|
40
|
+
Because Sass works out of the box, you can also include Compass for browser specific mixins and useful CSS3 helpers, keeping in mind that some email clients (Outlook for example) use very dated rendering engines and a lot of CSS properties may have undesired effects or not work at all.
|
41
|
+
|
42
|
+
For a complete rundown on what is supported, checkout this guide which CampaignMonitor has compiled.
|
43
|
+
|
44
|
+
[CampaignMonitor's guide to CSS support in email](http://www.campaignmonitor.com/css/)
|
45
|
+
|
46
|
+
## Tutorial
|
47
|
+
|
48
|
+
**1. Generate a Mailer:**
|
49
|
+
|
50
|
+
rails g mailer account_mailer account_created_email
|
51
|
+
|
52
|
+
**2. Create a template to be used for emails this Mailer sends:**
|
53
|
+
|
54
|
+
In `app/views/layouts/account_mailer.html.haml`
|
55
|
+
|
56
|
+
```haml
|
57
|
+
%html
|
58
|
+
%head
|
59
|
+
= stylesheet_link_tag "account_mailer"
|
60
|
+
|
61
|
+
%body
|
62
|
+
%table.main
|
63
|
+
%tr
|
64
|
+
%td= yield
|
65
|
+
```
|
66
|
+
|
67
|
+
You will notice that we have added a stylesheet link in the `head`, this location is not crucial, but the use of `stylesheet_link_tag` is because it will generate a link which we can process and feed through Sprockets in order to generate the inline styles.
|
68
|
+
|
69
|
+
**3. The stylesheet.**
|
70
|
+
|
71
|
+
You can use any style off CSS you like, we're using Sass.
|
72
|
+
|
73
|
+
`app/assets/stylesheets/account_mailer.css.scss`:
|
74
|
+
|
75
|
+
```css
|
76
|
+
body {
|
77
|
+
font-family: 'Helvetica Neue', Helvetica, sans-serif;
|
78
|
+
-webkit-font-smoothing: antialiased;
|
79
|
+
width: 100%;
|
80
|
+
background: darken(white, 8%);
|
81
|
+
}
|
82
|
+
|
83
|
+
table {
|
84
|
+
background: white;
|
85
|
+
&.main {
|
86
|
+
width: 430px;
|
87
|
+
tr td {
|
88
|
+
padding: 5px;
|
89
|
+
}
|
90
|
+
}
|
91
|
+
}
|
92
|
+
```
|
93
|
+
|
94
|
+
**4. Email views.**
|
95
|
+
|
96
|
+
In order to take advantage of all this fancy work, you must define a html view for your email, and optionally a text version. By default we will automatically generate a text version from the text content of the html view if none is supplied.
|
97
|
+
|
98
|
+
`app/views/account_mailer/account_created_email.html.haml`:
|
99
|
+
|
100
|
+
```haml
|
101
|
+
%p Hi #{@user.first_name},
|
102
|
+
%p Your account has been successfully created, so don't waste any time, #{link_to "Get started now", get_started_url}
|
103
|
+
```
|
104
|
+
|
105
|
+
**5. Send**
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
AccountMailer.account_created_email(@user).deliver
|
109
|
+
```
|
110
|
+
|
111
|
+
**6. Send awesome emails.**
|
112
|
+
|
113
|
+
The resulting email will look something like this:
|
114
|
+
|
115
|
+
```html
|
116
|
+
<html>
|
117
|
+
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head>
|
118
|
+
<body style="font-family: 'Helvetica Neue', Helvetica, sans-serif; -webkit-font-smoothing: antialiased; width: 100%; background-color: #ebebeb;" bgcolor="#ebebeb">
|
119
|
+
<table style="width: 430px; background-color: white;" bgcolor="white">
|
120
|
+
<tr>
|
121
|
+
<td style="padding: 5px;">
|
122
|
+
<p>Hi Michael,</p>
|
123
|
+
<p>Your account has been successfully created, so don't waste any time, <a href="/started">Get started now</a></p>
|
124
|
+
</td>
|
125
|
+
</tr>
|
126
|
+
</table>
|
127
|
+
</body>
|
128
|
+
</html>
|
129
|
+
```
|
130
|
+
|
131
|
+
**7. Grab a beer.**
|
132
|
+
|
133
|
+
As above.
|
134
|
+
|
135
|
+
## Contributing
|
136
|
+
|
137
|
+
1. Fork it
|
138
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
139
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
140
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
141
|
+
5. Create new Pull Request
|
142
|
+
|
143
|
+
## Meta
|
144
|
+
|
145
|
+
| Author | Twitter |
|
146
|
+
|------:|:------------|
|
147
|
+
| Robin Joseph | [@robinjoseph08](http://twitter.com/robinjoseph08) |
|
data/Rakefile
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/action_mailer/in_style/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Robin Joseph", "Ivan Vanderbyl"]
|
6
|
+
gem.email = ["robin.joseph@me.com"]
|
7
|
+
gem.description = %q{Easily create HTML emails in Rails ~>3.1}
|
8
|
+
gem.summary = %q{This gem brings you the power of the premailer gem to Rails 4
|
9
|
+
without any configuration needs. Create HTML emails, include a
|
10
|
+
CSS file as you do in a normal HTML document and premailer will
|
11
|
+
inline the included CSS.}
|
12
|
+
gem.homepage = "http://github.com/robinjoseph08/actionmailer-instyle4"
|
13
|
+
|
14
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
15
|
+
gem.files = `git ls-files`.split("\n")
|
16
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
gem.name = "actionmailer-instyle4"
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
gem.version = ActionMailer::InStyle::VERSION
|
20
|
+
|
21
|
+
gem.add_dependency("nokogiri", ">= 1.6")
|
22
|
+
gem.add_dependency("premailer", ">= 1.7")
|
23
|
+
gem.add_dependency("actionmailer", ">= 3.1")
|
24
|
+
gem.add_dependency("activesupport", ">= 3.1")
|
25
|
+
gem.add_dependency("sprockets", ">= 2.0")
|
26
|
+
|
27
|
+
gem.add_development_dependency 'rspec-rails', '~> 2.8.0'
|
28
|
+
gem.add_development_dependency 'guard-rspec'
|
29
|
+
gem.add_development_dependency 'sass', '~> 3.1'
|
30
|
+
gem.add_development_dependency 'sqlite3', '>= 1.3.5'
|
31
|
+
gem.add_development_dependency 'mail'
|
32
|
+
gem.add_development_dependency 'combustion', '~> 0.3.1'
|
33
|
+
|
34
|
+
end
|
data/config.ru
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require "action_mailer/in_style/version"
|
2
|
+
require "action_mailer"
|
3
|
+
|
4
|
+
module ActionMailer
|
5
|
+
module InStyle
|
6
|
+
autoload :Processor, 'action_mailer/in_style/processor'
|
7
|
+
autoload :Premailer, 'action_mailer/in_style/premailer'
|
8
|
+
|
9
|
+
# delivering_email hook within Mail
|
10
|
+
#
|
11
|
+
# This is where the whole process kicks off.
|
12
|
+
def self.delivering_email(message)
|
13
|
+
# If the email contains a html part or is only html
|
14
|
+
if message.html_part || (message.content_type =~ /text\/html/ && message)
|
15
|
+
InStyle::Processor.inline!(message)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
ActionMailer::Base.register_interceptor(ActionMailer::InStyle)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'premailer'
|
2
|
+
module ActionMailer
|
3
|
+
module InStyle
|
4
|
+
class Premailer < ::Premailer
|
5
|
+
|
6
|
+
def load_css_from_html!
|
7
|
+
load_css_from_asset_pipeline!
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
# Uses sprockets and the Rails ~>3.1 asset pipeline
|
12
|
+
# to load the compiled CSS from stylesheet links within the header of the
|
13
|
+
# email template.
|
14
|
+
def load_css_from_asset_pipeline!
|
15
|
+
if tags = @doc.search("link[@rel='stylesheet'], style")
|
16
|
+
tags.each do |tag|
|
17
|
+
if tag.to_s.strip =~ /^\<link/i && tag.attributes['href'] && media_type_ok?(tag.attributes['media'])
|
18
|
+
|
19
|
+
# If the stylesheet link begins with /assets we must be using the asset pipeline
|
20
|
+
# to generate the css. In this case we should be able to retrieve the css directly
|
21
|
+
# from sprockets
|
22
|
+
if tag.attributes['href'].to_s =~ /\/assets\//
|
23
|
+
link_uri = process_stylesheet_url(tag.attributes['href'])
|
24
|
+
asset = Rails.application.assets.find_asset(link_uri)
|
25
|
+
@css_parser.add_block!(asset.body) if asset
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def process_stylesheet_url(href)
|
33
|
+
# Example stylesheet url: email-1bd4488901bfc2f2ccf4f044fc9154a6.css
|
34
|
+
href = href.to_s.sub(/\?[0-9a-zA-Z]+$/, '').sub(/^\/assets\//, '')
|
35
|
+
|
36
|
+
if href =~ /(\w+)\-(?:[0-9a-zA-Z]{32})\.([a-z]{3})/
|
37
|
+
href = href.gsub(/(\w+)\-(?:[0-9a-zA-Z]{32})\.([a-z]{3})/, [$1,$2].join('.'))
|
38
|
+
end
|
39
|
+
|
40
|
+
return href
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require "premailer"
|
2
|
+
|
3
|
+
module ActionMailer
|
4
|
+
module InStyle
|
5
|
+
class Processor
|
6
|
+
|
7
|
+
def self.inline!(message)
|
8
|
+
new(message).inline!
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :message, :premailer
|
12
|
+
|
13
|
+
# Initialize
|
14
|
+
# Accepts one argument:
|
15
|
+
# - ActionMailer message object
|
16
|
+
def initialize(message)
|
17
|
+
@message = message
|
18
|
+
|
19
|
+
@existing_html_part = message.html_part || (message.content_type =~ /text\/html/ && message)
|
20
|
+
@premailer = ActionMailer::InStyle::Premailer.new(html_part.body.to_s, :with_html_string => true, :remove_classes => true)
|
21
|
+
end
|
22
|
+
|
23
|
+
def html_part
|
24
|
+
@existing_html_part
|
25
|
+
end
|
26
|
+
|
27
|
+
# InStyle!
|
28
|
+
# Processes the message object, replacing the html part with an inlined
|
29
|
+
# html version.
|
30
|
+
#
|
31
|
+
# If the message contains attachments or text parts, these parts are preserved.
|
32
|
+
# If the message does not contain a text part, one will be constructed from the text
|
33
|
+
# content available in the html part.
|
34
|
+
def inline!
|
35
|
+
capture_existing_message_parts
|
36
|
+
reset_message_body!
|
37
|
+
|
38
|
+
add_text_part!
|
39
|
+
add_html_part!
|
40
|
+
add_attachments!
|
41
|
+
|
42
|
+
message
|
43
|
+
end
|
44
|
+
|
45
|
+
# Add an HTML part with CSS inlined.
|
46
|
+
def add_html_part!
|
47
|
+
part = Mail::Part.new
|
48
|
+
part.body = premailer.to_inline_css
|
49
|
+
part.content_type = "text/html; charset=#{@msg_charset}"
|
50
|
+
message.html_part = part
|
51
|
+
end
|
52
|
+
|
53
|
+
# Add a text part with either the pre-existing text part, or one generated with premailer.
|
54
|
+
def add_text_part!
|
55
|
+
part = Mail::Part.new
|
56
|
+
part.body = @existing_text_part || premailer.to_plain_text
|
57
|
+
part.content_type = "text/plain; charset=#{@msg_charset}"
|
58
|
+
message.text_part = part
|
59
|
+
end
|
60
|
+
|
61
|
+
# Re-add any attachments
|
62
|
+
def add_attachments!
|
63
|
+
@existing_attachments.each {|a| message.body << a }
|
64
|
+
end
|
65
|
+
|
66
|
+
def capture_existing_message_parts
|
67
|
+
@existing_text_part = message.text_part && message.text_part.body.to_s
|
68
|
+
@existing_attachments = message.attachments
|
69
|
+
@msg_charset = message.charset
|
70
|
+
end
|
71
|
+
|
72
|
+
def original_message_parts
|
73
|
+
capture_existing_message_parts
|
74
|
+
|
75
|
+
{
|
76
|
+
:html_part => html_part,
|
77
|
+
:text_part => @existing_text_part,
|
78
|
+
:attachments => @existing_attachments,
|
79
|
+
:charset => @msg_charset
|
80
|
+
}
|
81
|
+
end
|
82
|
+
|
83
|
+
def reset_message_body!
|
84
|
+
message.body = nil
|
85
|
+
message.body.instance_variable_set("@parts", Mail::PartsList.new)
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require "action_mailer/in_style"
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class NotificationMailer < ActionMailer::Base
|
2
|
+
layout "notification_mailer"
|
3
|
+
|
4
|
+
default :from => "Johnny Quids<quidlicker@example.com>"
|
5
|
+
|
6
|
+
def welcome_email
|
7
|
+
mail(:to => "archie@example.com", :subject => "We need dry ice")
|
8
|
+
end
|
9
|
+
|
10
|
+
def email_with_html_only
|
11
|
+
mail(:to => "archie@example.com", :subject => "We need dry ice")
|
12
|
+
end
|
13
|
+
|
14
|
+
def welcome_html_email
|
15
|
+
mail(:to => "archie@example.com", :subject => "We need dry ice")
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class NotificationMailerNoStyle < ActionMailer::Base
|
2
|
+
layout "notification_mailer_without_style"
|
3
|
+
|
4
|
+
default :from => "Johnny Quids<quidlicker@example.com>"
|
5
|
+
|
6
|
+
def email_with_no_style
|
7
|
+
mail(:to => "archie@example.com", :subject => "We need dry ice")
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
4
|
+
|
5
|
+
<title>Notification_mailer.html</title>
|
6
|
+
<%#= stylesheet_link_tag "notification_mailer" %>
|
7
|
+
<link rel="stylesheet" href="/assets/notification_mailer-1bd4488901bfc2f2ccf4f044fc9154a6.css" />
|
8
|
+
</head>
|
9
|
+
|
10
|
+
<body>
|
11
|
+
<%= yield %>
|
12
|
+
</body>
|
13
|
+
</html>
|
14
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
Welcome this is a TEXT email
|
@@ -0,0 +1 @@
|
|
1
|
+
*.log
|
File without changes
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe ActionMailer::InStyle do
|
4
|
+
describe "CSS" do
|
5
|
+
it "Should return a CSS String" do
|
6
|
+
Rails.application.assets.find_asset('notification_mailer.css.scss').body.should match /font-family: 'Helvetica Neue', Helvetica, Ariel, sans-serif/
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe ActionMailer::InStyle::Premailer do
|
4
|
+
it 'it should handle stylesheet links containing cache token' do
|
5
|
+
ActionMailer::InStyle::Premailer.new('', :with_html_string => true, :remove_classes => true).process_stylesheet_url('/assets/email.css?jf87kjJHj787JHJGH').should == 'email.css'
|
6
|
+
end
|
7
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe ActionMailer::InStyle::Processor do
|
4
|
+
|
5
|
+
before do
|
6
|
+
ActionMailer::InStyle.stub(:delivering_email).and_return(message)
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:message) { NotificationMailer.welcome_html_email.deliver }
|
10
|
+
let(:processor) { ActionMailer::InStyle::Processor.new(message) }
|
11
|
+
|
12
|
+
describe :message do
|
13
|
+
it "should have a html part" do
|
14
|
+
message.html_part.should_not be_nil
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should initialize with a message object" do
|
19
|
+
processor.message.should == message
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should reset message body so we can replace it with the processed body" do
|
23
|
+
processor.message.should_receive(:body=).with(nil).once
|
24
|
+
processor.reset_message_body!
|
25
|
+
end
|
26
|
+
|
27
|
+
it "captures original html part" do
|
28
|
+
processor.original_message_parts[:html_part].should be_a Mail::Part
|
29
|
+
end
|
30
|
+
|
31
|
+
it "captures original text part" do
|
32
|
+
processor.original_message_parts[:text_part].should be_a String
|
33
|
+
end
|
34
|
+
|
35
|
+
it "captures original attachments" do
|
36
|
+
processor.original_message_parts[:attachments].should be_empty
|
37
|
+
end
|
38
|
+
|
39
|
+
it "captures message charset" do
|
40
|
+
processor.original_message_parts[:charset].should == 'UTF-8'
|
41
|
+
end
|
42
|
+
|
43
|
+
describe 'message' do
|
44
|
+
it 'should have two parts' do
|
45
|
+
message.parts.size.should == 2
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe 'html part' do
|
50
|
+
def parse_html_to_doc(html)
|
51
|
+
Nokogiri::HTML(html)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should have a html part' do
|
55
|
+
processor.html_part.should be_a Mail::Part
|
56
|
+
processor.html_part.body.should_not be_nil
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should include asset path for stylesheet in header' do
|
60
|
+
processor.html_part.body.should match /\<link(.+)href\=\"\/assets\/(\w+)\-(?:[0-9a-zA-Z]{32})\.([a-z]{3})\"(.+)\>/
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should have inlined css version without stylesheet links' do
|
64
|
+
processor.premailer.to_inline_css.should_not match /\<link(.+)href\=\"\/assets\/notification_mailer\.css\?(\w+)\"(.+)\>/
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'replaces html body with inlined css version' do
|
68
|
+
processor.inline!
|
69
|
+
processor.html_part.body.should_not be_nil
|
70
|
+
parse_html_to_doc(processor.premailer.to_inline_css).css('body')[0].attributes['style'].to_s.should == "font-family: 'Helvetica Neue', Helvetica, Ariel, sans-serif; font-size: 13px; color: #4d4d4d;"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe ActionMailer::InStyle do
|
4
|
+
it "is included in Mail interceptors" do
|
5
|
+
Mail.class_variable_get("@@delivery_interceptors").should include ActionMailer::InStyle
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:original_message) { NotificationMailer.welcome_html_email.deliver }
|
9
|
+
let(:message) { ActionMailer::InStyle.delivering_email(original_message) }
|
10
|
+
|
11
|
+
it "should keep text version of email if present" do
|
12
|
+
original_message.text_part.body.to_s.should == message.text_part.body.to_s
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should have two body parts" do
|
16
|
+
message.parts.size.should == 2
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should not have a style tag in original email" do
|
20
|
+
ActionMailer::InStyle.should_receive(:delivering_email).once
|
21
|
+
original_message = NotificationMailer.welcome_html_email.deliver
|
22
|
+
Nokogiri::HTML(original_message.html_part.body.to_s).css('body').first.attributes['style'].should be_nil
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should replace html version with premailer processed inline version" do
|
26
|
+
# If it has a style attribue then we have processed it
|
27
|
+
Nokogiri::HTML(message.html_part.body.to_s).css('body').first.attributes['style'].should_not be_nil
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should find stylesheet assets" do
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should not do anything if no stylesheets are present" do
|
35
|
+
message_with_no_css = ActionMailer::InStyle.delivering_email(NotificationMailerNoStyle.email_with_no_style.deliver)
|
36
|
+
Nokogiri::HTML(message_with_no_css.html_part.body.to_s).css('body').first.attributes['style'].should be_nil
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should inline stylesheets and replace IDs and Classes" do
|
40
|
+
# According to the email template the first table usually has a 'striped' class
|
41
|
+
Nokogiri::HTML(message.html_part.body.to_s).css('table').first.attributes['class'].should be_nil
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should create a text part from the html part if not present" do
|
45
|
+
message = ActionMailer::InStyle.delivering_email(NotificationMailer.email_with_html_only.deliver)
|
46
|
+
message.text_part.body.to_s.should == "Welcome, this is a HTML email\n\nAnother line"
|
47
|
+
end
|
48
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
|
4
|
+
Bundler.require
|
5
|
+
|
6
|
+
require "rails"
|
7
|
+
require "combustion"
|
8
|
+
|
9
|
+
Combustion.initialize!
|
10
|
+
|
11
|
+
require 'rspec/rails'
|
12
|
+
|
13
|
+
require 'nokogiri'
|
14
|
+
require "combustion"
|
15
|
+
|
16
|
+
require 'action_mailer/in_style'
|
17
|
+
|
18
|
+
RSpec.configure do |config|
|
19
|
+
config.mock_with :rspec
|
20
|
+
|
21
|
+
config.before do
|
22
|
+
ActionMailer::Base.delivery_method = :test
|
23
|
+
end
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,253 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: actionmailer-instyle4
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.4
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Robin Joseph
|
8
|
+
- Ivan Vanderbyl
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-07-18 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: nokogiri
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.6'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '1.6'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: premailer
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '1.7'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '1.7'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: actionmailer
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '3.1'
|
49
|
+
type: :runtime
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '3.1'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: activesupport
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '3.1'
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '3.1'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: sprockets
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '2.0'
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '2.0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: rspec-rails
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - "~>"
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 2.8.0
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - "~>"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: 2.8.0
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: guard-rspec
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
type: :development
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: sass
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - "~>"
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '3.1'
|
119
|
+
type: :development
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - "~>"
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '3.1'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: sqlite3
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: 1.3.5
|
133
|
+
type: :development
|
134
|
+
prerelease: false
|
135
|
+
version_requirements: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: 1.3.5
|
140
|
+
- !ruby/object:Gem::Dependency
|
141
|
+
name: mail
|
142
|
+
requirement: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
type: :development
|
148
|
+
prerelease: false
|
149
|
+
version_requirements: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - ">="
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
154
|
+
- !ruby/object:Gem::Dependency
|
155
|
+
name: combustion
|
156
|
+
requirement: !ruby/object:Gem::Requirement
|
157
|
+
requirements:
|
158
|
+
- - "~>"
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: 0.3.1
|
161
|
+
type: :development
|
162
|
+
prerelease: false
|
163
|
+
version_requirements: !ruby/object:Gem::Requirement
|
164
|
+
requirements:
|
165
|
+
- - "~>"
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
version: 0.3.1
|
168
|
+
description: Easily create HTML emails in Rails ~>3.1
|
169
|
+
email:
|
170
|
+
- robin.joseph@me.com
|
171
|
+
executables: []
|
172
|
+
extensions: []
|
173
|
+
extra_rdoc_files: []
|
174
|
+
files:
|
175
|
+
- ".gitignore"
|
176
|
+
- ".rspec"
|
177
|
+
- Gemfile
|
178
|
+
- Guardfile
|
179
|
+
- LICENSE
|
180
|
+
- README.md
|
181
|
+
- Rakefile
|
182
|
+
- actionmailer-instyle4.gemspec
|
183
|
+
- config.ru
|
184
|
+
- lib/action_mailer/in_style.rb
|
185
|
+
- lib/action_mailer/in_style/premailer.rb
|
186
|
+
- lib/action_mailer/in_style/processor.rb
|
187
|
+
- lib/action_mailer/in_style/version.rb
|
188
|
+
- lib/action_mailer/instyle.rb
|
189
|
+
- lib/actionmailer-instyle.rb
|
190
|
+
- spec/internal/app/assets/stylesheets/notification_mailer.css.scss
|
191
|
+
- spec/internal/app/mailers/notification_mailer.rb
|
192
|
+
- spec/internal/app/mailers/notification_mailer_no_layout.rb
|
193
|
+
- spec/internal/app/views/layouts/notification_mailer.html.erb
|
194
|
+
- spec/internal/app/views/layouts/notification_mailer_without_style.html.erb
|
195
|
+
- spec/internal/app/views/notification_mailer/email_with_html_only.html.erb
|
196
|
+
- spec/internal/app/views/notification_mailer/welcome_html_email.html.erb
|
197
|
+
- spec/internal/app/views/notification_mailer/welcome_html_email.text.erb
|
198
|
+
- spec/internal/app/views/notification_mailer_no_style/email_with_no_style.html.erb
|
199
|
+
- spec/internal/config/database.yml
|
200
|
+
- spec/internal/config/routes.rb
|
201
|
+
- spec/internal/db/schema.rb
|
202
|
+
- spec/internal/log/.gitignore
|
203
|
+
- spec/internal/public/favicon.ico
|
204
|
+
- spec/lib/action_mailer/inline/css_helper_spec.rb
|
205
|
+
- spec/lib/action_mailer/inline/premailer_spec.rb
|
206
|
+
- spec/lib/action_mailer/inline/processor_spec.rb
|
207
|
+
- spec/lib/action_mailer/inline_spec.rb
|
208
|
+
- spec/spec_helper.rb
|
209
|
+
homepage: http://github.com/robinjoseph08/actionmailer-instyle4
|
210
|
+
licenses: []
|
211
|
+
metadata: {}
|
212
|
+
post_install_message:
|
213
|
+
rdoc_options: []
|
214
|
+
require_paths:
|
215
|
+
- lib
|
216
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
217
|
+
requirements:
|
218
|
+
- - ">="
|
219
|
+
- !ruby/object:Gem::Version
|
220
|
+
version: '0'
|
221
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
222
|
+
requirements:
|
223
|
+
- - ">="
|
224
|
+
- !ruby/object:Gem::Version
|
225
|
+
version: '0'
|
226
|
+
requirements: []
|
227
|
+
rubyforge_project:
|
228
|
+
rubygems_version: 2.4.1
|
229
|
+
signing_key:
|
230
|
+
specification_version: 4
|
231
|
+
summary: This gem brings you the power of the premailer gem to Rails 4 without any
|
232
|
+
configuration needs. Create HTML emails, include a CSS file as you do in a normal
|
233
|
+
HTML document and premailer will inline the included CSS.
|
234
|
+
test_files:
|
235
|
+
- spec/internal/app/assets/stylesheets/notification_mailer.css.scss
|
236
|
+
- spec/internal/app/mailers/notification_mailer.rb
|
237
|
+
- spec/internal/app/mailers/notification_mailer_no_layout.rb
|
238
|
+
- spec/internal/app/views/layouts/notification_mailer.html.erb
|
239
|
+
- spec/internal/app/views/layouts/notification_mailer_without_style.html.erb
|
240
|
+
- spec/internal/app/views/notification_mailer/email_with_html_only.html.erb
|
241
|
+
- spec/internal/app/views/notification_mailer/welcome_html_email.html.erb
|
242
|
+
- spec/internal/app/views/notification_mailer/welcome_html_email.text.erb
|
243
|
+
- spec/internal/app/views/notification_mailer_no_style/email_with_no_style.html.erb
|
244
|
+
- spec/internal/config/database.yml
|
245
|
+
- spec/internal/config/routes.rb
|
246
|
+
- spec/internal/db/schema.rb
|
247
|
+
- spec/internal/log/.gitignore
|
248
|
+
- spec/internal/public/favicon.ico
|
249
|
+
- spec/lib/action_mailer/inline/css_helper_spec.rb
|
250
|
+
- spec/lib/action_mailer/inline/premailer_spec.rb
|
251
|
+
- spec/lib/action_mailer/inline/processor_spec.rb
|
252
|
+
- spec/lib/action_mailer/inline_spec.rb
|
253
|
+
- spec/spec_helper.rb
|