├── .gitignore
├── src
├── templates
│ ├── css
│ │ ├── media-queries.css
│ │ └── main.css
│ ├── partials
│ │ ├── preheader.html
│ │ └── footer.html
│ └── basic-template.html
└── panel
│ └── index.html
├── config-sample.json
├── package.json
├── panel
├── js
│ └── main.js
└── css
│ └── panel.css
├── gulpfile.js
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | kontist-basic-template.html
4 | config.json
5 | package-lock.json
6 |
--------------------------------------------------------------------------------
/src/templates/css/media-queries.css:
--------------------------------------------------------------------------------
1 | @media screen and (min-width: 600px) {
2 | .preheaderContent {
3 | padding: 40px 0 30px !important;
4 | }
5 | .bodyContent {
6 | padding: 40px 40px 0!important;
7 | }
8 | .button a{
9 | margin-top: 40px;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/config-sample.json:
--------------------------------------------------------------------------------
1 | {
2 | "testing": {
3 | "from": "from-email",
4 | "to": "recepit-email",
5 | "subject": "your-subject-line"
6 | },
7 |
8 | "auth": {
9 | "mailgun": {
10 | "apikey": "your-api-key",
11 | "sandbox": "your-sandbox-url"
12 | },
13 | "mandrill": {
14 | "apikey": "your-api-key"
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/templates/partials/preheader.html:
--------------------------------------------------------------------------------
1 |
17 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "email-framework",
3 | "version": "1.0.0",
4 | "description": "A simple framework for working with responsive email",
5 | "main": "index.html",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/joshuasoehn/email-framework.git"
12 | },
13 | "author": "",
14 | "license": "ISC",
15 | "bugs": {
16 | "url": "https://github.com/joshuasoehn/email-framework/issues"
17 | },
18 | "homepage": "https://github.com/joshuasoehn/email-framework#readme",
19 | "devDependencies": {
20 | "browser-sync": "^2.17.5",
21 | "glob": "^7.1.1",
22 | "gulp": "^4.0.2",
23 | "gulp-file-include": "^1.0.0",
24 | "gulp-filenames": "^4.0.1",
25 | "gulp-inline-css": "^3.1.0",
26 | "gulp-mailgun": "0.0.7",
27 | "gulp-template": "^4.0.0",
28 | "gulp-util": "^3.0.7"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/templates/partials/footer.html:
--------------------------------------------------------------------------------
1 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | @@include('./partials/preheader.html')
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | Heading 1
34 | Getting started: Customize your template by clicking on the style editor tabs up above. Set your fonts, colors, and styles. After setting your styling is all done you can click here in this area, delete the text, and start adding your own awesome content!
35 |
36 | After you enter your content, highlight the text you want to style and select the options you set in the style editor in the "styles" drop down box. Want to get rid of styling on a bit of text, but having trouble doing it? Just use the "clear styles" button to strip the text of any formatting and reset your style.
37 | |
38 |
39 |
40 | |
41 |
42 |
43 |
44 | |
45 |
52 | |
53 |
54 |
55 | @@include('./partials/footer.html')
56 |
57 |
58 |
59 |
60 |
61 | |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Gulp Email Framework
2 |
3 | A simple, gulp powered framework to develop and test responsive emails. Inspired by [Gulp Email Creator](https://github.com/darylldoyle/Gulp-Email-Creator) and the [Grunt Email Workflow](https://github.com/leemunroe/grunt-email-workflow).
4 |
5 | 
6 |
7 |
8 | ## Installation
9 |
10 | Clone this repository to a local folder and run:
11 | ```
12 | npm install
13 | ```
14 |
15 | ## Features
16 |
17 | ### A basic starter template
18 | This framework comes with a ready to use sample start template, which can be modified how you like it. All the used example assets are ©Mailchimp.
19 |
20 | ### Automatic CSS Inline and build system
21 | The build systems inlines all the css autmaticly, but keeps your media queries in the head tag, so the build email is ready to be used in any service.
22 |
23 | ### No more reloading thanks to browser sync
24 | Browser sync is keeping all the adjustments you make to the email templates in sync and previews changes live, without manually reloading.
25 |
26 | ### Smart partials
27 | We are using gulp-file-include for includes, giving you the option to pass down props to partials like so
28 | ```
29 | @@include('./var.html', {
30 | "name": "haoxin",
31 | "age": 12345,
32 | "socials": {
33 | "fb": "facebook.com/include",
34 | "tw": "twitter.com/include"
35 | })
36 | ```
37 |
38 | ### Sending test emails via Mailgun and Mandrill
39 | Use Mailgun to send preview emails to yourself using `gulp send` (please adjust the setting in the gulp file to the template you want to send). Or if you have an Mandrill you can send the email you are previewing right from the UI.
40 |
41 | ### A simple UI for designing your emails
42 | Preview and manage all your templates right from the UI and preview your email at two devices sizes at the same time, browser sync will keep all the iFrames in sync for you.
43 |
44 | ## How to use
45 | Rename the `config-sample.json` file to `config.json`. Add you api keys for mailgun and mandrill, if you want to use either of the service for sending test emails to yourself. Setting up an mailgun account for that is free, but it doesn't support sending emails from the UI.
46 |
47 | ```
48 | {
49 | "testing": {
50 | "from": "from-email",
51 | "to": "recepit-email",
52 | "subject": "your-subject-line"
53 | },
54 |
55 | "auth": {
56 | "mailgun": {
57 | "apikey": "your-api-key",
58 | "sandbox": "your-sandbox-url"
59 | },
60 | "mandrill": {
61 | "apikey": "your-api-key"
62 | }
63 | }
64 | }
65 |
66 | ```
67 |
68 | Run the framework by using
69 | ```
70 | gulp
71 | ```
72 | Now edit the template in
73 | ```
74 | src/templates/basic-template.html
75 | ```
76 | or create your own from scratch. As long as the gulp task is running it will automaticly build the template on every save and reload the browser. If you create a new template make sure to include it in the panel sidebar.
77 | ```
78 |
84 | ```
85 | in `panel/index.html`.
86 |
87 | Pull request and feedback welcome, as this is a very first version.
88 | Thanks a lot [Filip](https://github.com/peritus) for helping my with lots of the JS part.
89 |
--------------------------------------------------------------------------------
/src/templates/css/main.css:
--------------------------------------------------------------------------------
1 | * {
2 | margin: 0;
3 | padding: 0;
4 | }
5 |
6 | body {
7 | font-family: -apple-system, BlinkMacSystemFont, "Roboto", "Droid Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
8 | background-color: #f6f6f6;
9 | -webkit-text-size-adjust: none;
10 | }
11 |
12 | .body-wrap {
13 | background-color: #f6f6f6;
14 | margin: 0;
15 | width: 100%;
16 | }
17 |
18 | table,
19 | td,
20 | tr {
21 | border-spacing: 0;
22 | padding: 0;
23 | }
24 |
25 | table {
26 | width: 100%;
27 | }
28 |
29 | img {
30 | display: block;
31 | border: none;
32 | height: auto;
33 | outline: none;
34 | max-width: 100%;
35 | width: 100%;
36 | max-width: 600px;
37 | }
38 |
39 | .wrapper {
40 | margin: 0 auto;
41 | padding: 15px;
42 | max-width: 600px !important;
43 | width: 100%;
44 | }
45 |
46 | .templateContainer {
47 | background: #fff;
48 | border-radius: 4px;
49 | overflow: hidden;
50 | border: 1px solid #eee;
51 | }
52 |
53 | h1,.h1{
54 | color: #111;
55 | display: block;
56 | font-size: 34px;
57 | font-weight: bold;
58 | line-height: 100%;
59 | margin-bottom: 20px;
60 | text-align: left;
61 | }
62 |
63 | h2,.h2{
64 | display: block;
65 | color: #111;
66 | font-size: 30px;
67 | font-weight: bold;
68 | line-height: 100%;
69 | margin-bottom: 10px;
70 | text-align: left;
71 | }
72 |
73 | h3,.h3{
74 | font-size: 26px;
75 | display: block;
76 | color: #111;
77 | font-weight: bold;
78 | line-height: 100%;
79 | margin-bottom: 10px;
80 | text-align: left;
81 | }
82 |
83 | h4,.h4{
84 | color: #111111;
85 | display: block;
86 | font-size: 22px;
87 | font-weight: bold;
88 | line-height: 100%;
89 | margin-bottom: 10px;
90 | text-align: left;
91 | }
92 |
93 | p {
94 | display: block;
95 | margin: 0;
96 | }
97 |
98 | .button a {
99 | display: inline-block;
100 | text-decoration: none;
101 | font-size: 14px;
102 | background: #348eda;
103 | color: #fff;
104 | padding: 15px 40px;
105 | border-radius: 4px;
106 | margin-top: 20px;
107 | font-weight: 600;
108 | }
109 |
110 | .preheaderContent {
111 | padding: 30px 0px;
112 | }
113 |
114 | .preheaderClaim {
115 | text-align: right;
116 | color: #666;
117 | font-size: 14px;
118 | }
119 |
120 | .headerContent img {
121 | width: 100%;
122 | display: block;
123 | }
124 |
125 | .preheaderContent .logo {
126 | height: auto;
127 | width: 60px;
128 | }
129 |
130 | .bodyContent {
131 | padding: 20px 20px 0;
132 | color: #333333;
133 | font-size: 16px;
134 | line-height: 150%;
135 | text-align: left;
136 | }
137 |
138 |
139 | .bodyContent a:link,
140 | .bodyContent a:visited {
141 | color: #348eda;
142 | font-weight: normal;
143 | text-decoration: underline;
144 | }
145 |
146 | .bodyContent img {
147 | display: block;
148 | width: 100%;
149 | margin: 20px 0;
150 | }
151 |
152 | .templateFullWidthImage img {
153 | margin-top: 40px;
154 | display: block;
155 | width: 100%;
156 | }
157 |
158 | .templateFooter{
159 | margin-top: 20px;
160 | }
161 |
162 | .footerContent {
163 | color: #707070;
164 | font-size: 12px;
165 | line-height: 125%;
166 | }
167 |
168 | .footerContent img {
169 | display: inline;
170 | }
171 |
172 | .social {
173 | border-top: 1px solid #eee;
174 | border-bottom: 1px solid #eee;
175 | font-size: 14px;
176 | text-align: center;
177 | padding: 25px 0;
178 | }
179 |
180 | .social a {
181 | color: #348eda;
182 | text-decoration: none;
183 | line-height: 1.5
184 | font-size: 14px;
185 | }
186 |
187 | .templateAddress {
188 | color: #999;
189 | font-size: 12px;
190 | line-height: 125%;
191 | text-align: center;
192 | padding: 20px;
193 | }
194 |
195 | .templateAddress a {
196 | color: #999;
197 | font-size: 12px;
198 | text-decoration: underline;
199 | }
200 |
201 | .utility {
202 | color: #999;
203 | font-size: 12px;
204 | text-align: center;
205 | padding: 20px 0;
206 | }
207 |
208 | .utility a {
209 | color: #999;
210 | font-size: 12px;
211 | text-decoration: none;
212 | }
213 |
--------------------------------------------------------------------------------
|