express_mailer 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +116 -0
- data/Rakefile +10 -0
- data/app/helpers/express_mailer_helper.rb +13 -0
- data/app/mailers/express_mailer/mailer.rb +19 -0
- data/app/views/express_mailer/mailer/express.html.erb +252 -0
- data/lib/express_mailer/attributes.rb +63 -0
- data/lib/express_mailer/button.rb +18 -0
- data/lib/express_mailer/configuration.rb +54 -0
- data/lib/express_mailer/engine.rb +7 -0
- data/lib/express_mailer/image.rb +29 -0
- data/lib/express_mailer/table.rb +22 -0
- data/lib/express_mailer/version.rb +3 -0
- data/lib/express_mailer.rb +77 -0
- data/lib/generators/express_mailer/express_mailer_generator.rb +7 -0
- data/lib/generators/express_mailer/templates/express_mailer.rb +34 -0
- metadata +134 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a20f339d604e9e19351758b36dd04e727658f5d2
|
4
|
+
data.tar.gz: a0c6848b974f528c88b7d70807de6906fe5d62cc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b235879b7bb4197fb6aeaa8be7831f8e1c23a37b234e361e72c230aa9402943ac137ef982e73788300a905d44fb9d6a823801379497e896a958cbd678214f8ea
|
7
|
+
data.tar.gz: fe76d22352232caae1c3456a1006fecad61648e24cfccd7d45c5de6138164552d5881572f0eadd2fd7ac0aef640bee9640826752dee9c7f0a0f98427deaa7d66
|
data/README.md
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
# ExpressMailer
|
2
|
+
|
3
|
+
ExpressMailer is intended to be a quick and easy way to send yourself or your team members nice looking emails about things that happen in your rails application. No need for creating a new Mailer, copy views, wade through email HTML, or any of that. Just tell ExpressMailer a few things about what you want to send, and it makes a pre-designed ActionMailer object you can manipulate or deliver.
|
4
|
+
|
5
|
+
![ExpressMailer Preview](https://raw.githubusercontent.com/orderedlist/express_mailer/master/preview/express_mailer.jpg)
|
6
|
+
|
7
|
+
### What this IS:
|
8
|
+
|
9
|
+
- A quick way to keep yourself up to date on events in your application
|
10
|
+
- Mildly customizable (fonts and colors)
|
11
|
+
- Pretty and flexible _enough_
|
12
|
+
|
13
|
+
### What this IS NOT:
|
14
|
+
|
15
|
+
ExpressMailer is not intended to be a replacement for your user transactional emails (signups, notifications, etc). While there's nothing really stopping you from using it as such, it's probably never going to be flexible enough to satisfy all the needs of transactional emails. For user facing stuff, you should actually make something that's better and more personalized than ExpressMailer.
|
16
|
+
|
17
|
+
## Installation
|
18
|
+
|
19
|
+
Add this line to your application's Gemfile:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
gem 'express_mailer'
|
23
|
+
```
|
24
|
+
|
25
|
+
And then execute:
|
26
|
+
|
27
|
+
$ bundle
|
28
|
+
|
29
|
+
Or install it yourself as:
|
30
|
+
|
31
|
+
$ gem install express_mailer
|
32
|
+
|
33
|
+
Generate the initializer:
|
34
|
+
|
35
|
+
$ rails generate express_mailer
|
36
|
+
|
37
|
+
Edit `config/initializers/express_mailer.rb` to modify your configuration.
|
38
|
+
|
39
|
+
## Usage
|
40
|
+
|
41
|
+
An ExpressMailer email can be made up of several pieces, many of which are optional.
|
42
|
+
|
43
|
+
- **app_logo:** or **app_name:** defined in the configuration (required)
|
44
|
+
- **preheader:** An introductory few words before the header, defaults to today's date (optional)
|
45
|
+
- **header:** Describe the event, defaults to the subject (required)
|
46
|
+
- **image:** Show an image, avatar, logo, or something else below the header (optional)
|
47
|
+
- **url:** The url of the image (required)
|
48
|
+
- **alt:** The alt text of the image (required)
|
49
|
+
- **background:** Background color of the image, defaults to transparent (optional)
|
50
|
+
- **shape:** Shape of the image (`:normal`, `:rounded`, or `:circle`), defaults to `:normal` (optional)
|
51
|
+
- **size:** Size of the image (`:normal`, or `:large`), defaults to `:normal` (optional)
|
52
|
+
- **headline:** Tell what happened (eg. an amount, a title, etc.) (optional)
|
53
|
+
- **table:** An array of arrays to give some details about the event (optional)
|
54
|
+
- **text:** A brief explanation of the event (optional)
|
55
|
+
- **button:** Give me something to click on (optional)
|
56
|
+
- **text:** The text of the button
|
57
|
+
- **href:** the href of the button
|
58
|
+
- **footer:** Give more info, or describe why the recipient is receiving the message (optional)
|
59
|
+
|
60
|
+
In addition to providing these details, there are some mail-specific attributes:
|
61
|
+
|
62
|
+
- **to:** an email or more, can also be set with **default_to:** in the configuration (required)
|
63
|
+
- **subject:** the subject line of the email (required)
|
64
|
+
- **from:** who the email is from, can also be set with **default_from:** in the configuration (required)
|
65
|
+
- **reply_to:** sets the reply-to header of the email (optional)
|
66
|
+
|
67
|
+
Given these attributes, there are 4 styles of emails that can be sent that loosly correspond to types of events: (**info**, **success**, **warning**, and **error**). These are called directly on `ExpressMailer`.
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
attributes = {
|
71
|
+
to: 'me@test.com',
|
72
|
+
subject: 'New Signup by Rachael Thompson',
|
73
|
+
preheader: 'New Signup',
|
74
|
+
header: 'Rachael Thompson',
|
75
|
+
headline: 'Premium Plan',
|
76
|
+
text: '$29/month',
|
77
|
+
button: {
|
78
|
+
text: 'View order',
|
79
|
+
href: 'http://example.com/orders/1'
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
mailer = ExpressMailer.success(attributes)
|
84
|
+
mailer.deliver
|
85
|
+
|
86
|
+
# Other styles can be used as well...
|
87
|
+
#
|
88
|
+
# ExpressMailer.info(attributes)
|
89
|
+
# ExpressMailer.success(attributes)
|
90
|
+
# ExpressMailer.warning(attributes)
|
91
|
+
# ExpressMailer.error(attributes)
|
92
|
+
#
|
93
|
+
# These will use the colors described in the configuration for each specific state
|
94
|
+
```
|
95
|
+
|
96
|
+
## Delivery
|
97
|
+
|
98
|
+
ExpressMailer relies on ActionMailer being setup to send in your system. If your application is already sending email, you shouldn't have to change anything. If not, check out setting up [SendGrid](https://github.com/sendgrid/sendgrid-ruby) or [Postmark](https://github.com/wildbit/postmark-rails).
|
99
|
+
|
100
|
+
## Development
|
101
|
+
|
102
|
+
After checking out the repo, run `bin/bootstrap` to install dependencies. Then, run `rake` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
103
|
+
|
104
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
105
|
+
|
106
|
+
## Contributing
|
107
|
+
|
108
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/orderedlist/express_mailer. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
109
|
+
|
110
|
+
## License
|
111
|
+
|
112
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
113
|
+
|
114
|
+
## Code of Conduct
|
115
|
+
|
116
|
+
Everyone interacting in the ExpressMailer project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/orderedlist/express_mailer/blob/master/CODE_OF_CONDUCT.md).
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
module ExpressMailerHelper
|
2
|
+
def express_mailer_headline_color(configuration, style)
|
3
|
+
configuration[:"#{style}_text_color"]
|
4
|
+
end
|
5
|
+
|
6
|
+
def express_mailer_button_text_color(configuration, style)
|
7
|
+
configuration[:"#{style}_button_text_color"]
|
8
|
+
end
|
9
|
+
|
10
|
+
def express_mailer_button_background_color(configuration, style)
|
11
|
+
configuration[:"#{style}_button_background_color"]
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
if defined?(ActionMailer)
|
4
|
+
class ExpressMailer::Mailer < ActionMailer::Base
|
5
|
+
layout false
|
6
|
+
|
7
|
+
def express(attributes, style = :info)
|
8
|
+
@config = ExpressMailer.configuration
|
9
|
+
@attributes = ExpressMailer::Attributes.new(attributes.merge(style: style))
|
10
|
+
|
11
|
+
mail({
|
12
|
+
to: @attributes.to,
|
13
|
+
from: @attributes.from,
|
14
|
+
reply_to: @attributes.reply_to,
|
15
|
+
subject: @attributes.subject
|
16
|
+
})
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,252 @@
|
|
1
|
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
2
|
+
<head>
|
3
|
+
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
4
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0;">
|
5
|
+
<meta name="format-detection" content="telephone=no"/>
|
6
|
+
|
7
|
+
<!-- Responsive Mobile-First Email Template by Konstantin Savchenko, 2015.
|
8
|
+
https://github.com/konsav/email-templates/ -->
|
9
|
+
|
10
|
+
<% if @attributes.webfont_url %>
|
11
|
+
<style type="text/css" media="screen">
|
12
|
+
@import url('<%= @attributes.webfont_url %>');
|
13
|
+
</style>
|
14
|
+
<% end %>
|
15
|
+
<style type="text/css" media="screen">
|
16
|
+
@media screen {
|
17
|
+
/* Thanks Outlook 2013! */
|
18
|
+
* {
|
19
|
+
font-family: <%= @attributes.text_font_family %>;
|
20
|
+
font-weight: 500;
|
21
|
+
}
|
22
|
+
|
23
|
+
.headline {
|
24
|
+
font-family: <%= @attributes.headline_font_family %>;
|
25
|
+
font-weight: 600;
|
26
|
+
}
|
27
|
+
}
|
28
|
+
</style>
|
29
|
+
<style>
|
30
|
+
/* Reset styles */
|
31
|
+
body { margin: 0; padding: 0; min-width: 100%; width: 100% !important; height: 100% !important;}
|
32
|
+
body, table, td, div, p, a { -webkit-font-smoothing: antialiased; text-size-adjust: 100%; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; line-height: 100%; }
|
33
|
+
table, td { mso-table-lspace: 0pt; mso-table-rspace: 0pt; border-collapse: collapse !important; border-spacing: 0; }
|
34
|
+
img { border: 0; line-height: 100%; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; }
|
35
|
+
#outlook a { padding: 0; }
|
36
|
+
.ReadMsgBody { width: 100%; } .ExternalClass { width: 100%; }
|
37
|
+
.ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div { line-height: 100%; }
|
38
|
+
.button {font-size: 18px; font-weight:700;}
|
39
|
+
/* Rounded corners for advanced mail clients only */
|
40
|
+
@media all and (min-width: 560px) {
|
41
|
+
.container { border-radius: 8px; -webkit-border-radius: 8px; -moz-border-radius: 8px; -khtml-border-radius: 8px; }
|
42
|
+
}
|
43
|
+
|
44
|
+
/* Set color for auto links (addresses, dates, etc.) */
|
45
|
+
a, a:hover, .color {
|
46
|
+
color: <%= @attributes.headline_text_color %>;
|
47
|
+
}
|
48
|
+
|
49
|
+
.logo a, .logo a:hover {
|
50
|
+
color: <%= @attributes.text_color %>;
|
51
|
+
letter-spacing: 3px;
|
52
|
+
}
|
53
|
+
|
54
|
+
.shape-circle {
|
55
|
+
border-radius: 100%;
|
56
|
+
overflow: hidden;
|
57
|
+
}
|
58
|
+
|
59
|
+
.shape-rounded {
|
60
|
+
border-radius: 8px;
|
61
|
+
overflow: hidden;
|
62
|
+
}
|
63
|
+
|
64
|
+
</style>
|
65
|
+
|
66
|
+
<!-- MESSAGE SUBJECT -->
|
67
|
+
<title><%= @attributes.subject %></title>
|
68
|
+
|
69
|
+
</head>
|
70
|
+
|
71
|
+
<!-- BODY -->
|
72
|
+
<!-- Set message background color (twice) and text color (twice) -->
|
73
|
+
<body topmargin="0" rightmargin="0" bottommargin="0" leftmargin="0" marginwidth="0" marginheight="0" width="100%" style="border-collapse: collapse; border-spacing: 0; margin: 0; padding: 0; width: 100%; height: 100%; -webkit-font-smoothing: antialiased; text-size-adjust: 100%; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; line-height: 100%;
|
74
|
+
background-color: <%= @attributes.background_color %>;
|
75
|
+
color: <%= @attributes.text_color %>;"
|
76
|
+
bgcolor="<%= @attributes.background_color %>"
|
77
|
+
text="<%= @attributes.text_color %>">
|
78
|
+
|
79
|
+
<!-- SECTION / BACKGROUND -->
|
80
|
+
<!-- Set message background color one again -->
|
81
|
+
<table width="100%" align="center" border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse; border-spacing: 0; margin: 0; padding: 0; padding-bottom: 50px; width: 100%;" class="background"><tr><td align="center" valign="top" style="border-collapse: collapse; border-spacing: 0; margin: 0; padding: 0;"
|
82
|
+
bgcolor="<%= @attributes.background_color %>">
|
83
|
+
|
84
|
+
<!-- WRAPPER -->
|
85
|
+
<!-- Set wrapper width (twice) -->
|
86
|
+
<table border="0" cellpadding="0" cellspacing="0" align="center"
|
87
|
+
width="500" style="border-collapse: collapse; border-spacing: 0; padding: 0; width: inherit;
|
88
|
+
max-width: 500px;" class="wrapper">
|
89
|
+
|
90
|
+
<tr>
|
91
|
+
<td align="center" valign="top" class="logo" style="border-collapse: collapse; border-spacing: 0; margin: 0; padding: 0; padding-left: 6.25%; padding-right: 6.25%; width: 87.5%;
|
92
|
+
padding-top: 40px;
|
93
|
+
padding-bottom: 20px;">
|
94
|
+
|
95
|
+
<!-- LOGO -->
|
96
|
+
<!-- Image text color should be opposite to background color. Set your url, image src, alt and title. Alt text should fit the image size. Real image size should be x2. URL format: http://domain.com/?utm_source={{Campaign-Source}}&utm_medium=email&utm_content=logo&utm_campaign={{Campaign-Name}} -->
|
97
|
+
<a target="_blank" style="text-decoration: none;"
|
98
|
+
href="<%= @attributes.app_url %>" style="color: <%= @attributes.text_color %>; font-family: <%= @attributes.text_font_family %>;">
|
99
|
+
<% if @attributes.app_logo %>
|
100
|
+
<img border="0" vspace="0" hspace="0"
|
101
|
+
src="<%= @attributes.app_logo %>"
|
102
|
+
height="34"
|
103
|
+
alt="<%= @attributes.app_name %>" title="<%= @attributes.app_name %>" style="
|
104
|
+
color: #FFFFFF;
|
105
|
+
font-size: 10px; margin: 0; padding: 0; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; border: none; display: block;" />
|
106
|
+
<% else %>
|
107
|
+
<%= @attributes.app_name.upcase %>
|
108
|
+
<% end %>
|
109
|
+
</a>
|
110
|
+
</td>
|
111
|
+
</tr>
|
112
|
+
|
113
|
+
<!-- PREHEADER -->
|
114
|
+
<!-- Set text color and font family ("sans-serif" or "Georgia, serif") -->
|
115
|
+
<tr>
|
116
|
+
<td align="center" class="color" valign="top" style="border-collapse: collapse; border-spacing: 0; margin: 0; padding: 0; padding-left: 6.25%; padding-right: 6.25%; width: 87.5%; font-size: 14px; font-weight: 400; line-height: 150%; letter-spacing: 2px;
|
117
|
+
padding-top: 27px;
|
118
|
+
padding-bottom: 0;
|
119
|
+
text-transform: uppercase;
|
120
|
+
color: <%= @attributes.headline_text_color %>;
|
121
|
+
font-family: <%= @attributes.text_font_family %>;" class="supheader">
|
122
|
+
<%= @attributes.preheader %>
|
123
|
+
</td>
|
124
|
+
</tr>
|
125
|
+
|
126
|
+
<!-- HEADER -->
|
127
|
+
<!-- Set text color and font family ("sans-serif" or "Georgia, serif") -->
|
128
|
+
<tr>
|
129
|
+
<td align="center" valign="top" style="border-collapse: collapse; border-spacing: 0; margin: 0; padding: 0; padding-left: 6.25%; padding-right: 6.25%; width: 87.5%; font-size: 36px; font-weight: 600; line-height: 130%;
|
130
|
+
padding-bottom: 20px;
|
131
|
+
color: <%= @attributes.text_color %>;
|
132
|
+
font-family: <%= @attributes.headline_font_family %>;" class="header headline">
|
133
|
+
<%= @attributes.header %>
|
134
|
+
</td>
|
135
|
+
</tr>
|
136
|
+
|
137
|
+
<% if @attributes.image %>
|
138
|
+
<!-- IMAGE -->
|
139
|
+
<tr>
|
140
|
+
<td align="center" class="color" valign="top" style="border-collapse: collapse; border-spacing: 0; margin: 0; padding: 0; padding-left: 6.25%; padding-right: 6.25%; width: 87.5%; font-size: 14px; font-weight: 400; line-height: 150%; letter-spacing: 2px;
|
141
|
+
padding-bottom: 20px;">
|
142
|
+
<div style="display: inline-block; overflow: hidden; background-color: <%= @attributes.image.background %>;" class="<%= @attributes.image.shape_class %>">
|
143
|
+
<img src="<%= @attributes.image.url %>" alt="<%= @attributes.image.alt %>" height="<%= @attributes.image.height %>" style="float: left;" />
|
144
|
+
</div>
|
145
|
+
</td>
|
146
|
+
</tr>
|
147
|
+
<% end %>
|
148
|
+
|
149
|
+
<% if @attributes.headline %>
|
150
|
+
<!-- HEADLINE -->
|
151
|
+
<tr>
|
152
|
+
<td align="center" class="color headline" valign="top" style="border-collapse: collapse; border-spacing: 0; margin: 0; padding: 0; padding-left: 6.25%; padding-right: 6.25%; width: 87.5%; font-size: 60px; font-weight: 600; line-height: 1.1; letter-spacing: 2px;
|
153
|
+
padding-bottom: 20px;
|
154
|
+
font-family: <%= @attributes.headline_font_family %>;">
|
155
|
+
<%= @attributes.headline %>
|
156
|
+
</td>
|
157
|
+
</tr>
|
158
|
+
<% end %>
|
159
|
+
|
160
|
+
<% if @attributes.table %>
|
161
|
+
<!-- HEADLINE -->
|
162
|
+
<tr>
|
163
|
+
<td align="center" valign="top" style="border-collapse: collapse; border-spacing: 0; margin: 0; padding: 0; width: 87.5%; font-size: 18px; font-weight: 600; line-height: 1.1;
|
164
|
+
padding-bottom: 30px; padding-top: 10px; padding-left: 6.25%; padding-right: 6.25%;
|
165
|
+
font-family: <%= @attributes.text_font_family %>;">
|
166
|
+
<table style="width: 100%; border-collapse: collapse; border-spacing: 0; margin: 0; padding: 0;">
|
167
|
+
<tr>
|
168
|
+
<td align="center" colspan="<%= @attributes.table.column_count %>" valign="top" style="border-collapse: collapse; border-spacing: 0; margin: 0; padding: 0; width: 87.5%;" class="line">
|
169
|
+
<hr color="<%= @attributes.border_color %>" align="center" width="100%" size="1" noshade style="margin: 0; padding: 0;" />
|
170
|
+
</td>
|
171
|
+
</tr>
|
172
|
+
<% @attributes.table.rows.each do |row| %>
|
173
|
+
<tr>
|
174
|
+
<% row.each_with_index do |col, idx| %>
|
175
|
+
<td style="text-align: <%= idx == row.count - 1 ? 'right' : 'left' %>; padding-top: 12px; padding-bottom: 12px; padding-left: 8px; padding-right: 8px; font-weight: 600; font-family: <%= @attributes.text_font_family %>; color: <%= @attributes.text_color %>;"><%= col %></td>
|
176
|
+
<% end %>
|
177
|
+
</tr>
|
178
|
+
<tr>
|
179
|
+
<td align="center" colspan="<%= @attributes.table.column_count %>" valign="top" style="border-collapse: collapse; border-spacing: 0; margin: 0; padding: 0; width: 87.5%;" class="line">
|
180
|
+
<hr color="<%= @attributes.border_color %>" align="center" width="100%" size="1" noshade style="margin: 0; padding: 0;" />
|
181
|
+
</td>
|
182
|
+
</tr>
|
183
|
+
<% end %>
|
184
|
+
</table>
|
185
|
+
</td>
|
186
|
+
</tr>
|
187
|
+
<% end %>
|
188
|
+
|
189
|
+
<% if @attributes.text %>
|
190
|
+
<!-- TEXT -->
|
191
|
+
<tr>
|
192
|
+
<td align="<%= @attributes.text_align %>" valign="top" style="border-collapse: collapse; border-spacing: 0; margin: 0; padding: 0; padding-left: 6.25%; padding-right: 6.25%; width: 87.5%; font-size: <%= @attributes.text_size %>px; font-weight: 400; line-height: 1.3;
|
193
|
+
padding-bottom: 20px;
|
194
|
+
color: <%= @attributes.text_color %>;
|
195
|
+
font-family: <%= @attributes.text_font_family %>;" class="paragraph">
|
196
|
+
<%= @attributes.text %>
|
197
|
+
</td>
|
198
|
+
</tr>
|
199
|
+
<% end %>
|
200
|
+
|
201
|
+
<% if @attributes.button %>
|
202
|
+
<!-- BUTTON -->
|
203
|
+
<!-- Set button background color at TD, link/text color at A and TD, font family ("sans-serif" or "Georgia, serif") at TD. For verification codes add "letter-spacing: 5px;". Link format: http://domain.com/?utm_source={{Campaign-Source}}&utm_medium=email&utm_content={{Button-Name}}&utm_campaign={{Campaign-Name}} -->
|
204
|
+
<tr>
|
205
|
+
<td align="center" valign="top" style="border-collapse: collapse; border-spacing: 0; margin: 0; padding: 0; padding-left: 6.25%; padding-right: 6.25%; width: 87.5%;
|
206
|
+
padding-top: 10px;
|
207
|
+
padding-bottom: 5px;" class="button"><a
|
208
|
+
href="<%= @attributes.button.href %>" target="_blank" style="text-decoration: none;">
|
209
|
+
<table border="0" cellpadding="0" cellspacing="0" align="center" style="max-width: 240px; min-width: 120px; border-collapse: collapse; border-spacing: 0; padding: 0;"><tr><td align="center" valign="middle" style="padding: 12px 24px; margin: 0; text-decoration: none; border-collapse: collapse; border-spacing: 0; border-radius: 4px; -webkit-border-radius: 4px; -moz-border-radius: 4px; -khtml-border-radius: 4px;"
|
210
|
+
bgcolor="<%= @attributes.button_background_color %>"><a target="_blank" style="text-decoration: none;
|
211
|
+
color: <%= @attributes.button_text_color %>; font-family: <%= @attributes.text_font_family %>; font-size: 17px; font-weight: 700; line-height: 120%;"
|
212
|
+
href="<%= @attributes.button.href %>" class="button">
|
213
|
+
<%= @attributes.button.text %>
|
214
|
+
</a>
|
215
|
+
</td></tr></table></a>
|
216
|
+
</td>
|
217
|
+
</tr>
|
218
|
+
<% end %>
|
219
|
+
|
220
|
+
<!-- more stuff here -->
|
221
|
+
|
222
|
+
<% if @attributes.footer %>
|
223
|
+
<!-- LINE -->
|
224
|
+
<!-- Set line color -->
|
225
|
+
<tr>
|
226
|
+
<td align="center" valign="top" style="border-collapse: collapse; border-spacing: 0; margin: 0; padding: 0; padding-left: 6.25%; padding-right: 6.25%; width: 87.5%;
|
227
|
+
padding-top: 30px;" class="line"><hr
|
228
|
+
color="<%= @attributes.border_color %>" align="center" width="100%" size="1" noshade style="margin: 0; padding: 0;" />
|
229
|
+
</td>
|
230
|
+
</tr>
|
231
|
+
|
232
|
+
<!-- FOOTER -->
|
233
|
+
<!-- Set text color and font family ("sans-serif" or "Georgia, serif"). Duplicate all text styles in links, including line-height -->
|
234
|
+
<tr>
|
235
|
+
<td align="center" valign="top" style="border-collapse: collapse; border-spacing: 0; margin: 0; padding: 0; padding-left: 6.25%; padding-right: 6.25%; width: 87.5%; font-size: 14px; font-weight: 400; line-height: 150%;
|
236
|
+
padding-top: 10px;
|
237
|
+
padding-bottom: 30px;
|
238
|
+
color: <%= @attributes.text_color %>;
|
239
|
+
font-family: <%= @attributes.text_font_family %>;" class="footer">
|
240
|
+
<%= sanitize(@attributes.footer, :tags => %w(a br)).html_safe %>
|
241
|
+
</td>
|
242
|
+
</tr>
|
243
|
+
<% end %>
|
244
|
+
|
245
|
+
<!-- End of WRAPPER -->
|
246
|
+
</table>
|
247
|
+
|
248
|
+
<!-- End of SECTION / BACKGROUND -->
|
249
|
+
</td></tr></table>
|
250
|
+
|
251
|
+
</body>
|
252
|
+
</html>
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'express_mailer/image'
|
2
|
+
require 'express_mailer/table'
|
3
|
+
require 'express_mailer/button'
|
4
|
+
|
5
|
+
module ExpressMailer
|
6
|
+
class Attributes
|
7
|
+
attr_accessor :configuration, :style, :to, :from, :reply_to, :subject,
|
8
|
+
:preheader, :header, :image, :footer, :headline, :table, :text, :button
|
9
|
+
|
10
|
+
delegate :app_url, :app_name, :app_logo, :text_color, :background_color,
|
11
|
+
:border_color, :webfont_url, :text_font_family, :headline_font_family,
|
12
|
+
to: :configuration
|
13
|
+
|
14
|
+
def initialize(options = {})
|
15
|
+
@configuration = ExpressMailer.configuration
|
16
|
+
@style = options.fetch(:style, :info)
|
17
|
+
@to = options.fetch(:to, @configuration.default_to)
|
18
|
+
@from = options.fetch(:from, @configuration.default_from)
|
19
|
+
@reply_to = options.fetch(:reply_to, nil)
|
20
|
+
@subject = options.fetch(:subject, "Express Mail")
|
21
|
+
@preheader = options.fetch(:preheader, Date.today.strftime('%B %-d, %Y'))
|
22
|
+
@header = options.fetch(:header, @subject)
|
23
|
+
@footer = options.fetch(:footer, @configuration.default_footer)
|
24
|
+
@headline = options.fetch(:headline, nil)
|
25
|
+
@image = ExpressMailer::Image.create(options.fetch(:image, nil))
|
26
|
+
@table = ExpressMailer::Table.create(options.fetch(:table, nil))
|
27
|
+
@button = ExpressMailer::Button.create(options.fetch(:button, nil))
|
28
|
+
@text = options.fetch(:text, nil)
|
29
|
+
end
|
30
|
+
|
31
|
+
def subject
|
32
|
+
"#{@configuration.subject_prefix} #{@subject}".strip
|
33
|
+
end
|
34
|
+
|
35
|
+
def headline_text_color
|
36
|
+
@configuration.instance_variable_get(:"@#{@style}_text_color")
|
37
|
+
end
|
38
|
+
|
39
|
+
def button_text_color
|
40
|
+
@configuration.instance_variable_get(:"@#{@style}_button_text_color")
|
41
|
+
end
|
42
|
+
|
43
|
+
def button_background_color
|
44
|
+
@configuration.instance_variable_get(:"@#{@style}_button_background_color")
|
45
|
+
end
|
46
|
+
|
47
|
+
def text_align
|
48
|
+
if @text.to_s.length > 240
|
49
|
+
:left
|
50
|
+
else
|
51
|
+
:center
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def text_size
|
56
|
+
if @text.to_s.length > 60
|
57
|
+
20
|
58
|
+
else
|
59
|
+
26
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module ExpressMailer
|
2
|
+
class Button
|
3
|
+
attr_accessor :text, :href
|
4
|
+
|
5
|
+
def self.create(options)
|
6
|
+
if options
|
7
|
+
new(options)
|
8
|
+
else
|
9
|
+
nil
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(options = {})
|
14
|
+
@text = options.fetch(:text)
|
15
|
+
@href = options.fetch(:href)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module ExpressMailer
|
2
|
+
class Configuration
|
3
|
+
attr_accessor :default_to, :default_from, :default_footer,
|
4
|
+
:subject_prefix, :app_name, :app_logo, :app_url,
|
5
|
+
:background_color, :text_color, :border_color, :webfont_url,
|
6
|
+
:headline_font_family, :text_font_family,
|
7
|
+
:info_text_color, :info_button_text_color, :info_button_background_color,
|
8
|
+
:success_text_color, :success_button_text_color, :success_button_background_color,
|
9
|
+
:warning_text_color, :warning_button_text_color, :warning_button_background_color,
|
10
|
+
:error_text_color, :error_button_text_color, :error_button_background_color
|
11
|
+
|
12
|
+
def initialize(options = {})
|
13
|
+
@default_to = options.fetch(:default_to, nil)
|
14
|
+
@default_from = options.fetch(:default_from, 'noreply@example.com')
|
15
|
+
@default_footer = options.fetch(:default_footer, nil)
|
16
|
+
@subject_prefix = options.fetch(:subject_prefix, nil)
|
17
|
+
@app_name = options.fetch(:app_name, 'Example Company')
|
18
|
+
@app_logo = options.fetch(:app_logo, nil)
|
19
|
+
@app_url = options.fetch(:app_url, 'http://example.com')
|
20
|
+
|
21
|
+
@background_color = options.fetch(:background_color, '#212E3C')
|
22
|
+
@text_color = options.fetch(:text_color, '#FFF')
|
23
|
+
@border_color = options.fetch(:border_color, '#5E637A')
|
24
|
+
|
25
|
+
@webfont_url = options.fetch(:webfont_url, 'https://fonts.googleapis.com/css?family=Dosis:600|Lato:400,400i,700,700i')
|
26
|
+
@headline_font_family = options.fetch(:headline_font_family, "Dosis, 'Helvetica Neue', 'Arial', 'sans-serif'")
|
27
|
+
@text_font_family = options.fetch(:text_font_family, "Lato, 'Helvetica Neue', 'Arial', 'sans-serif'")
|
28
|
+
|
29
|
+
@info_text_color = options.fetch(:info_text_color, '#AC8DF7')
|
30
|
+
@info_button_text_color = options.fetch(:info_button_text_color, @background_color)
|
31
|
+
@info_button_background_color = options.fetch(:info_button_text_color, @info_text_color)
|
32
|
+
|
33
|
+
@success_text_color = options.fetch(:success_text_color, '#02D6A1')
|
34
|
+
@success_button_text_color = options.fetch(:success_button_text_color, @background_color)
|
35
|
+
@success_button_background_color = options.fetch(:success_button_text_color, @success_text_color)
|
36
|
+
|
37
|
+
@warning_text_color = options.fetch(:warning_text_color, '#FFD166')
|
38
|
+
@warning_button_text_color = options.fetch(:warning_button_text_color, @background_color)
|
39
|
+
@warning_button_background_color = options.fetch(:warning_button_text_color, @warning_text_color)
|
40
|
+
|
41
|
+
@error_text_color = options.fetch(:error_text_color, '#EF476F')
|
42
|
+
@error_button_text_color = options.fetch(:error_button_text_color, @background_color)
|
43
|
+
@error_button_background_color = options.fetch(:error_button_text_color, @error_text_color)
|
44
|
+
end
|
45
|
+
|
46
|
+
def text_font_family
|
47
|
+
@text_font_family.gsub('"', '\'').html_safe
|
48
|
+
end
|
49
|
+
|
50
|
+
def headline_font_family
|
51
|
+
@headline_font_family.gsub('"', '\'').html_safe
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module ExpressMailer
|
2
|
+
class Image
|
3
|
+
attr_accessor :url, :alt, :background, :shape, :size
|
4
|
+
|
5
|
+
def self.create(attrs)
|
6
|
+
if attrs
|
7
|
+
new(attrs)
|
8
|
+
else
|
9
|
+
nil
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(options = {})
|
14
|
+
@url = options.fetch(:url)
|
15
|
+
@alt = options.fetch(:alt)
|
16
|
+
@background = options.fetch(:background, 'transparent')
|
17
|
+
@shape = options.fetch(:shape, :normal) # :normal, :circle, :rounded
|
18
|
+
@size = options.fetch(:size, :normal) # :normal, :large
|
19
|
+
end
|
20
|
+
|
21
|
+
def shape_class
|
22
|
+
"shape-#{shape}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def height
|
26
|
+
@size.to_sym == :large ? 240 : 120
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module ExpressMailer
|
2
|
+
class Table
|
3
|
+
attr_accessor :data, :column_count
|
4
|
+
|
5
|
+
def self.create(data)
|
6
|
+
if data
|
7
|
+
new(data)
|
8
|
+
else
|
9
|
+
nil
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(data = [])
|
14
|
+
@data = data
|
15
|
+
@column_count = rows[0].size
|
16
|
+
end
|
17
|
+
|
18
|
+
def rows
|
19
|
+
@data
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require "express_mailer/attributes"
|
2
|
+
require "express_mailer/configuration"
|
3
|
+
require "express_mailer/engine"
|
4
|
+
require "express_mailer/version"
|
5
|
+
|
6
|
+
module ExpressMailer
|
7
|
+
module_function
|
8
|
+
|
9
|
+
# Public: Configure express mailer.
|
10
|
+
#
|
11
|
+
# ExpressMailer.configure do |config|
|
12
|
+
# config.default { ... }
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# Yields ExpressMailer::Configuration instance.
|
16
|
+
def configure
|
17
|
+
yield configuration if block_given?
|
18
|
+
end
|
19
|
+
|
20
|
+
# Public: Returns ExpressMailer::Configuration instance.
|
21
|
+
def configuration
|
22
|
+
@configuration ||= Configuration.new
|
23
|
+
end
|
24
|
+
|
25
|
+
# Public: Sets ExpressMailer::Configuration instance.
|
26
|
+
def configuration=(configuration)
|
27
|
+
@configuration = configuration
|
28
|
+
end
|
29
|
+
|
30
|
+
# Public: Creates an ActionMailer instance with attributes using the info styles
|
31
|
+
#
|
32
|
+
# ExpressMailer.info({
|
33
|
+
# to: 'steve@orderedlist.com',
|
34
|
+
# subject: 'Subscriptions processed',
|
35
|
+
# ...
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
def info(attributes)
|
39
|
+
ExpressMailer::Mailer.express(attributes, :info)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Public: Creates an ActionMailer instance with attributes using the info styles
|
43
|
+
#
|
44
|
+
# ExpressMailer.success({
|
45
|
+
# to: 'steve@orderedlist.com',
|
46
|
+
# subject: 'Subscriptions processed',
|
47
|
+
# ...
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
def success(attributes)
|
51
|
+
ExpressMailer::Mailer.express(attributes, :success)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Public: Creates an ActionMailer instance with attributes using the info styles
|
55
|
+
#
|
56
|
+
# ExpressMailer.warning({
|
57
|
+
# to: 'steve@orderedlist.com',
|
58
|
+
# subject: 'Subscriptions processed',
|
59
|
+
# ...
|
60
|
+
# end
|
61
|
+
#
|
62
|
+
def warning(attributes)
|
63
|
+
ExpressMailer::Mailer.express(attributes, :warning)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Public: Creates an ActionMailer instance with attributes using the info styles
|
67
|
+
#
|
68
|
+
# ExpressMailer.error({
|
69
|
+
# to: 'steve@orderedlist.com',
|
70
|
+
# subject: 'Subscriptions processed',
|
71
|
+
# ...
|
72
|
+
# end
|
73
|
+
#
|
74
|
+
def error(attributes)
|
75
|
+
ExpressMailer::Mailer.express(attributes, :error)
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
ExpressMailer.configure do |config|
|
2
|
+
config.default_from = 'Example App <noreply@example.com>'
|
3
|
+
config.app_name = 'Example Company'
|
4
|
+
config.app_url = 'http://example.com'
|
5
|
+
|
6
|
+
#config.default_to = 'admins@example.com'
|
7
|
+
#config.default_footer = 'This was only sent to Admins'
|
8
|
+
|
9
|
+
# config.subject_prefix = '[Example]'
|
10
|
+
# config.app_logo = 'https://s3.amazon.com/example/mailers/example-white.png'
|
11
|
+
# config.background_color = '#212E3C'
|
12
|
+
# config.text_color = '#fff'
|
13
|
+
# config.border_color = '#5E637A'
|
14
|
+
#
|
15
|
+
# config.webfont_url = 'https://fonts.googleapis.com/css?family=Dosis:600|Lato:400,400i,700,700i'
|
16
|
+
# config.headline_font_family = "Dosis, 'Helvetica Neue', 'Arial', 'sans-serif'"
|
17
|
+
# config.text_font_family = "Lato, 'Helvetica Neue', 'Arial', 'sans-serif'"
|
18
|
+
#
|
19
|
+
# config.info_text_color = '#AC8DF7'
|
20
|
+
# config.info_button_text_color = config.background_color
|
21
|
+
# config.info_button_background_color = config.info_text_color
|
22
|
+
#
|
23
|
+
# config.success_text_color = '#02D6A1'
|
24
|
+
# config.success_button_text_color = config.background_color
|
25
|
+
# config.success_button_background_color = config.info_text_color
|
26
|
+
#
|
27
|
+
# config.warning_text_color = '#FFD166'
|
28
|
+
# config.warning_button_text_color = config.background_color
|
29
|
+
# config.warning_button_background_color = config.info_text_color
|
30
|
+
#
|
31
|
+
# config.error_text_color = '#EF476F'
|
32
|
+
# config.error_button_text_color = config.background_color
|
33
|
+
# config.error_button_background_color = config.info_text_color
|
34
|
+
end
|
metadata
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: express_mailer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Steve Smith
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-03-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.15'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.15'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '5.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '5.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rails
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '5.1'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '5.1'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: sqlite3
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.3'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.3'
|
83
|
+
description: ExpressMailer is intended to be a quick and easy way to send yourself
|
84
|
+
or your team members nice looking emails about things that happen in your rails
|
85
|
+
application. No need for creating a new Mailer, copy views, wade through email HTML,
|
86
|
+
or any of that. Just tell ExpressMailer a few things about what you want to send,
|
87
|
+
and it makes a pre-designed ActionMailer object you can manipulate or deliver.
|
88
|
+
email:
|
89
|
+
- steve@orderedlist.com
|
90
|
+
executables: []
|
91
|
+
extensions: []
|
92
|
+
extra_rdoc_files: []
|
93
|
+
files:
|
94
|
+
- README.md
|
95
|
+
- Rakefile
|
96
|
+
- app/helpers/express_mailer_helper.rb
|
97
|
+
- app/mailers/express_mailer/mailer.rb
|
98
|
+
- app/views/express_mailer/mailer/express.html.erb
|
99
|
+
- lib/express_mailer.rb
|
100
|
+
- lib/express_mailer/attributes.rb
|
101
|
+
- lib/express_mailer/button.rb
|
102
|
+
- lib/express_mailer/configuration.rb
|
103
|
+
- lib/express_mailer/engine.rb
|
104
|
+
- lib/express_mailer/image.rb
|
105
|
+
- lib/express_mailer/table.rb
|
106
|
+
- lib/express_mailer/version.rb
|
107
|
+
- lib/generators/express_mailer/express_mailer_generator.rb
|
108
|
+
- lib/generators/express_mailer/templates/express_mailer.rb
|
109
|
+
homepage: https://github.com/orderedlist/express_mailer
|
110
|
+
licenses:
|
111
|
+
- MIT
|
112
|
+
metadata: {}
|
113
|
+
post_install_message:
|
114
|
+
rdoc_options: []
|
115
|
+
require_paths:
|
116
|
+
- lib
|
117
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - ">="
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
127
|
+
requirements: []
|
128
|
+
rubyforge_project:
|
129
|
+
rubygems_version: 2.5.1
|
130
|
+
signing_key:
|
131
|
+
specification_version: 4
|
132
|
+
summary: An easy way to send yourself or your team members nice looking emails about
|
133
|
+
things that happen in your rails application.
|
134
|
+
test_files: []
|