bootstrap-email 0.0.0.alpha.3 → 0.0.0.alpha.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/bootstrap-email.rb +86 -31
- data/lib/bootstrap-email/action_mailer.rb +3 -15
- data/lib/bootstrap-email/version.rb +3 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 808b3a7f074ff5e6618293422bd4fdb6cf9a54f0
|
4
|
+
data.tar.gz: e6d2760ed957397c371550ff1c616b942c3fd12f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e504c6b90af4481d174dcb7dc03a93770c97d24c55a26e7098a07e3c4404e29c587b8161d680a33439e0349a4abfdb5b7095c61a78ed4445e88f878875d00046
|
7
|
+
data.tar.gz: 80f5077166f1bb933237391e42b0153750f88b8a82a9d20f2c7793fe443269ef799cb17874fbb923e12c0b2269fbaae9d9ea6fcd3beb35c123cb521f5c83babd
|
data/lib/bootstrap-email.rb
CHANGED
@@ -11,7 +11,18 @@ module BootstrapEmail
|
|
11
11
|
|
12
12
|
def initialize mail
|
13
13
|
@mail = mail
|
14
|
-
|
14
|
+
self.update_doc(@mail.body.raw_source)
|
15
|
+
end
|
16
|
+
|
17
|
+
def update_doc source
|
18
|
+
@doc = Nokogiri::HTML(source)
|
19
|
+
end
|
20
|
+
|
21
|
+
def perform_full_compile
|
22
|
+
compile_html!
|
23
|
+
inline_css!
|
24
|
+
inject_head!
|
25
|
+
update_mailer!
|
15
26
|
end
|
16
27
|
|
17
28
|
def compile_html!
|
@@ -27,19 +38,40 @@ module BootstrapEmail
|
|
27
38
|
margin
|
28
39
|
spacer
|
29
40
|
table
|
41
|
+
body
|
30
42
|
end
|
31
43
|
|
32
|
-
def
|
44
|
+
def inline_css!
|
33
45
|
@mail.body = @doc.to_html
|
46
|
+
@mail = Premailer::Rails::Hook.perform(@mail)
|
47
|
+
@mail.header[:skip_premailer] = true
|
48
|
+
self.update_doc(@mail.html_part.body.raw_source)
|
49
|
+
end
|
50
|
+
|
51
|
+
def inject_head!
|
52
|
+
@doc.at_css('head').add_child(bootstrap_email_head)
|
53
|
+
end
|
54
|
+
|
55
|
+
def update_mailer!
|
56
|
+
@mail.html_part.body = @doc.to_html
|
34
57
|
@mail
|
35
58
|
end
|
36
59
|
|
37
60
|
private
|
38
61
|
|
39
|
-
def
|
62
|
+
def bootstrap_email_head
|
63
|
+
html_string = <<-HEREDOC
|
64
|
+
<style type="text/css">
|
65
|
+
#{Sass::Engine.new(File.open(File.expand_path('../core/head.scss', __dir__)).read, {syntax: :scss, style: :compressed, cache: false, read_cache: false}).render}
|
66
|
+
</style>
|
67
|
+
HEREDOC
|
68
|
+
html_string
|
69
|
+
end
|
70
|
+
|
71
|
+
def template file, locals_hash = {}
|
40
72
|
namespace = OpenStruct.new(locals_hash)
|
41
|
-
|
42
|
-
ERB.new(
|
73
|
+
template_html = File.open(File.expand_path("../core/templates/#{file}.html.erb", __dir__)).read
|
74
|
+
ERB.new(template_html).result(namespace.instance_eval { binding })
|
43
75
|
end
|
44
76
|
|
45
77
|
def each_node css_lookup, &blk
|
@@ -49,67 +81,73 @@ module BootstrapEmail
|
|
49
81
|
|
50
82
|
def button
|
51
83
|
each_node('.btn') do |node| # move all classes up and remove all classes from the element
|
52
|
-
node.replace(
|
84
|
+
node.replace(template('table', {classes: node['class'], contents: node.delete('class') && node.to_html}))
|
53
85
|
end
|
54
86
|
end
|
55
87
|
|
56
88
|
def badge
|
57
89
|
each_node('.badge') do |node| # move all classes up and remove all classes from the element
|
58
|
-
node.replace(
|
90
|
+
node.replace(template('table-left', {classes: node['class'], contents: node.delete('class') && node.to_html}))
|
59
91
|
end
|
60
92
|
end
|
61
93
|
|
62
94
|
def alert
|
63
95
|
each_node('.alert') do |node| # move all classes up and remove all classes from the element
|
64
|
-
node.replace(
|
96
|
+
node.replace(template('table', {classes: node['class'], contents: node.delete('class') && node.to_html}))
|
65
97
|
end
|
66
98
|
end
|
67
99
|
|
68
100
|
def align
|
69
|
-
each_node('.
|
70
|
-
node
|
71
|
-
node.replace(build_from_template('align-left', {contents: node.to_html}))
|
101
|
+
each_node('.float-left') do |node|
|
102
|
+
align_helper(node, /float-left/, 'left')
|
72
103
|
end
|
73
|
-
each_node('.
|
74
|
-
node
|
75
|
-
node.replace(build_from_template('align-center', {contents: node.to_html}))
|
104
|
+
each_node('.mx-auto') do |node|
|
105
|
+
align_helper(node, /mx-auto/, 'center')
|
76
106
|
end
|
77
|
-
each_node('.
|
78
|
-
node
|
79
|
-
|
107
|
+
each_node('.float-right') do |node|
|
108
|
+
align_helper(node, /float-right/, 'right')
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def align_helper node, klass, template
|
113
|
+
if node.name != 'table' # if it is already on a table, set the proprieties on the current table
|
114
|
+
node['class'] = node['class'].sub(klass, '')
|
115
|
+
node.replace(template("align-#{template}", {contents: node.to_html}))
|
116
|
+
else
|
117
|
+
node['align'] = template
|
80
118
|
end
|
81
119
|
end
|
82
120
|
|
83
121
|
def card
|
84
122
|
each_node('.card') do |node| # move all classes up and remove all classes from element
|
85
|
-
node.replace(
|
123
|
+
node.replace(template('table', {classes: node['class'], contents: node.delete('class') && node.to_html}))
|
86
124
|
end
|
87
125
|
each_node('.card-body') do |node| # move all classes up and remove all classes from element
|
88
|
-
node.replace(
|
126
|
+
node.replace(template('table', {classes: node['class'], contents: node.delete('class') && node.to_html}))
|
89
127
|
end
|
90
128
|
end
|
91
129
|
|
92
130
|
def hr
|
93
131
|
each_node('hr') do |node| # drop hr in place of current
|
94
|
-
node.replace(
|
132
|
+
node.replace(template('hr', {classes: "hr #{node['class']}"}))
|
95
133
|
end
|
96
134
|
end
|
97
135
|
|
98
136
|
def container
|
99
137
|
each_node('.container') do |node|
|
100
|
-
node.replace(
|
138
|
+
node.replace(template('container', {classes: node['class'], contents: node.inner_html}))
|
101
139
|
end
|
102
140
|
each_node('.container-fluid') do |node|
|
103
|
-
node.replace(
|
141
|
+
node.replace(template('table', {classes: node['class'], contents: node.inner_html}))
|
104
142
|
end
|
105
143
|
end
|
106
144
|
|
107
145
|
def grid
|
108
146
|
each_node('.row') do |node|
|
109
|
-
node.replace(
|
147
|
+
node.replace(template('row', {classes: node['class'], contents: node.inner_html}))
|
110
148
|
end
|
111
149
|
each_node('*[class*=col]') do |node|
|
112
|
-
node.replace(
|
150
|
+
node.replace(template('col', {classes: node['class'], contents: node.inner_html}))
|
113
151
|
end
|
114
152
|
end
|
115
153
|
|
@@ -119,23 +157,23 @@ module BootstrapEmail
|
|
119
157
|
padding_regex = /(p[trblxy]?-\d)/
|
120
158
|
classes = node['class'].scan(padding_regex).join(' ')
|
121
159
|
node['class'] = node['class'].gsub(padding_regex, '')
|
122
|
-
node.replace(
|
160
|
+
node.replace(template('table', {classes: classes, contents: node.to_html}))
|
123
161
|
end
|
124
162
|
end
|
125
163
|
end
|
126
164
|
|
127
165
|
def margin
|
128
166
|
each_node('*[class*=m-], *[class*=mt-], *[class*=mb-]') do |node|
|
129
|
-
top_class = node['class'][/m[
|
130
|
-
bottom_class = node['class'][/m[
|
131
|
-
node['class'] = node['class'].gsub(/(m[
|
167
|
+
top_class = node['class'][/m[ty]{1}-(lg-)?(\d)/]
|
168
|
+
bottom_class = node['class'][/m[by]{1}-(lg-)?(\d)/]
|
169
|
+
node['class'] = node['class'].gsub(/(m[tby]{1}-(lg-)?\d)/, '')
|
132
170
|
html = ''
|
133
171
|
if top_class
|
134
|
-
html +=
|
172
|
+
html += template('div', {classes: "s-#{top_class.gsub(/m[ty]?-/, '')}", contents: nil})
|
135
173
|
end
|
136
174
|
html += node.to_html
|
137
175
|
if bottom_class
|
138
|
-
html +=
|
176
|
+
html += template('div', {classes: "s-#{bottom_class.gsub(/m[by]?-/, '')}", contents: nil})
|
139
177
|
end
|
140
178
|
node.replace(html)
|
141
179
|
end
|
@@ -143,7 +181,7 @@ module BootstrapEmail
|
|
143
181
|
|
144
182
|
def spacer
|
145
183
|
each_node('*[class*=s-]') do |node|
|
146
|
-
node.replace(
|
184
|
+
node.replace(template('table', {classes: node['class'] + ' w-100', contents: " "}))
|
147
185
|
end
|
148
186
|
end
|
149
187
|
|
@@ -156,6 +194,23 @@ module BootstrapEmail
|
|
156
194
|
end
|
157
195
|
end
|
158
196
|
|
197
|
+
def body
|
198
|
+
@doc.css('body').each do |node|
|
199
|
+
node.replace( '<body>' + preview_text.to_s + template('table', {classes: "#{node['class']} body", contents: "#{node.inner_html}"}) + '</body>' )
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def preview_text
|
204
|
+
preview_node = @doc.at_css('preview')
|
205
|
+
if preview_node.present?
|
206
|
+
# apply spacing after the text max of 100 characters so it doesn't show body text
|
207
|
+
preview_node.content += " " * (100 - preview_node.content.length.to_i)
|
208
|
+
node = template('div', {classes: 'preview', contents: preview_node.content})
|
209
|
+
preview_node.remove
|
210
|
+
return node
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
159
214
|
end
|
160
215
|
end
|
161
216
|
|
@@ -2,21 +2,9 @@ class ActionMailer::Base
|
|
2
2
|
|
3
3
|
# sit in the middle and compile the html
|
4
4
|
def bootstrap_mail *args
|
5
|
-
bootstrap = BootstrapEmail::Compiler.new(mail(*args))
|
6
|
-
bootstrap.
|
7
|
-
bootstrap.update_mailer!
|
5
|
+
bootstrap = BootstrapEmail::Compiler.new(mail(*args) { |format| format.html { render layout: 'layouts/bootstrap-mailer.html.erb' } } )
|
6
|
+
bootstrap.perform_full_compile
|
8
7
|
end
|
9
8
|
|
10
|
-
|
11
|
-
module BootstrapEmailHelper
|
12
|
-
def bootstrap_email_head
|
13
|
-
html_string = <<-HEREDOC
|
14
|
-
<style type="text/css" data-premailer="ignore">
|
15
|
-
#{File.open(File.expand_path('../../core/head.css', __dir__)).read}
|
16
|
-
</style>
|
17
|
-
HEREDOC
|
18
|
-
html_string.html_safe
|
19
|
-
end
|
20
|
-
end
|
21
|
-
helper BootstrapEmailHelper
|
9
|
+
|
22
10
|
end
|