bootstrap-email 1.2.0 → 1.3.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
  SHA256:
3
- metadata.gz: c82d69b4546e02daeeff5fc09df8e91c3c372f6da42e39fd96b438bd0776a7c3
4
- data.tar.gz: 8cc3f250c82b779ddb99ae0d9618523b716d8110e0cbd3b639a71255158c181d
3
+ metadata.gz: cbb329e67fb8b535a16ee1215af017f799873acbaf4282971555bdb546e5138b
4
+ data.tar.gz: 14a664c9e97bfcb6846866ffdfa99809cc007646361e9db733aaffaaf53dee45
5
5
  SHA512:
6
- metadata.gz: 7154cdcef0287e4fbcb37f117f5c73ae4dbf15b11a28b287b13b082d1ac05b63d5010b664a230cf907e7eafb8c27901db5e584db8a65fa7eb7ea1101cf42c6a1
7
- data.tar.gz: bc5f07bdcb6ffca350685b5b39114d121ed27e33d4e18b24ce624143a4bd29f7210e405958634e1b86bc0ae6acdd5b70c259b5a77c805a3085d345a392f412c0
6
+ metadata.gz: 35bfed648f7f86be0eb2bcbd5dba531d785f0c2b1bc82af1100806896f2480e1816a9275fd9678fcb86700cc4ae9c4052be7ebb33e614300a8ffcf005178cb53
7
+ data.tar.gz: d409bb910231e9e157ff375c379bc059e573a2ca44c860af183a72851b8ce825c3f52c193ade74d61551575dfa1bbfa4dadb6b7890ef8bfe3fe9dbcd530dcff1
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.2.0
1
+ 1.3.0
@@ -42,6 +42,10 @@ parser = OptionParser.new do |opts|
42
42
  options[:config] = File.expand_path(v, Dir.pwd)
43
43
  end
44
44
 
45
+ opts.on('-t', '--text', 'Return the plain text version of the email.') do |v|
46
+ options[:plain_text] = true
47
+ end
48
+
45
49
  opts.on('-h', '--help', 'Prints this help') do
46
50
  puts opts
47
51
  exit
@@ -70,22 +74,23 @@ else
70
74
  end
71
75
 
72
76
  if input
77
+ method = options[:plain_text] ? :perform_text_compile : :perform_html_compile
73
78
  case options[:type]
74
79
  when :pattern
75
80
  Dir.glob(input, base: Dir.pwd).each do |path|
76
81
  next unless File.file?(path)
77
82
 
78
83
  puts "Compiling file #{path}"
79
- compiled = BootstrapEmail::Compiler.new(path, type: :file, options: { config_path: options[:config] }).perform_full_compile
84
+ compiled = BootstrapEmail::Compiler.new(path, type: :file, options: { config_path: options[:config] }).public_send(method)
80
85
  destination = options[:destination].chomp('/*')
81
86
  FileUtils.mkdir_p("#{Dir.pwd}/#{destination}")
82
87
  File.write(File.expand_path("#{destination}/#{path.split('/').last}", Dir.pwd), compiled)
83
88
  end
84
89
  when :file
85
90
  path = File.expand_path(input, Dir.pwd)
86
- puts BootstrapEmail::Compiler.new(path, type: :file, options: { config_path: options[:config], sass_log_enabled: false }).perform_full_compile
91
+ puts BootstrapEmail::Compiler.new(path, type: :file, options: { config_path: options[:config], sass_log_enabled: false }).public_send(method)
87
92
  when :string
88
- puts BootstrapEmail::Compiler.new(input, options: { config_path: options[:config], sass_log_enabled: false }).perform_full_compile
93
+ puts BootstrapEmail::Compiler.new(input, options: { config_path: options[:config], sass_log_enabled: false }).public_send(method)
89
94
  end
90
95
  else
91
96
  puts opts
@@ -8,29 +8,40 @@ module BootstrapEmail
8
8
  self.config = BootstrapEmail::Config.new(options)
9
9
  self.type = type
10
10
  case type
11
- when :rails
12
- @mail = input
13
- html = (@mail.html_part || @mail).body.raw_source
14
11
  when :string
15
12
  html = input
16
13
  when :file
17
14
  html = File.read(input)
18
15
  end
19
- html = add_layout!(html)
16
+ html = add_layout(html)
20
17
  sass_load_paths
21
18
  build_premailer_doc(html)
22
19
  end
23
20
 
24
- def perform_full_compile
25
- compile_html!
26
- inline_css!
27
- configure_html!
28
- finalize_document!
21
+ def perform_multipart_compile
22
+ @perform_multipart_compile ||= {
23
+ text: perform_text_compile,
24
+ html: perform_html_compile
25
+ }
29
26
  end
30
27
 
28
+ def perform_text_compile
29
+ @perform_text_compile ||= plain_text
30
+ end
31
+
32
+ def perform_html_compile
33
+ @perform_html_compile ||= begin
34
+ compile_html
35
+ inline_css
36
+ configure_html
37
+ finalize_document
38
+ end
39
+ end
40
+ alias perform_full_compile perform_html_compile
41
+
31
42
  private
32
43
 
33
- def add_layout!(html)
44
+ def add_layout(html)
34
45
  document = Nokogiri::HTML(html)
35
46
  return html unless document.at_css('head').nil?
36
47
 
@@ -57,7 +68,7 @@ module BootstrapEmail
57
68
  self.doc = premailer.doc
58
69
  end
59
70
 
60
- def compile_html!
71
+ def compile_html
61
72
  BootstrapEmail::Converter::Body.build(doc)
62
73
  BootstrapEmail::Converter::Block.build(doc)
63
74
 
@@ -81,28 +92,26 @@ module BootstrapEmail
81
92
  BootstrapEmail::Converter::Table.build(doc)
82
93
  end
83
94
 
84
- def inline_css!
95
+ def inline_css
85
96
  premailer.to_inline_css
86
97
  end
87
98
 
88
- def configure_html!
99
+ def plain_text
100
+ premailer.to_plain_text
101
+ end
102
+
103
+ def configure_html
89
104
  BootstrapEmail::Converter::HeadStyle.build(doc, config)
90
105
  BootstrapEmail::Converter::AddMissingMetaTags.build(doc)
91
106
  BootstrapEmail::Converter::VersionComment.build(doc)
92
107
  end
93
108
 
94
- def finalize_document!
95
- html = doc.to_html(encoding: 'US-ASCII')
96
- BootstrapEmail::Converter::SupportUrlTokens.replace(html)
97
- BootstrapEmail::Converter::EnsureDoctype.replace(html)
98
- BootstrapEmail::Converter::ForceEncoding.replace(html)
99
- BootstrapEmail::Converter::BeautifyHTML.replace(html)
100
- case type
101
- when :rails
102
- (@mail.html_part || @mail).body = html
103
- @mail
104
- when :string, :file
105
- html
109
+ def finalize_document
110
+ doc.to_html(encoding: 'US-ASCII').tap do |html|
111
+ BootstrapEmail::Converter::SupportUrlTokens.replace(html)
112
+ BootstrapEmail::Converter::EnsureDoctype.replace(html)
113
+ BootstrapEmail::Converter::ForceEncoding.replace(html)
114
+ BootstrapEmail::Converter::BeautifyHTML.replace(html)
106
115
  end
107
116
  end
108
117
  end
@@ -3,29 +3,31 @@
3
3
  module BootstrapEmail
4
4
  class ConfigStore
5
5
  OPTIONS = [
6
- :sass_email_location, # path to main sass file
7
- :sass_head_location, # path to head sass file
8
- :sass_email_string, # main sass file passed in as a string
9
- :sass_head_string, # head sass file passed in as a string
10
- :sass_load_paths, # array of directories for loading sass imports
11
- :sass_cache_location, # path to tmp folder for sass cache
12
- :sass_log_enabled # turn on or off sass log when caching new sass
6
+ :sass_email_location, # path to main sass file
7
+ :sass_head_location, # path to head sass file
8
+ :sass_email_string, # main sass file passed in as a string
9
+ :sass_head_string, # head sass file passed in as a string
10
+ :sass_load_paths, # array of directories for loading sass imports
11
+ :sass_cache_location, # path to tmp folder for sass cache
12
+ :sass_log_enabled, # turn on or off sass log when caching new sass
13
+ :generate_rails_text_part # boolean for whether or not to generate the text part in rails, default: true
13
14
  ].freeze
14
15
 
15
- attr_reader(*OPTIONS)
16
-
17
- OPTIONS.each do |option|
18
- define_method("#{option}=") do |value|
19
- instance_variable_set("@#{option}", value)
20
- end
21
- end
16
+ attr_accessor(*OPTIONS)
22
17
 
23
18
  def initialize(options = [])
19
+ defaults
24
20
  options.each { |name, value| instance_variable_set("@#{name}", value) if OPTIONS.include?(name) }
25
21
  end
26
22
 
27
23
  def did_set?(option)
28
24
  instance_variable_defined?("@#{option}")
29
25
  end
26
+
27
+ private
28
+
29
+ def defaults
30
+ self.generate_rails_text_part = true
31
+ end
30
32
  end
31
33
  end
@@ -7,8 +7,9 @@ module BootstrapEmail
7
7
  preview_node = doc.at_css('preview')
8
8
  return if preview_node.nil?
9
9
 
10
- # apply spacing after the text max of 100 characters so it doesn't show body text
11
- preview_node.inner_html += ' ' * [(100 - preview_node.content.length.to_i), 0].max
10
+ # https://www.litmus.com/blog/the-little-known-preview-text-hack-you-may-want-to-use-in-every-email/
11
+ # apply spacing after the text max of 278 characters so it doesn't show body text
12
+ preview_node.inner_html += '͏ ‌   ' * [(278 - preview_node.content.length.to_i), 0].max
12
13
  node = template('div', classes: 'preview', contents: preview_node.content)
13
14
  preview_node.remove
14
15
 
@@ -2,15 +2,9 @@
2
2
 
3
3
  ActiveSupport.on_load(:action_mailer, { yield: true }) do |action_mailer|
4
4
  action_mailer.class_eval do # To support Rails less than 6
5
- # sit in the middle and compile the html
6
5
  def bootstrap_mail(*args, &block)
7
- mail_message = mail(*args, &block)
8
- # if you override the #mail method in you ApplicationMailer you may intentionally return something other than a mail message
9
- if mail_message
10
- bootstrap = BootstrapEmail::Compiler.new(mail_message, type: :rails)
11
- bootstrap.perform_full_compile
12
- end
13
- mail_message
6
+ message = mail(*args, &block)
7
+ BootstrapEmail::Rails::MailBuilder.perform(message)
14
8
  end
15
9
  alias_method :bootstrap_email, :bootstrap_mail
16
10
  alias_method :make_bootstrap_mail, :bootstrap_mail
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BootstrapEmail
4
+ module Rails
5
+ class MailBuilder
6
+ attr_reader :mail, :bootstrap_email
7
+
8
+ def self.perform(mail)
9
+ new(mail) if mail
10
+ end
11
+
12
+ private
13
+
14
+ def initialize(mail)
15
+ @mail = mail
16
+ @bootstrap_email = BootstrapEmail::Compiler.new(html_part, type: :string)
17
+ perform
18
+ end
19
+
20
+ def perform
21
+ add_mail_parts
22
+ mail
23
+ end
24
+
25
+ def html_part
26
+ (mail.html_part || mail).body.raw_source
27
+ end
28
+
29
+ def add_mail_parts
30
+ if BootstrapEmail.static_config.generate_rails_text_part
31
+ mail.parts << build_alternative_part
32
+ else
33
+ html = bootstrap_email.perform_full_compile
34
+ mail.parts << build_html_part(html)
35
+ end
36
+ end
37
+
38
+ def build_alternative_part
39
+ compiled = bootstrap_email.perform_multipart_compile
40
+
41
+ part = Mail::Part.new(content_type: 'multipart/alternative')
42
+ part.add_part(build_text_part(compiled[:text]))
43
+ part.add_part(build_html_part(compiled[:html]))
44
+
45
+ part
46
+ end
47
+
48
+ def build_html_part(html)
49
+ Mail::Part.new do
50
+ content_type "text/html; charset=#{html.encoding}"
51
+ body html
52
+ end
53
+ end
54
+
55
+ def build_text_part(text)
56
+ Mail::Part.new do
57
+ content_type "text/plain; charset=#{text.encoding}"
58
+ body text
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -29,4 +29,5 @@ Dir[File.join(__dir__, 'bootstrap-email/converters', '*.rb')].each { |file| requ
29
29
  if defined?(Rails)
30
30
  require_relative 'bootstrap-email/rails/action_mailer'
31
31
  require_relative 'bootstrap-email/rails/engine'
32
+ require_relative 'bootstrap-email/rails/mail_builder'
32
33
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bootstrap-email
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stuart Yamartino
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-06-18 00:00:00.000000000 Z
11
+ date: 2022-07-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: htmlbeautifier
@@ -150,6 +150,7 @@ files:
150
150
  - lib/bootstrap-email/erb.rb
151
151
  - lib/bootstrap-email/rails/action_mailer.rb
152
152
  - lib/bootstrap-email/rails/engine.rb
153
+ - lib/bootstrap-email/rails/mail_builder.rb
153
154
  - lib/bootstrap-email/sass_cache.rb
154
155
  - lib/bootstrap-email/setup.rb
155
156
  - lib/bootstrap-email/version.rb