herbes 0.0.2

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 6617069fb9f0a326325321a279591bd81f3e18fe256c01662cc85f0f864e6bf3
4
+ data.tar.gz: 2024134c94502d6eabeb538202ce68c58293a5ca9d39a29bd6b90d26e29e8a80
5
+ SHA512:
6
+ metadata.gz: c1dfe60ee208e5dbe5bf950acb0260e3d2d47aa85aeb5a22c33ad24790e607bff94df373285948d854e90914376613a77616e555123b9969139a0c75bf877d23
7
+ data.tar.gz: 3ab70f817b5e0ca49c7386c8a4cb10e7c958291d3bb76a622d2e79fd3a9757d900e584e2ea9b05ca3756b1c5208525ddb8be02f664ff98b244fb05c9a035f981
@@ -0,0 +1 @@
1
+ example/*.html
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
@@ -0,0 +1 @@
1
+ 2.7.0
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
6
+
7
+ group :test do
8
+ gem 'pry'
9
+ gem 'rspec'
10
+ end
@@ -0,0 +1,53 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ herbes (0.0.2)
5
+ nokogiri
6
+ premailer
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ addressable (2.7.0)
12
+ public_suffix (>= 2.0.2, < 5.0)
13
+ coderay (1.1.2)
14
+ css_parser (1.7.1)
15
+ addressable
16
+ diff-lcs (1.3)
17
+ htmlentities (4.3.4)
18
+ method_source (0.9.2)
19
+ mini_portile2 (2.4.0)
20
+ nokogiri (1.10.9)
21
+ mini_portile2 (~> 2.4.0)
22
+ premailer (1.11.1)
23
+ addressable
24
+ css_parser (>= 1.6.0)
25
+ htmlentities (>= 4.0.0)
26
+ pry (0.12.2)
27
+ coderay (~> 1.1.0)
28
+ method_source (~> 0.9.0)
29
+ public_suffix (4.0.3)
30
+ rspec (3.9.0)
31
+ rspec-core (~> 3.9.0)
32
+ rspec-expectations (~> 3.9.0)
33
+ rspec-mocks (~> 3.9.0)
34
+ rspec-core (3.9.1)
35
+ rspec-support (~> 3.9.1)
36
+ rspec-expectations (3.9.0)
37
+ diff-lcs (>= 1.2.0, < 2.0)
38
+ rspec-support (~> 3.9.0)
39
+ rspec-mocks (3.9.1)
40
+ diff-lcs (>= 1.2.0, < 2.0)
41
+ rspec-support (~> 3.9.0)
42
+ rspec-support (3.9.2)
43
+
44
+ PLATFORMS
45
+ ruby
46
+
47
+ DEPENDENCIES
48
+ herbes!
49
+ pry
50
+ rspec
51
+
52
+ BUNDLED WITH
53
+ 2.1.4
@@ -0,0 +1,65 @@
1
+ # Herbes (ERB Email Generator for Ruby Lambda)
2
+
3
+ ![herbes](https://github.com/haydenmcfarland/assets/blob/master/images/herbes.png?raw=true)
4
+ ![herbes_template](https://github.com/haydenmcfarland/assets/blob/master/images/herbes_template.png?raw=true)
5
+
6
+ # What?
7
+
8
+ A gem for generating HTML with inlined css from ERB templates for email rendering purposes.
9
+
10
+ # How to use
11
+ Add `herbes` to your gem file:
12
+
13
+ ```ruby
14
+ gem 'herbes', github: 'haydenmcfarland/herbes'
15
+ ```
16
+
17
+ Run `bundle install`
18
+
19
+ # Example usage
20
+
21
+ #### using default template
22
+ ```ruby
23
+ require 'herbes'
24
+
25
+ github = 'https://github.com/haydenmcfarland'
26
+ img_path = "#{github}/assets/blob/master/images/herbes.png?raw=true"
27
+ params = {
28
+ title: 'Test Email',
29
+ preheader: 'This is what is used as an example in client',
30
+ p_greetings: 'Hey there john_cena,',
31
+ p_body: 'Please press the following button to confirm your account:',
32
+ p_end: 'You will be forwarded to a confirmation screen.',
33
+ p_regards: 'Thank you!',
34
+ footer_address: '8650 Del Monte Court, Taylors, SC 29687',
35
+ footer_extra: 'Questions? Issues? Call: 867-5309',
36
+ powered_by: "<a href=\"#{github}/herbes\">Herbes</a>",
37
+ img_absolute_path: img_path,
38
+ call_to_action: "<a href=\"#{github}/herbes\" "\
39
+ 'target="_blank">Confirm</a></td>'
40
+ }
41
+
42
+ Herbes::Email.render(params)
43
+
44
+ "<!DOCTYPE html>\n<html>\n <head>\n <meta name=\"viewport\" content=\"width=device-width\">\n...
45
+ ```
46
+
47
+ #### providing custom template path and style path
48
+
49
+ ```ruby
50
+ # parameters are tied to what is expected in template
51
+ params = {
52
+ new_param1: 'test',
53
+ new_param2: 'cool',
54
+ }
55
+
56
+ Herbes::Email.render(params, template_path: 'template.html.erb', style_path: 'style.css')
57
+ ```
58
+
59
+ #### providing style string
60
+
61
+ ```ruby
62
+
63
+ Herbes::Email.render(params, style_string: custom_css)
64
+
65
+ ```
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require_relative 'lib/herbes/version'
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = 'herbes'
9
+ s.version = Herbes::VERSION
10
+ s.authors = ['haydenmcfarland']
11
+ s.email = ['mcfarlandsms@gmail.com']
12
+ s.date = '2020-03-12'
13
+ s.summary = 'Simple ERB email generator for AWS Lambda'
14
+ s.description = 'Simple ERB email generator'
15
+ s.homepage = 'https://github.com/haydenmcfarland/herbes'
16
+ s.license = 'MIT'
17
+ s.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+
21
+ s.require_paths = ['lib']
22
+ s.add_dependency('nokogiri')
23
+ s.add_dependency('premailer')
24
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ # require gem ruby files
4
+
5
+ require_relative 'herbes/version'
6
+ require_relative 'herbes/constants'
7
+ require_relative 'herbes/email'
@@ -0,0 +1,337 @@
1
+ /* -------------------------------------
2
+ ripped from https://github.com/leemunroe/responsive-html-email-template
3
+ ------------------------------------- /*
4
+
5
+ /* -------------------------------------
6
+ GLOBAL RESETS
7
+ ------------------------------------- */
8
+
9
+ img {
10
+ border: none;
11
+ width: 100px;
12
+ height: 100px;
13
+ -ms-interpolation-mode: bicubic;
14
+ max-width: 100%;
15
+ }
16
+
17
+ body {
18
+ background-color: #f6f6f6;
19
+ font-family: sans-serif;
20
+ -webkit-font-smoothing: antialiased;
21
+ font-size: 14px;
22
+ line-height: 1.4;
23
+ margin: 0;
24
+ padding: 0;
25
+ -ms-text-size-adjust: 100%;
26
+ -webkit-text-size-adjust: 100%;
27
+ }
28
+
29
+ table {
30
+ border-collapse: separate;
31
+ mso-table-lspace: 0pt;
32
+ mso-table-rspace: 0pt;
33
+ width: 100%;
34
+ }
35
+ table td {
36
+ font-family: sans-serif;
37
+ font-size: 14px;
38
+ vertical-align: top;
39
+ }
40
+
41
+ /* -------------------------------------
42
+ BODY & CONTAINER
43
+ ------------------------------------- */
44
+
45
+ .body {
46
+ background-color: #f6f6f6;
47
+ width: 100%;
48
+ }
49
+
50
+ /* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink down on a phone or something */
51
+ .container {
52
+ display: block;
53
+ margin: 0 auto !important;
54
+ /* makes it centered */
55
+ max-width: 580px;
56
+ padding: 10px;
57
+ width: 580px;
58
+ }
59
+
60
+ /* This should also be a block element, so that it will fill 100% of the .container */
61
+ .content {
62
+ box-sizing: border-box;
63
+ display: block;
64
+ margin: 0 auto;
65
+ max-width: 580px;
66
+ padding: 10px;
67
+ }
68
+
69
+ /* -------------------------------------
70
+ HEADER, FOOTER, MAIN
71
+ ------------------------------------- */
72
+
73
+ .main {
74
+ background: #ffffff;
75
+ border-radius: 3px;
76
+ width: 100%;
77
+ }
78
+
79
+ .wrapper {
80
+ box-sizing: border-box;
81
+ padding: 20px;
82
+ }
83
+
84
+ .content-block {
85
+ padding-bottom: 10px;
86
+ padding-top: 10px;
87
+ }
88
+
89
+ .footer {
90
+ clear: both;
91
+ margin-top: 10px;
92
+ text-align: center;
93
+ width: 100%;
94
+ }
95
+ .footer td,
96
+ .footer p,
97
+ .footer span,
98
+ .footer a {
99
+ color: #999999;
100
+ font-size: 12px;
101
+ text-align: center;
102
+ }
103
+
104
+ /* -------------------------------------
105
+ TYPOGRAPHY
106
+ ------------------------------------- */
107
+
108
+ h1,
109
+ h2,
110
+ h3,
111
+ h4 {
112
+ color: #000000;
113
+ font-family: sans-serif;
114
+ font-weight: 400;
115
+ line-height: 1.4;
116
+ margin: 0;
117
+ margin-bottom: 30px;
118
+ }
119
+
120
+ h1 {
121
+ font-size: 35px;
122
+ font-weight: 300;
123
+ text-align: center;
124
+ text-transform: capitalize;
125
+ }
126
+
127
+ p,
128
+ ul,
129
+ ol {
130
+ font-family: sans-serif;
131
+ font-size: 14px;
132
+ font-weight: normal;
133
+ margin: 0;
134
+ margin-bottom: 15px;
135
+ }
136
+ p li,
137
+ ul li,
138
+ ol li {
139
+ list-style-position: inside;
140
+ margin-left: 5px;
141
+ }
142
+
143
+ a {
144
+ color: #3498db;
145
+ text-decoration: underline;
146
+ }
147
+
148
+ /* -------------------------------------
149
+ BUTTONS
150
+ ------------------------------------- */
151
+
152
+ .btn {
153
+ box-sizing: border-box;
154
+ width: 100%;
155
+ }
156
+ .btn > tbody > tr > td {
157
+ padding-bottom: 15px;
158
+ }
159
+ .btn table {
160
+ width: auto;
161
+ }
162
+ .btn table td {
163
+ background-color: #ffffff;
164
+ border-radius: 5px;
165
+ text-align: center;
166
+ }
167
+ .btn a {
168
+ background-color: #ffffff;
169
+ border: solid 1px #3498db;
170
+ border-radius: 5px;
171
+ box-sizing: border-box;
172
+ color: #3498db;
173
+ cursor: pointer;
174
+ display: inline-block;
175
+ font-size: 14px;
176
+ font-weight: bold;
177
+ margin: 0;
178
+ padding: 12px 25px;
179
+ text-decoration: none;
180
+ text-transform: capitalize;
181
+ }
182
+
183
+ .btn-primary table td {
184
+ background-color: #3498db;
185
+ }
186
+
187
+ .btn-primary a {
188
+ background-color: #3498db;
189
+ border-color: #3498db;
190
+ color: #ffffff;
191
+ }
192
+
193
+ /* -------------------------------------
194
+ OTHER STYLES THAT MIGHT BE USEFUL
195
+ ------------------------------------- */
196
+
197
+ .last {
198
+ margin-bottom: 0;
199
+ }
200
+
201
+ .first {
202
+ margin-top: 0;
203
+ }
204
+
205
+ .align-center {
206
+ text-align: center;
207
+ }
208
+
209
+ .align-right {
210
+ text-align: right;
211
+ }
212
+
213
+ .align-left {
214
+ text-align: left;
215
+ }
216
+
217
+ .clear {
218
+ clear: both;
219
+ }
220
+
221
+ .mt0 {
222
+ margin-top: 0;
223
+ }
224
+
225
+ .mb0 {
226
+ margin-bottom: 0;
227
+ }
228
+
229
+ .preheader {
230
+ color: transparent;
231
+ display: none;
232
+ height: 0;
233
+ max-height: 0;
234
+ max-width: 0;
235
+ opacity: 0;
236
+ overflow: hidden;
237
+ mso-hide: all;
238
+ visibility: hidden;
239
+ width: 0;
240
+ }
241
+
242
+ .powered-by a {
243
+ text-decoration: none;
244
+ }
245
+
246
+ hr {
247
+ border: 0;
248
+ border-bottom: 1px solid #f6f6f6;
249
+ margin: 20px 0;
250
+ }
251
+
252
+ /* -------------------------------------
253
+ RESPONSIVE AND MOBILE FRIENDLY STYLES
254
+ ------------------------------------- */
255
+
256
+ @media only screen and (max-width: 620px) {
257
+ table[class="body"] h1 {
258
+ font-size: 28px !important;
259
+ margin-bottom: 10px !important;
260
+ }
261
+ table[class="body"] p,
262
+ table[class="body"] ul,
263
+ table[class="body"] ol,
264
+ table[class="body"] td,
265
+ table[class="body"] span,
266
+ table[class="body"] a {
267
+ font-size: 16px !important;
268
+ }
269
+ table[class="body"] .wrapper,
270
+ table[class="body"] .article {
271
+ padding: 10px !important;
272
+ }
273
+ table[class="body"] .content {
274
+ padding: 0 !important;
275
+ }
276
+ table[class="body"] .container {
277
+ padding: 0 !important;
278
+ width: 100% !important;
279
+ }
280
+ table[class="body"] .main {
281
+ border-left-width: 0 !important;
282
+ border-radius: 0 !important;
283
+ border-right-width: 0 !important;
284
+ }
285
+ table[class="body"] .btn table {
286
+ width: 100% !important;
287
+ }
288
+ table[class="body"] .btn a {
289
+ width: 100% !important;
290
+ }
291
+ table[class="body"] .img-responsive {
292
+ height: auto !important;
293
+ max-width: 100% !important;
294
+ width: auto !important;
295
+ }
296
+ }
297
+
298
+ /* -------------------------------------
299
+ PRESERVE THESE STYLES IN THE HEAD
300
+ ------------------------------------- */
301
+
302
+ @media all {
303
+ .ExternalClass {
304
+ width: 100%;
305
+ }
306
+ .ExternalClass,
307
+ .ExternalClass p,
308
+ .ExternalClass span,
309
+ .ExternalClass font,
310
+ .ExternalClass td,
311
+ .ExternalClass div {
312
+ line-height: 100%;
313
+ }
314
+ .apple-link a {
315
+ color: inherit !important;
316
+ font-family: inherit !important;
317
+ font-size: inherit !important;
318
+ font-weight: inherit !important;
319
+ line-height: inherit !important;
320
+ text-decoration: none !important;
321
+ }
322
+ #MessageViewBody a {
323
+ color: inherit;
324
+ text-decoration: none;
325
+ font-size: inherit;
326
+ font-family: inherit;
327
+ font-weight: inherit;
328
+ line-height: inherit;
329
+ }
330
+ .btn-primary table td:hover {
331
+ background-color: #34495e !important;
332
+ }
333
+ .btn-primary a:hover {
334
+ background-color: #34495e !important;
335
+ border-color: #34495e !important;
336
+ }
337
+ }
@@ -0,0 +1,93 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <meta name="viewport" content="width=device-width" />
5
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6
+ <title> <%= title %> </title>
7
+ </head>
8
+ <body>
9
+ <span class="preheader"> <%= preheader %> </span>
10
+ <table role="presentation"
11
+ border="0"
12
+ cellpadding="0"
13
+ cellspacing="0"
14
+ class="body"
15
+ >
16
+ <tr>
17
+ <td>&nbsp;</td>
18
+ <td class="container">
19
+ <div class="content">
20
+ <table role="presentation" class="main">
21
+ <tr>
22
+ <td class="wrapper">
23
+ <table role="presentation"
24
+ border="0"
25
+ cellpadding="0"
26
+ cellspacing="0"
27
+ >
28
+ <th>
29
+ <img src="<%= img_absolute_path %>">
30
+ </th>
31
+ <tr>
32
+ <td>
33
+ <p><%= p_greetings %></p>
34
+ <p><%= p_body %></p>
35
+ <table role="presentation"
36
+ border="0"
37
+ cellpadding="0"
38
+ cellspacing="0"
39
+ class="btn btn-primary"
40
+ >
41
+ <tbody>
42
+ <tr>
43
+ <td align="left">
44
+ <table role="presentation"
45
+ border="0"
46
+ cellpadding="0"
47
+ cellspacing="0"
48
+ >
49
+ <tbody>
50
+ <tr>
51
+ <td> <%= call_to_action %> </td>
52
+ </tr>
53
+ </tbody>
54
+ </table>
55
+ </td>
56
+ </tr>
57
+ </tbody>
58
+ </table>
59
+ <p> <%= p_end %></p>
60
+ <p><%= p_regards %></p>
61
+ </td>
62
+ </tr>
63
+ </table>
64
+ </td>
65
+ </tr>
66
+ </table>
67
+ <div class="footer">
68
+ <table role="presentation"
69
+ border="0"
70
+ cellpadding="0"
71
+ cellspacing="0"
72
+ >
73
+ <tr>
74
+ <td class="content-block">
75
+ <span class="apple-link"> <%= footer_address %></span>
76
+ <br>
77
+ <%= footer_extra %>
78
+ </td>
79
+ </tr>
80
+ <tr>
81
+ <td class="content-block powered-by">
82
+ <%= powered_by %>
83
+ </td>
84
+ </tr>
85
+ </table>
86
+ </div>
87
+ </div>
88
+ </td>
89
+ <td>&nbsp;</td>
90
+ </tr>
91
+ </table>
92
+ </body>
93
+ </html>
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Herbes
4
+ module Constants
5
+ DEFAULT_EMAIL_TEMPLATE_PATH = 'lib/herbes/assets/templates/herbes.html.erb'
6
+ DEFAULT_EMAIL_STYLE_PATH = 'lib/herbes/assets/styles/herbes.css'
7
+ end
8
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'erb'
4
+ require 'ostruct'
5
+ require 'premailer'
6
+
7
+ module Herbes
8
+ class Email < OpenStruct
9
+ def render_style(path = Herbes::Constants::DEFAULT_EMAIL_STYLE_PATH)
10
+ File.read(path)
11
+ end
12
+
13
+ def resolve_style(params)
14
+ return render_style(params[:style_path]) if params.key?(:style_path)
15
+ return style_string if params.key?(:style_string)
16
+
17
+ render_style
18
+ end
19
+
20
+ def initialize(template_params, options = {})
21
+ style = resolve_style(options)
22
+ params = template_params.transform_keys(&:to_sym)
23
+ super(params.merge(style: style))
24
+ end
25
+
26
+ def render_html(template)
27
+ ERB.new(template).result(binding)
28
+ end
29
+
30
+ def render_template(path = nil)
31
+ path ||= Herbes::Constants::DEFAULT_EMAIL_TEMPLATE_PATH
32
+ render_html(File.read(path))
33
+ end
34
+
35
+ def render_inline_template(path = nil, premailer_options = {})
36
+ path ||= Herbes::Constants::DEFAULT_EMAIL_TEMPLATE_PATH
37
+ Premailer.new(
38
+ render_template(path),
39
+ [
40
+ { warn_level: Premailer::Warnings::SAFE },
41
+ premailer_options,
42
+ { css_string: style, with_html_string: true }
43
+ ].reduce(&:merge)
44
+ ).to_inline_css
45
+ end
46
+
47
+ class << self
48
+ def render(params, options = {})
49
+ path = options[:template_path]
50
+ premailer = options[:premailer] || {}
51
+ Herbes::Email.new(params, options)
52
+ .render_inline_template(path, premailer)
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Herbes
4
+ VERSION = '0.0.2'
5
+ end
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: herbes
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - haydenmcfarland
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-03-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: nokogiri
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: premailer
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Simple ERB email generator
42
+ email:
43
+ - mcfarlandsms@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".gitignore"
49
+ - ".rspec"
50
+ - ".ruby-version"
51
+ - Gemfile
52
+ - Gemfile.lock
53
+ - README.md
54
+ - herbes.gemspec
55
+ - lib/herbes.rb
56
+ - lib/herbes/assets/styles/herbes.css
57
+ - lib/herbes/assets/templates/herbes.html.erb
58
+ - lib/herbes/constants.rb
59
+ - lib/herbes/email.rb
60
+ - lib/herbes/version.rb
61
+ homepage: https://github.com/haydenmcfarland/herbes
62
+ licenses:
63
+ - MIT
64
+ metadata: {}
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubygems_version: 3.1.2
81
+ signing_key:
82
+ specification_version: 4
83
+ summary: Simple ERB email generator for AWS Lambda
84
+ test_files: []