premailer-rails 1.5.1 → 1.6.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.
- checksums.yaml +4 -4
- data/.travis.yml +11 -1
- data/CHANGELOG.md +16 -0
- data/Gemfile +10 -0
- data/README.md +82 -40
- data/VERSION +1 -1
- data/lib/premailer/rails.rb +1 -2
- data/lib/premailer/rails/css_helper.rb +8 -20
- data/lib/premailer/rails/css_loaders.rb +4 -63
- data/lib/premailer/rails/css_loaders/asset_pipeline_loader.rb +27 -0
- data/lib/premailer/rails/css_loaders/cache_loader.rb +19 -0
- data/lib/premailer/rails/css_loaders/file_system_loader.rb +15 -0
- data/lib/premailer/rails/css_loaders/network_loader.rb +32 -0
- data/lib/premailer/rails/hook.rb +12 -3
- data/premailer-rails.gemspec +4 -6
- data/spec/integration/css_helper_spec.rb +168 -0
- data/spec/{lib → integration}/hook_registration_spec.rb +2 -3
- data/spec/{lib → integration}/hook_spec.rb +26 -10
- data/spec/spec_helper.rb +17 -5
- data/spec/{fixtures → support/fixtures}/html.rb +0 -8
- data/spec/{fixtures → support/fixtures}/message.rb +0 -0
- data/spec/{stubs → support/stubs}/action_mailer.rb +0 -0
- data/spec/{stubs → support/stubs}/rails.rb +0 -26
- data/spec/unit/css_loaders/asset_pipeline_loader_spec.rb +30 -0
- data/spec/{lib → unit}/customized_premailer_spec.rb +12 -13
- data/spec/{lib/premailer_rails_3_spec.rb → unit/premailer_rails_spec.rb} +0 -0
- metadata +44 -56
- data/spec/lib/css_helper_spec.rb +0 -164
- data/spec/stubs/dummy.rb +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5a2073ed1c61cca54326ea63233c597afc05673a
|
4
|
+
data.tar.gz: 8a067a0516b3ff404ead0d70b147408a0ca88dea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 613d3feeeceb8be28f49e32c656b945d98ce23b6b22ef597e063a519a3e798e250e8ae80fe0a2bcd700acd6ee6b13efbdf92bf9813266c61aa0ef147d9fc4e45
|
7
|
+
data.tar.gz: 869483a1f22ae2e38587eb73f763fa11f430271c74a30f0ebdbb08164893113dd962027b43524abec789467481209e764d98cfb4798305b1c9662975a5ed8fa2
|
data/.travis.yml
CHANGED
@@ -1,8 +1,18 @@
|
|
1
1
|
language: ruby
|
2
|
+
cache: bundler
|
2
3
|
script: "bundle exec rspec"
|
3
4
|
rvm:
|
4
5
|
- 2.0.0
|
5
6
|
- 1.9.3
|
7
|
+
- ruby-head
|
6
8
|
- jruby-19mode
|
7
9
|
- rbx-19mode
|
8
|
-
env:
|
10
|
+
env:
|
11
|
+
- "ACTION_MAILER_VERSION=3.1.0"
|
12
|
+
- "ACTION_MAILER_VERSION=3.2.0"
|
13
|
+
- "ACTION_MAILER_VERSION=4.0.0"
|
14
|
+
- "ACTION_MAILER_VERSION=head"
|
15
|
+
matrix:
|
16
|
+
allow_failures:
|
17
|
+
- env: "ACTION_MAILER_VERSION=head"
|
18
|
+
- rvm: ruby-head
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## v1.6.0
|
4
|
+
|
5
|
+
- Only use asset pipeline if Rails is defined and if compile is true
|
6
|
+
|
7
|
+
- Depend on actionmailer instead of rails
|
8
|
+
|
9
|
+
- Check whether `::Rails` is defined before using it
|
10
|
+
|
11
|
+
- Add ability to skip premailer
|
12
|
+
|
13
|
+
- Test against multiple action mailer versions on travis
|
14
|
+
|
15
|
+
- Ensure CSS strings are always UTF-8 encoded
|
16
|
+
|
17
|
+
- Require premailer version >= 1.7.9
|
18
|
+
|
3
19
|
## v1.5.1
|
4
20
|
|
5
21
|
- Prefer precompiled assets over asset pipeline
|
data/Gemfile
CHANGED
@@ -2,6 +2,16 @@ source "https://rubygems.org"
|
|
2
2
|
|
3
3
|
gemspec
|
4
4
|
|
5
|
+
action_mailer_version = ENV.fetch('ACTION_MAILER_VERSION', '4.0')
|
6
|
+
|
7
|
+
if action_mailer_version == 'head'
|
8
|
+
git 'git://github.com/rails/rails.git' do
|
9
|
+
gem 'actionmailer'
|
10
|
+
end
|
11
|
+
else
|
12
|
+
gem 'actionmailer', "~> #{action_mailer_version}"
|
13
|
+
end
|
14
|
+
|
5
15
|
platforms :jruby do
|
6
16
|
gem "jruby-openssl"
|
7
17
|
end
|
data/README.md
CHANGED
@@ -1,78 +1,120 @@
|
|
1
1
|
# premailer-rails
|
2
2
|
|
3
|
-
|
4
|
-
[](http://badge.fury.io/rb/premailer-rails)
|
5
|
-
[](https://gemnasium.com/fphilipe/premailer-rails)
|
6
|
-
[](https://codeclimate.com/github/fphilipe/premailer-rails)
|
3
|
+
CSS styled emails without the hassle.
|
7
4
|
|
8
|
-
|
9
|
-
|
5
|
+
[![Build Status][build-image]][build-link]
|
6
|
+
[![Gem Version][gem-image]][gem-link]
|
7
|
+
[![Dependency Status][deps-image]][deps-link]
|
8
|
+
[![Code Climate][gpa-image]][gpa-link]
|
9
|
+
[![Coverage Status][cov-image]][cov-link]
|
10
|
+
[![Bitdeli Badge][stats-image]][stats-link]
|
10
11
|
|
11
|
-
|
12
|
+
## Introduction
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
```
|
14
|
+
This gem is a drop in solution for styling HTML emails with CSS without having
|
15
|
+
to do the hard work yourself.
|
16
16
|
|
17
|
-
|
17
|
+
Styling emails is not just a matter of linking to a stylesheet. Most clients,
|
18
|
+
especially web clients, ignore linked stylesheets or `<style>` tags in the HTML.
|
19
|
+
The workaround is to write all the CSS rules in the `style` attribute of each
|
20
|
+
tag inside your email. This is a rather tedious and hard to maintain approach.
|
18
21
|
|
19
|
-
The
|
22
|
+
Premailer to the rescue! The great [premailer] gem applies all CSS rules to each
|
23
|
+
matching HTML element by adding them to the `style` attribute. This allows you
|
24
|
+
to keep HTML and CSS in separate files, just as you're used to from web
|
25
|
+
development, thus keeping your sanity.
|
20
26
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
27
|
+
This gem is an adapter for premailer to work with [actionmailer] out of the box.
|
28
|
+
Actionmailer is the email framework used in Rails, which also works outside of
|
29
|
+
Rails. Although premailer-rails has certain Rails specific features, **it also
|
30
|
+
works in the absence of Rails** making it compatible with other frameworks such
|
31
|
+
as sinatra.
|
25
32
|
|
26
|
-
|
27
|
-
|
33
|
+
premailer-rails works with actionmailer by registering a delivery hook. This
|
34
|
+
causes all emails that are delivered to be processed by premailer-rails. This
|
35
|
+
means that, by simply including premailer-rails in your `Gemfile`, you'll get
|
36
|
+
styled emails without having to set anything up.
|
28
37
|
|
29
38
|
## Installation
|
30
39
|
|
31
|
-
Simply add the gem to your Gemfile
|
40
|
+
Simply add the gem to your `Gemfile`:
|
32
41
|
|
33
|
-
|
42
|
+
```ruby
|
43
|
+
gem 'premailer-rails'
|
44
|
+
```
|
34
45
|
|
35
|
-
premailer-rails requires either nokogiri or hpricot. It doesn't list them as
|
46
|
+
premailer-rails requires either [nokogiri] or [hpricot]. It doesn't list them as
|
47
|
+
a dependency so you can choose which one to use. Since hpricot is no longer
|
48
|
+
maintained, I suggest you to go with nokogiri. Add either one to your `Gemfile`:
|
36
49
|
|
37
|
-
|
38
|
-
|
39
|
-
|
50
|
+
```ruby
|
51
|
+
gem 'nokogiri'
|
52
|
+
# or
|
53
|
+
gem 'hpricot'
|
54
|
+
```
|
40
55
|
|
41
|
-
If both are loaded for some reason, premailer chooses hpricot.
|
56
|
+
If both gems are loaded for some reason, premailer chooses hpricot.
|
42
57
|
|
43
58
|
That's it!
|
44
59
|
|
45
60
|
## Configuration
|
46
61
|
|
47
62
|
Premailer itself accepts a number of options. In order for premailer-rails to
|
48
|
-
pass these options on to the underlying premailer instance, specify them
|
49
|
-
initializer
|
63
|
+
pass these options on to the underlying premailer instance, specify them
|
64
|
+
as follows (in Rails you could do that in an initializer such as
|
65
|
+
`config/initializers/premailer_rails.rb`):
|
50
66
|
|
51
67
|
```ruby
|
52
|
-
Premailer::Rails.config.merge!(preserve_styles: true,
|
53
|
-
remove_ids: true)
|
68
|
+
Premailer::Rails.config.merge!(preserve_styles: true, remove_ids: true)
|
54
69
|
```
|
55
70
|
|
56
|
-
For a list of options, refer to the [
|
57
|
-
|
58
|
-
The default configs are:
|
71
|
+
For a list of options, refer to the [premailer documentation]. The default
|
72
|
+
configs are:
|
59
73
|
|
60
74
|
```ruby
|
61
75
|
{
|
62
|
-
input_encoding:
|
63
|
-
inputencoding: 'UTF-8',
|
76
|
+
input_encoding: 'UTF-8',
|
64
77
|
generate_text_part: true
|
65
78
|
}
|
66
79
|
```
|
67
80
|
|
68
|
-
|
69
|
-
|
70
|
-
If you want to use another encoding make sure to specify the right one or both.
|
81
|
+
If you don't want to automatically generate a text part from the html part, set
|
82
|
+
the config `:generate_text_part` to false.
|
71
83
|
|
72
|
-
|
84
|
+
Note that the options `:with_html_string` and `:css_string` are used internally
|
85
|
+
by premailer-rails and thus will be overridden.
|
73
86
|
|
74
|
-
|
87
|
+
## Usage
|
75
88
|
|
89
|
+
premailer-rails processes all outgoing emails by default. If you wish to skip
|
90
|
+
premailer for a certain email, simply set the `:skip_premailer` header:
|
76
91
|
|
77
|
-
|
92
|
+
```ruby
|
93
|
+
class UserMailer < ActionMailer::Base
|
94
|
+
def welcome_email(user)
|
95
|
+
mail to: user.email,
|
96
|
+
subject: 'Welcome to My Awesome Site',
|
97
|
+
skip_premailer: true
|
98
|
+
end
|
99
|
+
end
|
100
|
+
```
|
78
101
|
|
102
|
+
[build-image]: https://travis-ci.org/fphilipe/premailer-rails.png
|
103
|
+
[build-link]: https://travis-ci.org/fphilipe/premailer-rails
|
104
|
+
[gem-image]: https://badge.fury.io/rb/premailer-rails.png
|
105
|
+
[gem-link]: https://rubygems.org/gems/premailer-rails
|
106
|
+
[deps-image]: https://gemnasium.com/fphilipe/premailer-rails.png
|
107
|
+
[deps-link]: https://gemnasium.com/fphilipe/premailer-rails
|
108
|
+
[gpa-image]: https://codeclimate.com/github/fphilipe/premailer-rails.png
|
109
|
+
[gpa-link]: https://codeclimate.com/github/fphilipe/premailer-rails
|
110
|
+
[cov-image]: https://coveralls.io/repos/fphilipe/premailer-rails/badge.png
|
111
|
+
[cov-link]: https://coveralls.io/r/fphilipe/premailer-rails
|
112
|
+
[stats-image]: https://d2weczhvl823v0.cloudfront.net/fphilipe/premailer-rails/trend.png
|
113
|
+
[stats-link]: https://bitdeli.com/
|
114
|
+
|
115
|
+
[premailer]: https://github.com/premailer/premailer
|
116
|
+
[actionmailer]: https://github.com/rails/rails/tree/master/actionmailer
|
117
|
+
[nokogiri]: https://github.com/sparklemotion/nokogiri
|
118
|
+
[hpricot]: https://github.com/hpricot/hpricot
|
119
|
+
|
120
|
+
[premailer documentation]: http://rubydoc.info/gems/premailer/1.7.3/Premailer:initialize
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.6.0
|
data/lib/premailer/rails.rb
CHANGED
@@ -9,13 +9,14 @@ class Premailer
|
|
9
9
|
STRATEGIES = [
|
10
10
|
CSSLoaders::CacheLoader,
|
11
11
|
CSSLoaders::FileSystemLoader,
|
12
|
-
CSSLoaders::AssetPipelineLoader
|
12
|
+
CSSLoaders::AssetPipelineLoader,
|
13
|
+
CSSLoaders::NetworkLoader
|
13
14
|
]
|
14
15
|
|
15
16
|
# Returns all linked CSS files concatenated as string.
|
16
17
|
def css_for_doc(doc)
|
17
18
|
urls = css_urls_in_doc(doc)
|
18
|
-
urls.map { |url| load_css(url) }.join("\n")
|
19
|
+
urls.map { |url| load_css(url).force_encoding('UTF-8') }.join("\n")
|
19
20
|
end
|
20
21
|
|
21
22
|
private
|
@@ -27,24 +28,11 @@ class Premailer
|
|
27
28
|
end
|
28
29
|
|
29
30
|
def load_css(url)
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
# Extracts the path of a url.
|
39
|
-
def extract_path(url)
|
40
|
-
if url.is_a? String
|
41
|
-
# Remove everything after ? including ?
|
42
|
-
url = url[0..(url.index('?') - 1)] if url.include? '?'
|
43
|
-
# Remove the host
|
44
|
-
url = url.sub(/^https?\:\/\/[^\/]*/, '') if url.index('http') == 0
|
45
|
-
end
|
46
|
-
|
47
|
-
url
|
31
|
+
@cache[url] =
|
32
|
+
STRATEGIES.each do |strategy|
|
33
|
+
css = strategy.load(url)
|
34
|
+
break css if css
|
35
|
+
end
|
48
36
|
end
|
49
37
|
end
|
50
38
|
end
|
@@ -1,65 +1,6 @@
|
|
1
1
|
require 'uri'
|
2
|
-
require 'zlib'
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
module CacheLoader
|
9
|
-
extend self
|
10
|
-
|
11
|
-
def load(path)
|
12
|
-
unless ::Rails.env.development?
|
13
|
-
CSSHelper.cache[path]
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
# Loads the CSS from the asset pipeline.
|
19
|
-
module AssetPipelineLoader
|
20
|
-
extend self
|
21
|
-
|
22
|
-
def load(path)
|
23
|
-
if assets_enabled?
|
24
|
-
file = file_name(path)
|
25
|
-
if asset = ::Rails.application.assets.find_asset(file)
|
26
|
-
asset.to_s
|
27
|
-
else
|
28
|
-
Net::HTTP.get(uri_for_path(path))
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def assets_enabled?
|
34
|
-
::Rails.configuration.assets.enabled rescue false
|
35
|
-
end
|
36
|
-
|
37
|
-
def file_name(path)
|
38
|
-
path
|
39
|
-
.sub("#{::Rails.configuration.assets.prefix}/", '')
|
40
|
-
.sub(/-\h{32}\.css$/, '.css')
|
41
|
-
end
|
42
|
-
|
43
|
-
def uri_for_path(path)
|
44
|
-
URI(path).tap do |uri|
|
45
|
-
scheme, host =
|
46
|
-
::Rails.configuration.action_controller.asset_host.split(%r{:?//})
|
47
|
-
scheme = 'http' if scheme.blank?
|
48
|
-
uri.scheme ||= scheme
|
49
|
-
uri.host ||= host
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
# Loads the CSS from the file system.
|
55
|
-
module FileSystemLoader
|
56
|
-
extend self
|
57
|
-
|
58
|
-
def load(path)
|
59
|
-
file_path = "#{::Rails.root}/public#{path}"
|
60
|
-
File.read(file_path) if File.exist?(file_path)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
3
|
+
require 'premailer/rails/css_loaders/cache_loader'
|
4
|
+
require 'premailer/rails/css_loaders/file_system_loader'
|
5
|
+
require 'premailer/rails/css_loaders/asset_pipeline_loader'
|
6
|
+
require 'premailer/rails/css_loaders/network_loader'
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class Premailer
|
2
|
+
module Rails
|
3
|
+
module CSSLoaders
|
4
|
+
module AssetPipelineLoader
|
5
|
+
extend self
|
6
|
+
|
7
|
+
def load(url)
|
8
|
+
if asset_pipeline_present?
|
9
|
+
file = file_name(url)
|
10
|
+
asset = ::Rails.application.assets.find_asset(file)
|
11
|
+
asset.to_s if asset
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def asset_pipeline_present?
|
16
|
+
defined?(::Rails) and ::Rails.application.respond_to?(:assets)
|
17
|
+
end
|
18
|
+
|
19
|
+
def file_name(url)
|
20
|
+
URI(url).path
|
21
|
+
.sub("#{::Rails.configuration.assets.prefix}/", '')
|
22
|
+
.sub(/-\h{32}\.css$/, '.css')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class Premailer
|
2
|
+
module Rails
|
3
|
+
module CSSLoaders
|
4
|
+
module CacheLoader
|
5
|
+
extend self
|
6
|
+
|
7
|
+
def load(url)
|
8
|
+
unless development_env?
|
9
|
+
CSSHelper.cache[url]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def development_env?
|
14
|
+
defined?(::Rails) and ::Rails.env.development?
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class Premailer
|
2
|
+
module Rails
|
3
|
+
module CSSLoaders
|
4
|
+
module NetworkLoader
|
5
|
+
extend self
|
6
|
+
|
7
|
+
def load(url)
|
8
|
+
uri = uri_for_url(url)
|
9
|
+
Net::HTTP.get(uri) if uri
|
10
|
+
end
|
11
|
+
|
12
|
+
def uri_for_url(url)
|
13
|
+
uri = URI(url)
|
14
|
+
|
15
|
+
if not valid_uri?(uri) and defined?(::Rails)
|
16
|
+
scheme, host =
|
17
|
+
::Rails.configuration.action_controller.asset_host.split(%r{:?//})
|
18
|
+
scheme = 'http' if scheme.blank?
|
19
|
+
uri.scheme ||= scheme
|
20
|
+
uri.host ||= host
|
21
|
+
end
|
22
|
+
|
23
|
+
uri if valid_uri?(uri)
|
24
|
+
end
|
25
|
+
|
26
|
+
def valid_uri?(uri)
|
27
|
+
uri.host.present? && uri.scheme.present?
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|