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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c14b05b4d57365b47366c6c56d7080ed7610bb0e
4
- data.tar.gz: 3bb5ba65597cc2fe6d40fc053785683ad0e08d69
3
+ metadata.gz: 5a2073ed1c61cca54326ea63233c597afc05673a
4
+ data.tar.gz: 8a067a0516b3ff404ead0d70b147408a0ca88dea
5
5
  SHA512:
6
- metadata.gz: af255aab35b0a2ebbbe9fc554d45bbf190878531ba2faef489cc88dcc4d1b40031713da7a21f8cdbbc1cdc49fdd8e96ca32ac2a3f439f40af4602fc3874c4bbc
7
- data.tar.gz: 7aed5714d084a540a096da8df6606894d68616dbcfe1de3fb9bdcaee3eeb61624c2f1377064a850c10c6e454926ef8fda3815fc8aaca635f1398b5bd4e8c2046
6
+ metadata.gz: 613d3feeeceb8be28f49e32c656b945d98ce23b6b22ef597e063a519a3e798e250e8ae80fe0a2bcd700acd6ee6b13efbdf92bf9813266c61aa0ef147d9fc4e45
7
+ data.tar.gz: 869483a1f22ae2e38587eb73f763fa11f430271c74a30f0ebdbb08164893113dd962027b43524abec789467481209e764d98cfb4798305b1c9662975a5ed8fa2
@@ -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: "JRUBY_OPTS=--debug"
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
@@ -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
- [![Build Status](https://travis-ci.org/fphilipe/premailer-rails.png)](https://travis-ci.org/fphilipe/premailer-rails)
4
- [![Gem Version](https://badge.fury.io/rb/premailer-rails.png)](http://badge.fury.io/rb/premailer-rails)
5
- [![Dependency Status](https://gemnasium.com/fphilipe/premailer-rails.png)](https://gemnasium.com/fphilipe/premailer-rails)
6
- [![Code Climate](https://codeclimate.com/github/fphilipe/premailer-rails.png)](https://codeclimate.com/github/fphilipe/premailer-rails)
3
+ CSS styled emails without the hassle.
7
4
 
8
- This gem is a no config solution for the wonderful [Premailer gem](https://github.com/alexdunae/premailer) to be used with Rails.
9
- It uses interceptors which were introduced in Rails 3 and tweaks all mails which are `deliver`ed and adds a plain text part to them and inlines all CSS rules into the HTML part.
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
- By default it inlines all inline `<style>` declarations and all the CSS files that are linked to in the HTML:
12
+ ## Introduction
12
13
 
13
- ```html
14
- <link rel="stylesheet" ... />
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
- Don't worry about the host in the CSS URL since this will be ignored.
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 retrieval of the file depends on your assets configuration:
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
- * Rails 3.1 asset pipeline: It will load the compiled version of the CSS asset
22
- which is normally located in `app/assets/stylesheets/`. If the asset can't be
23
- found (e.g. it is only available on a CDN and not locally), it will be
24
- HTTP requested.
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
- * Classic static assets: It will try to load the CSS file located in
27
- `public/stylesheets/`
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 in your Rails project:
40
+ Simply add the gem to your `Gemfile`:
32
41
 
33
- gem 'premailer-rails'
42
+ ```ruby
43
+ gem 'premailer-rails'
44
+ ```
34
45
 
35
- premailer-rails requires either nokogiri or hpricot. It doesn't list them as a dependency so you can choose which one to use.
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
- gem 'nokogiri'
38
- # or
39
- gem 'hpricot'
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 in an
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 [Premailer documentation](http://rubydoc.info/gems/premailer/1.7.3/Premailer:initialize)
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: 'UTF-8',
63
- inputencoding: 'UTF-8',
76
+ input_encoding: 'UTF-8',
64
77
  generate_text_part: true
65
78
  }
66
79
  ```
67
80
 
68
- The input encoding option [changed](https://github.com/alexdunae/premailer/commit/5f5cbb4ac181299a7e73d3eca11f3cf546585364) at some point.
69
- To make sure this option works regardless of the premailer version, the old and new setting is specified.
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
- If you don't want to automatically generate a text part from the html part, set the config `:generate_text_part` to false.
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
- Note that the options `:with_html_string` and `:css_string` are used internally and thus will be overridden.
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
- [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/fphilipe/premailer-rails/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
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.5.1
1
+ 1.6.0
@@ -11,8 +11,7 @@ require 'premailer/rails/nokogiri_fix'
11
11
  class Premailer
12
12
  module Rails
13
13
  @config = {
14
- input_encoding: 'UTF-8',
15
- inputencoding: 'UTF-8',
14
+ input_encoding: 'UTF-8',
16
15
  generate_text_part: true
17
16
  }
18
17
  class << self
@@ -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
- path = extract_path(url)
31
-
32
- @cache[path] = STRATEGIES.each do |strategy|
33
- css = strategy.load(path)
34
- break css if css
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
- class Premailer
5
- module Rails
6
- module CSSLoaders
7
- # Loads the CSS from cache when not in development env.
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,15 @@
1
+ class Premailer
2
+ module Rails
3
+ module CSSLoaders
4
+ module FileSystemLoader
5
+ extend self
6
+
7
+ def load(url)
8
+ path = URI(url).path
9
+ file_path = "public#{path}"
10
+ File.read(file_path) if File.exist?(file_path)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ 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