antwort 0.0.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.rspec +2 -0
- data/.rubocop.yml +19 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +249 -0
- data/Gemfile +3 -0
- data/Guardfile +14 -0
- data/README.md +108 -0
- data/Rakefile +14 -0
- data/antwort.gemspec +45 -0
- data/bin/antwort +5 -0
- data/lib/antwort.rb +13 -0
- data/lib/antwort/builder.rb +8 -0
- data/lib/antwort/builder/builder.rb +104 -0
- data/lib/antwort/builder/email.rb +61 -0
- data/lib/antwort/builder/flattener.rb +37 -0
- data/lib/antwort/builder/helpers/logic.rb +82 -0
- data/lib/antwort/builder/helpers/sanitizers.rb +29 -0
- data/lib/antwort/builder/partial.rb +80 -0
- data/lib/antwort/builder/style.rb +59 -0
- data/lib/antwort/cli.rb +7 -0
- data/lib/antwort/cli/cli.rb +275 -0
- data/lib/antwort/cli/helpers.rb +44 -0
- data/lib/antwort/cli/send.rb +79 -0
- data/lib/antwort/cli/upload.rb +89 -0
- data/lib/antwort/helpers.rb +19 -0
- data/lib/antwort/server.rb +70 -0
- data/lib/antwort/server/assets.rb +23 -0
- data/lib/antwort/server/helpers.rb +67 -0
- data/lib/antwort/server/markup.rb +39 -0
- data/lib/antwort/version.rb +3 -0
- data/spec/builder/builder_spec.rb +30 -0
- data/spec/builder/email_spec.rb +21 -0
- data/spec/builder/flattener_spec.rb +64 -0
- data/spec/builder/helpers_logic_spec.rb +244 -0
- data/spec/builder/partial_spec.rb +87 -0
- data/spec/builder/style_spec.rb +66 -0
- data/spec/cli/helpers_spec.rb +60 -0
- data/spec/cli/upload_spec.rb +47 -0
- data/spec/cli_spec.rb +46 -0
- data/spec/fixtures/assets/images/1-demo/placeholder.png +0 -0
- data/spec/fixtures/assets/images/newsletter/placeholder.png +0 -0
- data/spec/fixtures/assets/images/shared/placeholder-grey.png +0 -0
- data/spec/fixtures/assets/images/shared/placeholder-white.png +0 -0
- data/spec/fixtures/build/demo-123456/build.html +7 -0
- data/spec/fixtures/build/demo-123457/build.html +7 -0
- data/spec/fixtures/build/demo-bar-123/build.html +7 -0
- data/spec/fixtures/build/foo-1/build.html +7 -0
- data/spec/fixtures/data/1-demo.yml +3 -0
- data/spec/fixtures/emails/1-demo/index.html.erb +9 -0
- data/spec/fixtures/emails/2-no-layout/index.html.erb +6 -0
- data/spec/fixtures/emails/3-no-title/index.html.erb +1 -0
- data/spec/fixtures/views/404.html.erb +1 -0
- data/spec/fixtures/views/index.html.erb +14 -0
- data/spec/fixtures/views/layout.erb +8 -0
- data/spec/fixtures/views/server.erb +5 -0
- data/spec/server_spec.rb +54 -0
- data/spec/spec_helper.rb +38 -0
- data/spec/support/capture.rb +17 -0
- data/template/email/css/include.scss +5 -0
- data/template/email/css/inline.scss +5 -0
- data/template/email/email.html.erb +11 -0
- data/template/email/images/.empty_directory +0 -0
- data/template/project/.env.sample +21 -0
- data/template/project/.gitignore.tt +17 -0
- data/template/project/.ruby-version +1 -0
- data/template/project/Gemfile.tt +9 -0
- data/template/project/Guardfile +9 -0
- data/template/project/assets/css/demo/include.scss +3 -0
- data/template/project/assets/css/demo/inline.scss +33 -0
- data/template/project/assets/css/server.scss +167 -0
- data/template/project/assets/css/shared/_base.scss +64 -0
- data/template/project/assets/css/shared/_mixins.scss +25 -0
- data/template/project/assets/css/shared/_reset.scss +59 -0
- data/template/project/assets/css/shared/_vars.scss +12 -0
- data/template/project/assets/css/shared/include.scss +23 -0
- data/template/project/assets/css/shared/inline.scss +9 -0
- data/template/project/assets/images/.gitkeep +0 -0
- data/template/project/assets/images/shared/placeholder.png +0 -0
- data/template/project/build/.empty_directory +0 -0
- data/template/project/data/.empty_directory +0 -0
- data/template/project/data/config.yml +3 -0
- data/template/project/data/demo.yml +4 -0
- data/template/project/emails/demo/_partial.html.erb +9 -0
- data/template/project/emails/demo/index.html.erb +54 -0
- data/template/project/views/404.html.erb +8 -0
- data/template/project/views/index.html.erb +18 -0
- data/template/project/views/layout.erb +38 -0
- data/template/project/views/markup/_button.html.erb +5 -0
- data/template/project/views/markup/_image_tag.html.erb +10 -0
- data/template/project/views/server.erb +32 -0
- metadata +443 -0
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
ENV['RACK_ENV'] = 'test'
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
require 'antwort'
|
5
|
+
require 'rspec'
|
6
|
+
require 'rack/test'
|
7
|
+
|
8
|
+
Pathname.glob(Pathname(__dir__) + 'support' '**/*.rb').each { |f| require f }
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
# Run specs in random order to surface order dependencies. If you find an
|
12
|
+
# order dependency and want to debug it, you can fix the order by providing
|
13
|
+
# the seed, which is printed after each run.
|
14
|
+
# --seed 1234
|
15
|
+
config.order = 'random'
|
16
|
+
|
17
|
+
config.include Rack::Test::Methods
|
18
|
+
|
19
|
+
config.filter_run focus: true
|
20
|
+
config.run_all_when_everything_filtered = true
|
21
|
+
config.raise_errors_for_deprecations!
|
22
|
+
|
23
|
+
config.mock_with :rspec do |mocks|
|
24
|
+
mocks.syntax = :expect
|
25
|
+
end
|
26
|
+
|
27
|
+
# move to .env later
|
28
|
+
config.before :suite do
|
29
|
+
ENV['AWS_ACCESS_KEY_ID'] ||= 'MY_TEST_ACCESS_KEY'
|
30
|
+
ENV['AWS_SECRET_ACCESS_KEY'] ||= 'MY_TEST_SECRET_ACCESS_KEY'
|
31
|
+
ENV['AWS_BUCKET'] ||= 'MY_TEST_BUCKET'
|
32
|
+
end
|
33
|
+
|
34
|
+
def fixtures_root
|
35
|
+
File.join(File.dirname(__FILE__), "fixtures")
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Source: https://github.com/erikhuda/thor
|
2
|
+
# License: MIT
|
3
|
+
|
4
|
+
def capture(stream)
|
5
|
+
begin
|
6
|
+
stream = stream.to_s
|
7
|
+
eval "$#{stream} = StringIO.new"
|
8
|
+
yield
|
9
|
+
result = eval("$#{stream}").string
|
10
|
+
ensure
|
11
|
+
eval("$#{stream} = #{stream.upcase}")
|
12
|
+
end
|
13
|
+
|
14
|
+
result
|
15
|
+
end
|
16
|
+
|
17
|
+
alias silence capture
|
File without changes
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Settings required for sending test emails
|
2
|
+
SEND_TO: me@example.com
|
3
|
+
SEND_FROM: me@example.com
|
4
|
+
SMTP_SERVER: smtp.mandrillapp.com
|
5
|
+
SMTP_PORT: 587
|
6
|
+
SMTP_USERNAME: username
|
7
|
+
SMTP_PASSWORD: password
|
8
|
+
|
9
|
+
# Required for building emails
|
10
|
+
# Where are your assets served from?
|
11
|
+
ASSET_SERVER: https://example.s3.amazonaws.com
|
12
|
+
|
13
|
+
# Any empty links, e.g. '/' or '#' will be overwritten to use a full URL instead
|
14
|
+
# Otherwise clients like Outlook.com struggle
|
15
|
+
HREF_PLACEHOLDER: http://example.com
|
16
|
+
|
17
|
+
# Required for uploading images
|
18
|
+
AWS_ACCESS_KEY_ID: ''
|
19
|
+
AWS_SECRET_ACCESS_KEY: ''
|
20
|
+
AWS_BUCKET: ''
|
21
|
+
FOG_REGION: ''
|
@@ -0,0 +1 @@
|
|
1
|
+
2.2.2
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<% if @user %>
|
2
|
+
source 'https://<%= @user %>:<%= @key %>@offsides-gems.herokuapp.com/'
|
3
|
+
<% else %>
|
4
|
+
# Forgot credentials? Contact support@antwort.co.
|
5
|
+
# source 'https://USERNAME:KEY@offsides-gems.herokuapp.com/'
|
6
|
+
<% end %>
|
7
|
+
source 'https://rubygems.org'
|
8
|
+
|
9
|
+
gem 'antwort'
|
@@ -0,0 +1,9 @@
|
|
1
|
+
guard 'livereload' do
|
2
|
+
watch(%r{^.rb})
|
3
|
+
watch(%r{^emails/.*/(.*)\.(erb)})
|
4
|
+
watch(%r{^emails/(.*)\.erb})
|
5
|
+
watch(%r{^views/.*/(.*)\.(erb)})
|
6
|
+
watch(%r{^views/(.*)\.erb})
|
7
|
+
watch(%r{^assets/css/.*/(.*)\.(css|scss)})
|
8
|
+
watch(%r{^assets/css/(.*)\.(css|scss)})
|
9
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
// demo/inline.scss
|
2
|
+
|
3
|
+
@import "../shared/inline";
|
4
|
+
|
5
|
+
// Use email specific stylesheets for custom code that isn't used elsewhere.
|
6
|
+
// This helps for overriding default styles.
|
7
|
+
|
8
|
+
code {
|
9
|
+
font-size: 14px;
|
10
|
+
line-height: 16px;
|
11
|
+
font-family: 'Courier New', Courier, monospace;
|
12
|
+
background-color: #eeeeee;
|
13
|
+
color: #333333;
|
14
|
+
|
15
|
+
display: inline-block;
|
16
|
+
padding: 0 4px;
|
17
|
+
vertical-align: middle;
|
18
|
+
}
|
19
|
+
|
20
|
+
.table {
|
21
|
+
td {
|
22
|
+
border: 1px solid #dddddd;
|
23
|
+
border-left-width: 0;
|
24
|
+
padding-top: 10px;
|
25
|
+
padding-bottom: 10px;
|
26
|
+
&:first-child {
|
27
|
+
border-left-width: 1px;
|
28
|
+
}
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
32
|
+
// Note: These layout styles may not work across all email clients.
|
33
|
+
// They are here for documentation purposes.
|
@@ -0,0 +1,167 @@
|
|
1
|
+
|
2
|
+
$bodyFont: 'Helvetica Neue', Helvetica, sans-serif;
|
3
|
+
$headlineFont: 'Open Sans', 'Helvetica Neue', Helvetica, sans-serif;
|
4
|
+
|
5
|
+
$bodyColor: #444;
|
6
|
+
$blue: #018696;
|
7
|
+
$darkBlue: #374550;
|
8
|
+
$green: #ACC642;
|
9
|
+
$orange: #DF4726;
|
10
|
+
$yellow: #FFC526;
|
11
|
+
$linkColor: #7AA6B6;
|
12
|
+
$linkVisitedColor: darken($linkColor, 10%);
|
13
|
+
$linkHoverColor: lighten($linkColor, 10%);
|
14
|
+
$borderColor: #ddd;
|
15
|
+
|
16
|
+
html {
|
17
|
+
font-size: 100%;
|
18
|
+
-webkit-text-size-adjust: 100%;
|
19
|
+
-ms-text-size-adjust: 100%;
|
20
|
+
text-rendering: optimizeLegibility;
|
21
|
+
}
|
22
|
+
|
23
|
+
body {
|
24
|
+
color: $bodyColor;
|
25
|
+
font: 400 14px/1.5em $bodyFont;
|
26
|
+
padding: 0;
|
27
|
+
margin: 0;
|
28
|
+
}
|
29
|
+
|
30
|
+
a {
|
31
|
+
outline: none;
|
32
|
+
}
|
33
|
+
|
34
|
+
a:link {
|
35
|
+
color: $linkColor;
|
36
|
+
}
|
37
|
+
|
38
|
+
a:visited {
|
39
|
+
color: $linkVisitedColor;
|
40
|
+
}
|
41
|
+
|
42
|
+
a:hover,
|
43
|
+
a:active {
|
44
|
+
color: $linkHoverColor;
|
45
|
+
}
|
46
|
+
|
47
|
+
a:focus {
|
48
|
+
outline: none;
|
49
|
+
outline-style: none;
|
50
|
+
-moz-outline-style: none;
|
51
|
+
}
|
52
|
+
|
53
|
+
hr {
|
54
|
+
border: 0;
|
55
|
+
border-bottom: 1px solid $borderColor;
|
56
|
+
margin: 2em 0;
|
57
|
+
}
|
58
|
+
|
59
|
+
code {
|
60
|
+
background-color: #f3f3f3;
|
61
|
+
padding: 2px 6px;
|
62
|
+
}
|
63
|
+
|
64
|
+
h1 {
|
65
|
+
font: 600 2em/1.5em $headlineFont;
|
66
|
+
}
|
67
|
+
|
68
|
+
h2 {
|
69
|
+
font: 600 1.5em/1.5em $headlineFont;
|
70
|
+
color: $orange;
|
71
|
+
}
|
72
|
+
|
73
|
+
h3 {
|
74
|
+
font-weight: 500;
|
75
|
+
font-size: 1.25em; // 20/16
|
76
|
+
line-height: 1.5em;
|
77
|
+
font-family: $bodyFont;
|
78
|
+
}
|
79
|
+
|
80
|
+
h4 {
|
81
|
+
font: 400 1.125em/1.5em $bodyFont; // 18/16
|
82
|
+
}
|
83
|
+
|
84
|
+
.lead {
|
85
|
+
font: 300 1.6em/1.4em $headlineFont;
|
86
|
+
color: #666;
|
87
|
+
}
|
88
|
+
|
89
|
+
//-- Layout
|
90
|
+
|
91
|
+
header {
|
92
|
+
margin-bottom: 2em;
|
93
|
+
padding: 1.25em 0;
|
94
|
+
background-color: $darkBlue;
|
95
|
+
color: #eee;
|
96
|
+
|
97
|
+
h1 {
|
98
|
+
margin: 0;
|
99
|
+
font-size: 1.25em;
|
100
|
+
color: $yellow;
|
101
|
+
font-weight: 600;
|
102
|
+
text-transform: uppercase;
|
103
|
+
}
|
104
|
+
|
105
|
+
span {
|
106
|
+
color: $yellow;
|
107
|
+
font-weight: 800;
|
108
|
+
}
|
109
|
+
|
110
|
+
em {
|
111
|
+
font-style: normal;
|
112
|
+
font-weight: 300;
|
113
|
+
color: #ddd;
|
114
|
+
text-transform: none;
|
115
|
+
}
|
116
|
+
|
117
|
+
.container {
|
118
|
+
position: relative;
|
119
|
+
}
|
120
|
+
|
121
|
+
.support-link {
|
122
|
+
display: inline-block;
|
123
|
+
position: absolute;
|
124
|
+
right: 0;
|
125
|
+
top: 50%;
|
126
|
+
height: 2em;
|
127
|
+
line-height: 2em;
|
128
|
+
margin-top: -1em;
|
129
|
+
|
130
|
+
a:link, a:visited {
|
131
|
+
color: #879C9E;
|
132
|
+
text-decoration: none;
|
133
|
+
}
|
134
|
+
}
|
135
|
+
}
|
136
|
+
|
137
|
+
footer {
|
138
|
+
margin-top: 2em;
|
139
|
+
|
140
|
+
p {
|
141
|
+
font-size: 0.85em;
|
142
|
+
color: #bbb;
|
143
|
+
}
|
144
|
+
|
145
|
+
a:link, a:visited {
|
146
|
+
color: #bbb;
|
147
|
+
}
|
148
|
+
|
149
|
+
a:hover, a:active {
|
150
|
+
color: $linkHoverColor;
|
151
|
+
}
|
152
|
+
|
153
|
+
.container {
|
154
|
+
border-top: 1px solid #eee;
|
155
|
+
}
|
156
|
+
}
|
157
|
+
|
158
|
+
.container {
|
159
|
+
width: 62.5em;
|
160
|
+
max-width: 90%;
|
161
|
+
margin-right: auto;
|
162
|
+
margin-left: auto;
|
163
|
+
}
|
164
|
+
|
165
|
+
.content {
|
166
|
+
min-height: 200px;
|
167
|
+
}
|
@@ -0,0 +1,64 @@
|
|
1
|
+
// shared/based.scss
|
2
|
+
|
3
|
+
@import "_vars";
|
4
|
+
@import "_mixins";
|
5
|
+
|
6
|
+
body {
|
7
|
+
margin: 0;
|
8
|
+
padding: 0;
|
9
|
+
}
|
10
|
+
|
11
|
+
.container {
|
12
|
+
width: 600px;
|
13
|
+
max-width: 600px;
|
14
|
+
}
|
15
|
+
|
16
|
+
.container-padding {
|
17
|
+
padding-left: $gutter;
|
18
|
+
padding-right: $gutter;
|
19
|
+
}
|
20
|
+
|
21
|
+
.content {
|
22
|
+
background-color: #ffffff;
|
23
|
+
}
|
24
|
+
|
25
|
+
.title {
|
26
|
+
font-weight: bold;
|
27
|
+
font-size: 24px;
|
28
|
+
line-height: 28px;
|
29
|
+
font-family: $fontFamily;
|
30
|
+
}
|
31
|
+
|
32
|
+
.body-text {
|
33
|
+
font-size: 16px;
|
34
|
+
line-height: 20px;
|
35
|
+
font-family: $fontFamily;
|
36
|
+
}
|
37
|
+
|
38
|
+
|
39
|
+
//-- Buttons
|
40
|
+
|
41
|
+
.button {
|
42
|
+
td {
|
43
|
+
@include border-radius(3px);
|
44
|
+
background-color: $buttonBgColor;
|
45
|
+
}
|
46
|
+
|
47
|
+
a {
|
48
|
+
@include border-radius(3px);
|
49
|
+
@include font(bold, 14px, 20px);
|
50
|
+
text-decoration: none;
|
51
|
+
display: inline-block;
|
52
|
+
padding: 12px 18px;
|
53
|
+
border: 1px solid darken($buttonBgColor, 5%);
|
54
|
+
background-color: $buttonBgColor;
|
55
|
+
color: $buttonColor;
|
56
|
+
}
|
57
|
+
|
58
|
+
&.green {
|
59
|
+
td, a {
|
60
|
+
background-color: $greenBtnBgColor;
|
61
|
+
border-color: darken($greenBtnBgColor, 5%);
|
62
|
+
}
|
63
|
+
}
|
64
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
//
|
2
|
+
// Mixins
|
3
|
+
// -------------------
|
4
|
+
// shared properties that we don't want to repeatedly define
|
5
|
+
|
6
|
+
@mixin padding($top: $gutter, $right: $gutter, $bottom: $gutter, $left: $gutter) {
|
7
|
+
padding-top: $top;
|
8
|
+
padding-right: $right;
|
9
|
+
padding-bottom: $bottom;
|
10
|
+
padding-left: $left;
|
11
|
+
}
|
12
|
+
|
13
|
+
@mixin border-radius($radius: 4px){
|
14
|
+
-webkit-border-radius: $radius;
|
15
|
+
-moz-border-radius: $radius;
|
16
|
+
border-radius: $radius;
|
17
|
+
}
|
18
|
+
|
19
|
+
@mixin font($weight: normal, $size: 14px, $line-height: 20px, $family: $fontFamily) {
|
20
|
+
font-weight: $weight;
|
21
|
+
font-size: $size;
|
22
|
+
line-height: $line-height;
|
23
|
+
font-family: $family;
|
24
|
+
}
|
25
|
+
|