-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
51 changed files
with
1,821 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
dist/ | ||
langs/ | ||
node_modules/ | ||
|
||
# Created by https://www.gitignore.io/api/macos,windows,linux | ||
|
||
### macOS ### | ||
*.DS_Store | ||
.AppleDouble | ||
.LSOverride | ||
|
||
# Icon must end with two \r | ||
Icon | ||
|
||
|
||
# Thumbnails | ||
._* | ||
|
||
# Files that might appear in the root of a volume | ||
.DocumentRevisions-V100 | ||
.fseventsd | ||
.Spotlight-V100 | ||
.TemporaryItems | ||
.Trashes | ||
.VolumeIcon.icns | ||
.com.apple.timemachine.donotpresent | ||
|
||
# Directories potentially created on remote AFP share | ||
.AppleDB | ||
.AppleDesktop | ||
Network Trash Folder | ||
Temporary Items | ||
.apdisk | ||
|
||
|
||
### Windows ### | ||
# Windows image file caches | ||
Thumbs.db | ||
ehthumbs.db | ||
|
||
# Folder config file | ||
Desktop.ini | ||
|
||
# Recycle Bin used on file shares | ||
$RECYCLE.BIN/ | ||
|
||
# Windows Installer files | ||
*.cab | ||
*.msi | ||
*.msm | ||
*.msp | ||
|
||
# Windows shortcuts | ||
*.lnk | ||
|
||
|
||
### Linux ### | ||
*~ | ||
|
||
# temporary files which can be created if a process still has a handle open of a deleted file | ||
.fuse_hidden* | ||
|
||
# KDE directory preferences | ||
.directory | ||
|
||
# Linux trash folder which might appear on any partition or disk | ||
.Trash-* | ||
|
||
# .nfs files are created when an open file is removed but is still being accessed | ||
.nfs* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
## What is this? | ||
|
||
The PrestaShop Emails SDK is a toolkit to create custom emails for PrestaShop 1.5, 1.6 and 1.7. | ||
|
||
## Installation | ||
|
||
You first need to install [Node.js](https://nodejs.org). | ||
|
||
Install Gulp: | ||
|
||
`npm install -g gulp` | ||
|
||
Download or clone the repository | ||
|
||
Install all the dependencies: | ||
|
||
``` | ||
cd email-templates-sdk | ||
npm install | ||
``` | ||
Before anything, you need to download required languages: | ||
|
||
`gulp langs:dl` | ||
|
||
## Usage | ||
|
||
During development, you just need to watch files: | ||
|
||
`gulp watch` | ||
|
||
This will detect changes on your files and output a compiled version in `./dist/en/`. | ||
3 languages are available during development but more languages are available when the emails are installed on PrestaShop. More information below. | ||
|
||
## Build | ||
|
||
To install the emails on PrestaShop, you need to build a package: | ||
|
||
`gulp build` | ||
|
||
This will create a zip file in `./dist/` with the name you set in the `./src/config/settings.json`. | ||
|
||
To install the zip file that contains the emails, you need to use the Emails Manager available in the PrestaShop back office (soon). | ||
This is also this file you will need to submit on [PrestaShop Addons](https://addons.prestashop.com) if you want to sell it. | ||
The emails are translated by the module during the installation and the dynamic variables & conditions are processed (see "Dynamic variables" and "Conditions" for more information). | ||
|
||
## MJML: Emails made easy | ||
|
||
Building emails is not easy. We know that and Mailjet too. This is why they created a framework to develop emails and make sure they will work fine for all email clients. | ||
|
||
We chose to use this framework to help you develop your emails for PrestaShop. The better part is that Mailjet improves MJML everyday and you can enjoy it directly. | ||
|
||
All the PrestaShop's emails have been converted in a MJML format so you can create your own emails based on it. | ||
|
||
You can find a complete documentation on the [official website](https://mjml.io/documentation/). | ||
|
||
## Translations | ||
|
||
Emails are automatically translated when they are installed. This is why you can find variables like this in your templates: | ||
|
||
`${{ lang.my_variable }}$` | ||
|
||
Make sure to use these variables and not hard coded text. | ||
|
||
## Dynamic variables | ||
|
||
In order to allow the merchants to customize they emails, you can create dynamic variables. In your email, you just need to include a variable where you want: | ||
|
||
`{{$my_var}}` | ||
|
||
For every variable, you need to declare it in `./src/config/settings.json` | ||
|
||
``` | ||
{ | ||
"product_key": "", | ||
"name": "preston", | ||
"version": "1.0", | ||
"inputs": [ | ||
{ | ||
"type": "text", // Two types are supported: text or color | ||
"name": "my_var", | ||
"default": "", | ||
"required": false, | ||
"label": { | ||
"en": "English label", | ||
"fr": "French label", | ||
... | ||
}, | ||
"desc": { | ||
"en": "English description", | ||
"fr": "French description", | ||
... | ||
} | ||
} | ||
] | ||
} | ||
``` | ||
|
||
To help you during your development, you can use the `./src/config/fake.json` to declare fake data. This will replace the variables in the compiled versions. | ||
|
||
You can replace : | ||
|
||
* Your dynamic variables. | ||
* Default variables like {shop_name}. The default fake.json already comes with almost all the default variables. | ||
* Whatever you want! | ||
|
||
Note: A few variables for PrestaShop 1.5 are also available in the `fake.json`. When you want to test for this version, just temporarly replace the variables in your templates. | ||
|
||
## Conditions | ||
|
||
You will sometimes need to add some conditions. Social links are a good example as the merchants are not using all of them. | ||
|
||
Your conditions must be really simple and only check if a variable is here. | ||
|
||
```html | ||
<mj-raw>{{if $my_var}}</mj-raw> | ||
// Your code | ||
<mj-raw>{/if}</mj-raw> | ||
``` | ||
You can find real examples in the default template's footer. | ||
|
||
## Partials | ||
|
||
If you want to include the same code in multiple files, you can use partials. Create a new file in the `./src/partials/` folder and then, include it where you want: | ||
|
||
`<mj-include path="./src/partials/your_file.mjml" />` | ||
|
||
## Global CSS | ||
|
||
MJML lets you custom every components with attributes and we really recommend you to do it like this but sometimes, you will need to add some global CSS. Media queries are a good example. | ||
|
||
Another good example is the `order_conf.html` email. On PrestaShop 1.5, the products list is hard coded and you can't change the HTML so you will need to custom the style. You will have to do it in the global CSS. Take a look at the default template for an example. | ||
|
||
Starting 1.6, tpl files are used in the `order_conf.html` and we provide a better version in this SDK. You can edit the files as much as you want, they will replace the default files. | ||
|
||
## Tests & Compatibility | ||
|
||
We recommend you to test your emails with Litmus. On PrestaShop Addons, we will use it to make sure that your emails are valid on the most common email clients, both desktop and mobile. You can also create a few accounts (GMail, Yahoo...) to test it yourself. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
var gulp = require('gulp'); | ||
var mjml = require('gulp-mjml') | ||
var mjmlEngine = require('mjml') | ||
var i18n = require('gulp-html-i18n') | ||
var download = require("gulp-download-stream"); | ||
var buffer = require('vinyl-buffer') | ||
var replace_task = require('gulp-replace-task'); | ||
var ext_replace = require('gulp-ext-replace'); | ||
var zip = require('gulp-zip'); | ||
var replace = require('gulp-replace'); | ||
var rename = require("gulp-rename"); | ||
var clean = require('gulp-clean'); | ||
var fs = require('fs'); | ||
|
||
var fake = require('./src/config/fake.json'); | ||
var settings = require('./src/config/settings.json'); | ||
|
||
// Compile files [dev mode] | ||
gulp.task('build:dev', function () { | ||
var css = fs.readFileSync(__dirname+'/src/css/global.css', 'utf8'); | ||
|
||
return gulp.src(['src/*.mjml']) | ||
|
||
// Compile MJML to HTML | ||
.pipe(mjml(mjmlEngine)) | ||
|
||
// Delete conditions | ||
.pipe(replace('{{/if}}', '')) | ||
.pipe(replace(/{{if \$[a-z_]+}}/ig, '')) | ||
|
||
// We need to decode some curly brackets because of MJML | ||
.pipe(replace('%7B%7B', '{{')) | ||
.pipe(replace('%7D%7D', '}}')) | ||
|
||
// CSS injection in the header | ||
.pipe(replace('</head>', '<style>'+css+'</style></head>')) | ||
|
||
// Translate | ||
.pipe(i18n({ | ||
langDir: './langs', | ||
trace: true, | ||
createLangDirs: true | ||
})) | ||
|
||
// Replace variables with fake data | ||
.pipe(replace_task({ | ||
patterns: [{json: fake}], | ||
usePrefix: false | ||
})) | ||
|
||
.pipe(gulp.dest('./dist/html/')) | ||
}); | ||
|
||
// Compile files with MJML | ||
gulp.task('build:mjml', function () { | ||
var css = fs.readFileSync(__dirname+'/src/css/global.css', 'utf8'); | ||
return gulp.src(['src/*.mjml']) | ||
|
||
// Compile MJML to HTML | ||
.pipe(mjml(mjmlEngine)) | ||
|
||
// We need to decode some curly brackets because of MJML | ||
.pipe(replace('%7B%7B', '{{')) | ||
.pipe(replace('%7D%7D', '}}')) | ||
|
||
// CSS injection in the header | ||
.pipe(replace('</head>', '<style>'+css+'</style></head>')) | ||
|
||
// Rename files | ||
.pipe(ext_replace('.tpl')) | ||
|
||
.pipe(gulp.dest('./dist/'+settings.name)) | ||
}); | ||
|
||
// Copy images in dist folder | ||
gulp.task('build:copy:img', function() { | ||
return gulp.src('src/img/*.{jpg,jpeg,png,gif}') | ||
.pipe(gulp.dest('./dist/'+settings.name+'/img/')); | ||
}); | ||
|
||
// Copy tpls in dist folder | ||
gulp.task('build:copy:tpl', function () { | ||
return gulp.src('src/*.tpl') | ||
.pipe(gulp.dest('./dist/'+settings.name+'/tpl/')); | ||
}); | ||
|
||
// Copy preview img in dist folder | ||
gulp.task('build:copy:preview', function() { | ||
return gulp.src('src/preview.jpg') | ||
.pipe(gulp.dest('./dist/'+settings.name+'/')); | ||
}); | ||
|
||
// Copy settings in dist folder | ||
gulp.task('build:copy:settings', function() { | ||
return gulp.src('src/config/settings.json') | ||
.pipe(gulp.dest('./dist/'+settings.name+'/')); | ||
}); | ||
|
||
// Compress folder | ||
gulp.task('build:compress', ['build:copy:settings', 'build:mjml', 'build:copy:tpl', 'build:copy:img', 'build:copy:preview'], function() { | ||
return gulp.src('./dist/'+settings.name+'/**/*') | ||
.pipe(zip(settings.name+'.zip')) | ||
.pipe(gulp.dest('./dist/')); | ||
}); | ||
|
||
// Copy images in dist folder | ||
gulp.task('build', ['build:copy:settings', 'build:mjml', 'build:copy:img', 'build:copy:preview', 'build:copy:tpl', 'build:compress']); | ||
|
||
// Watch changes | ||
gulp.task('watch', function () { | ||
gulp.watch('src/**/*.mjml', ['build:dev']); | ||
gulp.watch('src/css/global.css', ['build:dev']); | ||
}); | ||
|
||
// Download translations | ||
gulp.task('langs:dl', ['langs:clean'], function () { | ||
['en', 'fr', 'es'].forEach(function(lang) { | ||
download('http://scritik.addons.prestashop.net/request/1/contributor/dependencies/6c7a3d34fa01934e71f53aae16f2698b/'+lang) | ||
.pipe(buffer()) | ||
.pipe(rename("lang.json")) | ||
.pipe(gulp.dest('langs/'+lang+'/')); | ||
}) | ||
}); | ||
|
||
// Remove previously downloaded langs | ||
gulp.task('langs:clean', function () { | ||
return gulp.src('langs/', {read: false}) | ||
.pipe(clean()); | ||
}); | ||
|
||
// Run all tasks if no args | ||
gulp.task('default', ['watch']); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"name": "ps-mails-sdk", | ||
"version": "1.0.0", | ||
"description": "PrestaShop emails SDK", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
}, | ||
"author": "PrestaShop", | ||
"license": "ISC", | ||
"devDependencies": { | ||
"gulp": "^3.9.1", | ||
"gulp-clean": "^0.3.2", | ||
"gulp-download-stream": "0.0.13", | ||
"gulp-ext-replace": "^0.3.0", | ||
"gulp-html-i18n": "^0.6.1", | ||
"gulp-mjml": "^1.0.1", | ||
"gulp-rename": "^1.2.2", | ||
"gulp-replace": "^0.5.4", | ||
"gulp-replace-task": "^0.11.0", | ||
"gulp-zip": "^3.2.0", | ||
"vinyl-buffer": "^1.0.0" | ||
} | ||
} |
Oops, something went wrong.