├── tutorials ├── .gitignore ├── digest │ ├── screenshots │ │ ├── hero.png │ │ ├── mail.png │ │ ├── sales.png │ │ ├── content.png │ │ ├── contents.png │ │ ├── navbar.png │ │ └── social.png │ ├── variables.json │ ├── index.mjml │ └── README.md ├── receipt │ ├── screenshots │ │ ├── hero.png │ │ ├── item.png │ │ ├── mail.png │ │ ├── footer.png │ │ ├── header.png │ │ ├── items.png │ │ ├── order.png │ │ ├── preview.png │ │ ├── total.png │ │ └── suggestions.png │ ├── variables.json │ └── index.mjml ├── welcome │ ├── screenshots │ │ ├── copy.png │ │ ├── mail.png │ │ ├── footer.png │ │ ├── header.png │ │ ├── social.png │ │ ├── hero_male.png │ │ ├── categories.png │ │ └── hero_female.png │ ├── variables.json │ ├── index.mjml │ └── README.md ├── abandoned_cart │ ├── screenshots │ │ ├── cart.png │ │ ├── hero.png │ │ ├── mail.png │ │ ├── footer.png │ │ ├── navbar.png │ │ ├── social.png │ │ ├── hero_cart.png │ │ └── youwilllovethat.png │ ├── variables.json │ ├── index.mjml │ └── README.md ├── email_sender │ └── v0.1 │ │ ├── config │ │ └── index.js │ │ ├── send-email.js │ │ ├── templates │ │ ├── welcome │ │ │ ├── variables.json │ │ │ └── index.mjml │ │ ├── abandoned_cart │ │ │ ├── variables.json │ │ │ └── index.mjml │ │ └── receipt │ │ │ ├── variables.json │ │ │ └── index.mjml │ │ ├── render-mjml.js │ │ ├── read-files.js │ │ ├── package.json │ │ ├── services │ │ ├── mailjet-sender.js │ │ └── mjml-api.js │ │ ├── index.js │ │ ├── test │ │ ├── mailjet-sender.test.js │ │ └── mjml-api.test.js │ │ └── README.md ├── LICENSE.md └── README.md ├── .gitignore ├── samples ├── ecommerce │ ├── img │ │ ├── photo1.jpg │ │ ├── photo2.jpg │ │ └── photo3.jpg │ ├── media │ │ ├── ecommerce1.png │ │ ├── ecommerce2.png │ │ ├── ecommerce3.png │ │ ├── ecommerce4.png │ │ └── ecommerce5.png │ ├── README.md │ └── test.php ├── white_label │ ├── img │ │ ├── vs3n.png │ │ └── mailjet.jpg │ ├── media │ │ ├── white_label1.png │ │ ├── white_label2.png │ │ └── white_label3.png │ ├── README.md │ └── test.php ├── composer.json ├── zigzag_loop │ ├── media │ │ ├── zigzag.png │ │ └── zigzag_design.png │ ├── template.html │ ├── test.php │ ├── README.md │ └── test_design.php ├── all_in_one_transac │ ├── media │ │ ├── all1.png │ │ ├── all2.png │ │ ├── all3.png │ │ └── all4.png │ ├── img │ │ ├── writer-1.png │ │ ├── writer-2.png │ │ ├── writer-3.png │ │ ├── writer-4.png │ │ ├── contributor-1.png │ │ ├── contributor-2.png │ │ ├── contributor-3.png │ │ └── contributor-4.png │ ├── README.md │ └── test.php ├── products_list │ ├── media │ │ └── designed.png │ ├── template.html │ ├── README.md │ └── test.php ├── rss_to_email │ ├── media │ │ └── rss2email.png │ ├── template.html │ ├── README.md │ └── test.php ├── ecommerce_receipt │ ├── media │ │ └── receipt.png │ ├── README.md │ └── test.php ├── question_answer │ ├── media │ │ ├── question1.png │ │ ├── question2.png │ │ ├── question3.png │ │ └── question4.png │ ├── template.html │ ├── test.php │ └── README.md ├── electronic_ticket │ ├── media │ │ ├── MailjetAir1.png │ │ └── MailjetAir2.png │ ├── README.md │ └── test.php ├── conf.php └── README.md ├── LICENCE └── README.md /tutorials/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .credentials 3 | npm-debug.log 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/* 2 | composer.lock 3 | samples/vendor/* 4 | samples/composer.lock 5 | -------------------------------------------------------------------------------- /samples/ecommerce/img/photo1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/ecommerce/img/photo1.jpg -------------------------------------------------------------------------------- /samples/ecommerce/img/photo2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/ecommerce/img/photo2.jpg -------------------------------------------------------------------------------- /samples/ecommerce/img/photo3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/ecommerce/img/photo3.jpg -------------------------------------------------------------------------------- /samples/white_label/img/vs3n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/white_label/img/vs3n.png -------------------------------------------------------------------------------- /samples/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "mailjet/mailjet-apiv3-php": "1.1.0", 4 | "dg/rss-php": "^1.2" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /samples/white_label/img/mailjet.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/white_label/img/mailjet.jpg -------------------------------------------------------------------------------- /samples/zigzag_loop/media/zigzag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/zigzag_loop/media/zigzag.png -------------------------------------------------------------------------------- /samples/ecommerce/media/ecommerce1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/ecommerce/media/ecommerce1.png -------------------------------------------------------------------------------- /samples/ecommerce/media/ecommerce2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/ecommerce/media/ecommerce2.png -------------------------------------------------------------------------------- /samples/ecommerce/media/ecommerce3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/ecommerce/media/ecommerce3.png -------------------------------------------------------------------------------- /samples/ecommerce/media/ecommerce4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/ecommerce/media/ecommerce4.png -------------------------------------------------------------------------------- /samples/ecommerce/media/ecommerce5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/ecommerce/media/ecommerce5.png -------------------------------------------------------------------------------- /tutorials/digest/screenshots/hero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/digest/screenshots/hero.png -------------------------------------------------------------------------------- /tutorials/digest/screenshots/mail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/digest/screenshots/mail.png -------------------------------------------------------------------------------- /tutorials/digest/screenshots/sales.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/digest/screenshots/sales.png -------------------------------------------------------------------------------- /tutorials/receipt/screenshots/hero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/receipt/screenshots/hero.png -------------------------------------------------------------------------------- /tutorials/receipt/screenshots/item.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/receipt/screenshots/item.png -------------------------------------------------------------------------------- /tutorials/receipt/screenshots/mail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/receipt/screenshots/mail.png -------------------------------------------------------------------------------- /tutorials/welcome/screenshots/copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/welcome/screenshots/copy.png -------------------------------------------------------------------------------- /tutorials/welcome/screenshots/mail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/welcome/screenshots/mail.png -------------------------------------------------------------------------------- /samples/all_in_one_transac/media/all1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/all_in_one_transac/media/all1.png -------------------------------------------------------------------------------- /samples/all_in_one_transac/media/all2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/all_in_one_transac/media/all2.png -------------------------------------------------------------------------------- /samples/all_in_one_transac/media/all3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/all_in_one_transac/media/all3.png -------------------------------------------------------------------------------- /samples/all_in_one_transac/media/all4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/all_in_one_transac/media/all4.png -------------------------------------------------------------------------------- /samples/products_list/media/designed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/products_list/media/designed.png -------------------------------------------------------------------------------- /samples/rss_to_email/media/rss2email.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/rss_to_email/media/rss2email.png -------------------------------------------------------------------------------- /tutorials/digest/screenshots/content.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/digest/screenshots/content.png -------------------------------------------------------------------------------- /tutorials/digest/screenshots/contents.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/digest/screenshots/contents.png -------------------------------------------------------------------------------- /tutorials/digest/screenshots/navbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/digest/screenshots/navbar.png -------------------------------------------------------------------------------- /tutorials/digest/screenshots/social.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/digest/screenshots/social.png -------------------------------------------------------------------------------- /tutorials/receipt/screenshots/footer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/receipt/screenshots/footer.png -------------------------------------------------------------------------------- /tutorials/receipt/screenshots/header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/receipt/screenshots/header.png -------------------------------------------------------------------------------- /tutorials/receipt/screenshots/items.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/receipt/screenshots/items.png -------------------------------------------------------------------------------- /tutorials/receipt/screenshots/order.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/receipt/screenshots/order.png -------------------------------------------------------------------------------- /tutorials/receipt/screenshots/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/receipt/screenshots/preview.png -------------------------------------------------------------------------------- /tutorials/receipt/screenshots/total.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/receipt/screenshots/total.png -------------------------------------------------------------------------------- /tutorials/welcome/screenshots/footer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/welcome/screenshots/footer.png -------------------------------------------------------------------------------- /tutorials/welcome/screenshots/header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/welcome/screenshots/header.png -------------------------------------------------------------------------------- /tutorials/welcome/screenshots/social.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/welcome/screenshots/social.png -------------------------------------------------------------------------------- /samples/all_in_one_transac/img/writer-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/all_in_one_transac/img/writer-1.png -------------------------------------------------------------------------------- /samples/all_in_one_transac/img/writer-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/all_in_one_transac/img/writer-2.png -------------------------------------------------------------------------------- /samples/all_in_one_transac/img/writer-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/all_in_one_transac/img/writer-3.png -------------------------------------------------------------------------------- /samples/all_in_one_transac/img/writer-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/all_in_one_transac/img/writer-4.png -------------------------------------------------------------------------------- /samples/ecommerce_receipt/media/receipt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/ecommerce_receipt/media/receipt.png -------------------------------------------------------------------------------- /samples/question_answer/media/question1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/question_answer/media/question1.png -------------------------------------------------------------------------------- /samples/question_answer/media/question2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/question_answer/media/question2.png -------------------------------------------------------------------------------- /samples/question_answer/media/question3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/question_answer/media/question3.png -------------------------------------------------------------------------------- /samples/question_answer/media/question4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/question_answer/media/question4.png -------------------------------------------------------------------------------- /samples/white_label/media/white_label1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/white_label/media/white_label1.png -------------------------------------------------------------------------------- /samples/white_label/media/white_label2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/white_label/media/white_label2.png -------------------------------------------------------------------------------- /samples/white_label/media/white_label3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/white_label/media/white_label3.png -------------------------------------------------------------------------------- /samples/zigzag_loop/media/zigzag_design.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/zigzag_loop/media/zigzag_design.png -------------------------------------------------------------------------------- /tutorials/welcome/screenshots/hero_male.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/welcome/screenshots/hero_male.png -------------------------------------------------------------------------------- /tutorials/abandoned_cart/screenshots/cart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/abandoned_cart/screenshots/cart.png -------------------------------------------------------------------------------- /tutorials/abandoned_cart/screenshots/hero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/abandoned_cart/screenshots/hero.png -------------------------------------------------------------------------------- /tutorials/abandoned_cart/screenshots/mail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/abandoned_cart/screenshots/mail.png -------------------------------------------------------------------------------- /tutorials/receipt/screenshots/suggestions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/receipt/screenshots/suggestions.png -------------------------------------------------------------------------------- /tutorials/welcome/screenshots/categories.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/welcome/screenshots/categories.png -------------------------------------------------------------------------------- /tutorials/welcome/screenshots/hero_female.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/welcome/screenshots/hero_female.png -------------------------------------------------------------------------------- /samples/all_in_one_transac/img/contributor-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/all_in_one_transac/img/contributor-1.png -------------------------------------------------------------------------------- /samples/all_in_one_transac/img/contributor-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/all_in_one_transac/img/contributor-2.png -------------------------------------------------------------------------------- /samples/all_in_one_transac/img/contributor-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/all_in_one_transac/img/contributor-3.png -------------------------------------------------------------------------------- /samples/all_in_one_transac/img/contributor-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/all_in_one_transac/img/contributor-4.png -------------------------------------------------------------------------------- /samples/electronic_ticket/media/MailjetAir1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/electronic_ticket/media/MailjetAir1.png -------------------------------------------------------------------------------- /samples/electronic_ticket/media/MailjetAir2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/samples/electronic_ticket/media/MailjetAir2.png -------------------------------------------------------------------------------- /tutorials/abandoned_cart/screenshots/footer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/abandoned_cart/screenshots/footer.png -------------------------------------------------------------------------------- /tutorials/abandoned_cart/screenshots/navbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/abandoned_cart/screenshots/navbar.png -------------------------------------------------------------------------------- /tutorials/abandoned_cart/screenshots/social.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/abandoned_cart/screenshots/social.png -------------------------------------------------------------------------------- /tutorials/abandoned_cart/screenshots/hero_cart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/abandoned_cart/screenshots/hero_cart.png -------------------------------------------------------------------------------- /tutorials/abandoned_cart/screenshots/youwilllovethat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjet-apiv3-templating-samples/HEAD/tutorials/abandoned_cart/screenshots/youwilllovethat.png -------------------------------------------------------------------------------- /samples/rss_to_email/template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /samples/products_list/template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | {% for line in var:products %} 7 | 12 | {% endfor %} 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /samples/conf.php: -------------------------------------------------------------------------------- 1 | 19 | -------------------------------------------------------------------------------- /tutorials/email_sender/v0.1/config/index.js: -------------------------------------------------------------------------------- 1 | // general properties 2 | module.exports = { 3 | FromEmail: 'gbetton@mailjet.com', // should be a validated address from your account 4 | FromName: 'grebett', 5 | Subject: '🐸 Templating language test 🐸 ', 6 | 'Mj-Templateerrorreporting': 'gbetton@mailjet.com', // specify this address to access debug reports 7 | 'MJ-TemplateLanguage': true, // mandatory 8 | Recipients: [{ 9 | Email: "gregory.betton@gmail.com", 10 | Name: "grebett" 11 | }] 12 | }; 13 | -------------------------------------------------------------------------------- /samples/rss_to_email/README.md: -------------------------------------------------------------------------------- 1 | #RSS to EMAIL 2 | 3 | This example shows how with the loops you can repeat pieces of your template. 4 | This example download a RSS feed and push the articles information to the Mailjet Transational template. 5 | 6 | ## Vars 7 | 8 | We download a RSS feed from an external source. 9 | 10 | ## Template source 11 | 12 | ```html 13 | 18 | ``` 19 | 20 | ## Result 21 | 22 | ![Example 1](media/rss2email.png) 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /tutorials/email_sender/v0.1/send-email.js: -------------------------------------------------------------------------------- 1 | module.exports = function (emailData) { 2 | const MailjetSender = require('./services/mailjet-sender'); 3 | const sender = new MailjetSender(process.env.MAILJET_API_KEY, process.env.MAILJET_API_SECRET); 4 | 5 | return new Promise((resolve, reject) => { 6 | sender.send(emailData).then(response => { 7 | resolve({ 8 | message : 'Congratulations, you\'ve just sent an email to the following recipients:', 9 | data: response.Sent 10 | }); 11 | }, senderError => { 12 | // check the Send API error payload for more details 13 | reject(senderError); 14 | }); 15 | }); 16 | }; 17 | -------------------------------------------------------------------------------- /tutorials/welcome/variables.json: -------------------------------------------------------------------------------- 1 | { 2 | "user": { 3 | "name": "Matthew", 4 | "gender": "male" 5 | }, 6 | "categories": { 7 | "top_left": { 8 | "title": "Shoes", 9 | "link": "/shoes", 10 | "image_URL": "http://bit.ly/mj-tpl-tuto-shoes" 11 | }, 12 | "top_right": { 13 | "title": "Jumper", 14 | "link": "/t-shirt", 15 | "image_URL": "http://bit.ly/mj-tpl-lang-tuto-tshirt" 16 | }, 17 | "bottom_left": { 18 | "title": "Shirt", 19 | "link": "/shirt", 20 | "image_URL": "http://bit.ly/mj-tpl-lang-tuto-shirt" 21 | }, 22 | "bottom_right": { 23 | "title": "Accessories", 24 | "link": "/accessories", 25 | "image_URL": "http://bit.ly/mj-tpl-lang-tuto-accessories" 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tutorials/email_sender/v0.1/templates/welcome/variables.json: -------------------------------------------------------------------------------- 1 | { 2 | "user": { 3 | "name": "Matthew", 4 | "gender": "male" 5 | }, 6 | "categories": { 7 | "top_left": { 8 | "title": "Shoes", 9 | "link": "/shoes", 10 | "image_URL": "http://bit.ly/mj-tpl-tuto-shoes" 11 | }, 12 | "top_right": { 13 | "title": "Jumper", 14 | "link": "/t-shirt", 15 | "image_URL": "http://bit.ly/mj-tpl-lang-tuto-tshirt" 16 | }, 17 | "bottom_left": { 18 | "title": "Shirt", 19 | "link": "/shirt", 20 | "image_URL": "http://bit.ly/mj-tpl-lang-tuto-shirt" 21 | }, 22 | "bottom_right": { 23 | "title": "Accessories", 24 | "link": "/accessories", 25 | "image_URL": "http://bit.ly/mj-tpl-lang-tuto-accessories" 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /samples/zigzag_loop/template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | {% for product in var:products %} 7 | {% if (product.id mod 2) = 1 %} 8 | 9 | {% else %} 10 | 11 | {% endif %} 12 | {% endfor %} 13 |
{{product.name}}
{{product.price}}
{{product.name}}
{{product.price}}
14 | 15 |
16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /tutorials/email_sender/v0.1/render-mjml.js: -------------------------------------------------------------------------------- 1 | const chalk = require('chalk'); 2 | 3 | module.exports = function (mjml) { 4 | const MjmlClient = require('./services/mjml-api'); 5 | const client = new MjmlClient(process.env.MJML_APPLICATION_ID, process.env.MJML_SECRET_KEY); 6 | 7 | return new Promise((resolve, reject) => { 8 | client.render(mjml).then(data => { 9 | if (data.errors.length) { 10 | // some errors are warnings and shoudn't be blocking... we resolve the html anyway 11 | // could change if the API distinguishes errors from warnings 12 | console.error(chalk.yellow('Errors/Warnings in your MJML'), data.errors); 13 | resolve(data.html); 14 | } 15 | resolve(data.html); 16 | }, clientError => { 17 | reject(clientError.body); 18 | }); 19 | }); 20 | }; 21 | -------------------------------------------------------------------------------- /tutorials/email_sender/v0.1/read-files.js: -------------------------------------------------------------------------------- 1 | module.exports = function () { 2 | const fs = require('fs'); 3 | const path = require('path'); 4 | const templateName = process.argv[2]; 5 | const templatePath = `./templates/${templateName}`; 6 | 7 | try { 8 | fs.readdirSync(templatePath); 9 | } catch (e) { 10 | if (e.code === 'ENOENT') { 11 | return { 12 | readFilesError: { 13 | message: 'Error: this template does not exist.' 14 | } 15 | }; 16 | } 17 | } 18 | // should also check here if index.mjml and variables.json exist 19 | let mjml = fs.readFileSync(path.join(templatePath, 'index.mjml')).toString(); 20 | let variables = JSON.parse(fs.readFileSync(path.join(templatePath, 'variables.json')).toString()); 21 | return {readFilesError: null, mjml, variables}; 22 | }; 23 | -------------------------------------------------------------------------------- /samples/electronic_ticket/README.md: -------------------------------------------------------------------------------- 1 | #ELECTRONIC TICKET FRO MAILJET AIR 2 | 3 | Example of layout change depending of the class and booking information 4 | 5 | ## Vars 6 | 7 | ``` 8 | "Vars" => array( 9 | "firstclass" => true, 10 | "chaufferedcar" => true, 11 | "business" => false, 12 | "destination" => 'New York' 13 | ) 14 | ``` 15 | 16 | ## Results 17 | 18 | ###Vars 19 | ``` 20 | "Vars" => array( 21 | "firstclass" => true, 22 | "chaufferedcar" => false, 23 | "business" => false, 24 | "destination" => 'Paris' 25 | ) 26 | ``` 27 | ###Result 28 | 29 | ![Example 1](media/MailjetAir1.png) 30 | 31 | 32 | ###Vars 33 | ``` 34 | "Vars" => array( 35 | "firstclass" => true, 36 | "chaufferedcar" => true, 37 | "business" => false, 38 | "destination" => 'New York' 39 | ) 40 | ``` 41 | ###Result 42 | 43 | ![Example 1](media/MailjetAir2.png) 44 | 45 | 46 | -------------------------------------------------------------------------------- /tutorials/email_sender/v0.1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mjtl", 3 | "version": "0.1.0", 4 | "description": "Simple node.js tool to leverage the power of Mailjet Templating Language and MJML. Using Mailjet Send API and MJML API (beta).", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "env -S `cat .credentials` mocha", 8 | "start": "env -S `cat .credentials` node index.js" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git@gitlab.mailjet.com:gbetton/mjtl.git" 13 | }, 14 | "keywords": [ 15 | "MJML", 16 | "Mailjet", 17 | "Templating-Language", 18 | "API" 19 | ], 20 | "author": "grebett", 21 | "license": "ISC", 22 | "devDependencies": { 23 | "chai": "^3.5.0", 24 | "mocha": "^3.2.0" 25 | }, 26 | "dependencies": { 27 | "chalk": "^1.1.3", 28 | "node-mailjet": "^3.0.6", 29 | "request": "^2.79.0" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tutorials/email_sender/v0.1/services/mailjet-sender.js: -------------------------------------------------------------------------------- 1 | const nodeMailjet = require('node-mailjet'); 2 | 3 | // simple Sender class using the node.js mailjet wrapper 4 | class Sender { 5 | // the mailjet sender needs valid credentials 6 | constructor(APIKey, APISecret) { 7 | if (typeof APIKey !== 'string' || typeof APISecret !== 'string') { 8 | throw new Error('missing or invalid parameters: APIKey and APISecret are both required and should be strings'); 9 | } 10 | this.sender = nodeMailjet.connect(APIKey, APISecret).post('send'); 11 | } 12 | 13 | // simple send method – see wrapper documentation for more infos: https://github.com/mailjet/mailjet-apiv3-nodejs 14 | send(data) { 15 | return new Promise((resolve, reject) => { 16 | this.sender.request(data).then(function (result) { 17 | resolve(JSON.parse(result.response.text)); 18 | }, function (error) { 19 | reject(error); 20 | }); 21 | }); 22 | } 23 | } 24 | 25 | module.exports = Sender; 26 | -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Mailjet 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /tutorials/LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Mailjet 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /tutorials/email_sender/v0.1/index.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | const chalk = require('chalk'); 4 | 5 | const emailConfig = require('./config'); 6 | const readFiles = require('./read-files'); 7 | const renderMJML = require('./render-mjml'); 8 | const sendEmail = require('./send-email'); 9 | 10 | // 1) read files 11 | const {readFilesError, mjml, variables} = readFiles(); 12 | 13 | if (readFilesError) { 14 | console.error(chalk.red(readFilesError.message)); 15 | return; 16 | } 17 | 18 | // 2) render MJML 19 | renderMJML(mjml).then(html => { 20 | 21 | // 3) create email data by merging emailConfig and data from files 22 | let emailData = { 23 | 'Html-part': html, 24 | Vars: variables 25 | }; 26 | Object.assign(emailData, emailConfig); 27 | 28 | // 4) send email via the Send API (using mailjet-node) 29 | sendEmail(emailData).then(senderSuccess => { 30 | console.log(chalk.green(senderSuccess.message), senderSuccess.data); 31 | }, senderError => { 32 | console.error(chalk.red(senderError)); 33 | }); 34 | }, renderError => { 35 | console.error(chalk.red(renderError.message), '\n', renderError); 36 | }); 37 | -------------------------------------------------------------------------------- /samples/rss_to_email/test.php: -------------------------------------------------------------------------------- 1 | item as $row) { 16 | $list[] = $row; 17 | } 18 | 19 | print(json_encode($list)); 20 | 21 | $params = array( 22 | "method" => "POST", 23 | "FromEmail" => $sender, 24 | "FromName" => "Mailjet Pilot", 25 | "Subject" => 'Your RSS', 26 | "Html-part" => $html_part, 27 | "MJ-TemplateLanguage" => true, 28 | "Vars" => array ( 29 | "rss" => $list, 30 | ), 31 | "Recipients" => array( 32 | array( 33 | "Email" => $recipients[0], 34 | ) 35 | 36 | ) 37 | ); 38 | 39 | print_r($params); 40 | 41 | $response = $mj->post(Resources::$Email, ['body' => $params]); 42 | 43 | var_dump($response->request->getUrl()); 44 | 45 | var_dump($response->request->getFilters()); 46 | 47 | var_dump($response->request->getBody()); 48 | 49 | $response->success() && var_dump($response->getData()); 50 | 51 | ?> 52 | 53 | -------------------------------------------------------------------------------- /tutorials/email_sender/v0.1/test/mailjet-sender.test.js: -------------------------------------------------------------------------------- 1 | const expect = require('chai').expect; 2 | const chalk = require('chalk'); 3 | const Sender = require('../services/mailjet-sender'); 4 | 5 | describe('s (Sender instance)', () => { 6 | describe('constructor', () => { 7 | it('should create a sender object', () => { 8 | const s = new Sender(process.env.MAILJET_API_KEY, process.env.MAILJET_API_SECRET); 9 | expect(s).to.be.an('object'); 10 | }); 11 | }); 12 | 13 | describe('send method', () => { 14 | it('should return an object', (done) => { 15 | const s = new Sender(process.env.MAILJET_API_KEY, process.env.MAILJET_API_SECRET); 16 | const data = require('../config'); 17 | data['Text-part'] = '{{var:title}} This is a TEST EMAIL!'; 18 | data['Html-part'] = '

{{var:title}}

This is a TEST EMAIL!

'; 19 | data['Vars'] = { 20 | title: 'Hello world!' 21 | }; 22 | 23 | s.send(data).then(response => { 24 | expect(response).to.be.an('object'); 25 | expect(response.Sent).to.be.an('array'); 26 | done(); 27 | }, error => { 28 | console.error('error', error); 29 | done(); 30 | }); 31 | }); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /samples/ecommerce_receipt/README.md: -------------------------------------------------------------------------------- 1 | #ECOMMERCE RECEIPT 2 | 3 | This example show how with the loops you can repeat pieces of your template. 4 | Here we display a list of articles purchased and the total of the purchase. 5 | 6 | ## Vars 7 | 8 | ```php 9 | "Vars" => array ( 10 | 'products' => [ 11 | [ 12 | 'name' => 'Minibar', 13 | 'number' => 10, 14 | 'price' => '$5.00', 15 | 'totalprice' => '$50.00' 16 | ], 17 | [ 18 | 'name' => 'Foot massage', 19 | 'number' => 1, 20 | 'price' => '$10.00', 21 | 'totalprice' => '$10.00' 22 | ], 23 | [ 24 | 'name' => 'Dinner', 25 | 'number' => 2, 26 | 'price' => '$50.00', 27 | 'totalprice' => '$100.00' 28 | ], 29 | [ 30 | 'name' => 'Nights', 31 | 'number' => 2, 32 | 'price' => '$150.00', 33 | 'totalprice' => '$300.00' 34 | ] 35 | 36 | ] , 37 | 'vat'=> "$100.00", 38 | 'totalprice'=> "$460.00" 39 | ), 40 | 41 | ``` 42 | 43 | ## Template source 44 | 45 | ```html 46 | {% for article in var:products %} 47 | {{ article.name }} 48 | {{article.number}} 49 | {{article.price}} 50 | {{article.totalprice}} 51 | {% endfor%} 52 | {{var:vat}} 53 | {{var:totalprice}} 54 | ``` 55 | 56 | ## Result 57 | 58 | ![Example 1](media/receipt.png) 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /samples/products_list/README.md: -------------------------------------------------------------------------------- 1 | #PRODUCT LIST 2 | 3 | This example show how with the loops you can repeat pieces of your template. 4 | 5 | ## Vars 6 | 7 | ``` 8 | "Vars" => array ( 9 | 'products' => [ 10 | [ 11 | [ 12 | 'img' => 'http://191n.mj.am/img/191n/3s/x41.jpg', 13 | 'name' => 'MAVA PULLOVER', 14 | 'price' => '55€' 15 | ],[ 16 | 'img' => 'http://191n.mj.am/img/191n/3s/x4l.jpg', 17 | 'name' => 'NEOS PURPLE SKIRT', 18 | 'price' => '45€' 19 | ],[ 20 | 'img' => 'http://191n.mj.am/img/191n/3s/x4m.jpg', 21 | 'name' => 'JENSEN TOP', 22 | 'price' => '78€' 23 | ] 24 | ], 25 | [ 26 | [ 27 | 'img' => 'http://191n.mj.am/img/191n/3s/x42.jpg', 28 | 'name' => 'LEADY JACKET', 29 | 'price' => '110€' 30 | ], 31 | [ 32 | 'img' => 'http://191n.mj.am/img/191n/3s/x4p.jpg', 33 | 'name' => 'FUNKY PANTS', 34 | 'price' => '73€' 35 | ], 36 | [ 37 | 'img' => 'http://191n.mj.am/img/191n/3s/x43.jpg', 38 | 'name' => 'PINKY DRESS', 39 | 'price' => '60€' 40 | ] 41 | ] 42 | ] 43 | ), 44 | ``` 45 | 46 | ## Template source 47 | 48 | ```html 49 | {% for line in var:products %} 50 | 55 | {% endfor %} 56 | ``` 57 | 58 | ## Result 59 | 60 | ![Example 1](media/designed.png) 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /tutorials/email_sender/v0.1/test/mjml-api.test.js: -------------------------------------------------------------------------------- 1 | const expect = require('chai').expect; 2 | const chalk = require('chalk'); 3 | const Client = require('../services/mjml-api'); 4 | 5 | describe('c (Client instance)', () => { 6 | describe('constructor', () => { 7 | it('should be constructed with two string keys', () => { 8 | const c = new Client(process.env.MJML_APPLICATION_ID, process.env.MJML_SECRET_KEY); 9 | expect(c.applicationID).to.be.a('string'); 10 | expect(c.APIPrivateKey).to.be.a('string'); 11 | }); 12 | 13 | it('should throw an error if missing required parameters', () => { 14 | expect(function () { 15 | new Client(undefined, process.env.MJML_SECRET_KEY); 16 | new Client(process.env.MJML_APPLICATION_ID, undefined); 17 | }).to.throw(); 18 | }); 19 | }); 20 | 21 | describe('renderer', () => { 22 | it('should return an object', (done) => { 23 | const c = new Client(process.env.MJML_APPLICATION_ID, process.env.MJML_SECRET_KEY); 24 | c.render('Hello world!').then(body => { 25 | expect(body).to.be.an('object'); 26 | expect(body.html).to.be.a('string'); 27 | done(); 28 | }, error => { 29 | console.error('error:', error.statusCode, error.statusMessage); 30 | done(); 31 | }); 32 | }); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /samples/all_in_one_transac/README.md: -------------------------------------------------------------------------------- 1 | #ALL IN ONE TRANSACTIONAL EMAIL 2 | 3 | This example show how with one single template you can manage a unique canvas for all your small transactional emails 4 | 5 | This example handle : 6 | 7 | - Registration confirmation message 8 | - Email verification message 9 | - third day after registration message 10 | - custom message 11 | - Badge / Gamification notification 12 | 13 | ## Vars 14 | 15 | ``` 16 | "Vars" => array( 17 | "firstname" => "Emmanuel", 18 | "step" => "badge", 19 | "badge" => "writer", 20 | "level" => 1, 21 | "messagecontent" => "hi!!", 22 | ) 23 | ``` 24 | 25 | ## Results 26 | 27 | ###Vars 28 | ``` 29 | "Vars" => array( 30 | "firstname" => "Emmanuel2", 31 | "step" => "registration", 32 | ) 33 | ``` 34 | ###Result 35 | 36 | ![Example 1](media/all1.png) 37 | 38 | 39 | ###Vars 40 | ``` 41 | "Vars" => array( 42 | "firstname" => "Emmanuel4", 43 | "step" => "badge", 44 | "badge" => "contributor", 45 | "level" => 4, 46 | ) 47 | ``` 48 | ###Result 49 | 50 | ![Example 1](media/all2.png) 51 | 52 | 53 | ###Vars 54 | ``` 55 | "Vars" => array( 56 | "firstname" => "Emmanuel1", 57 | "step" => "confirmation", 58 | ) 59 | ``` 60 | ###Result 61 | 62 | ![Example 1](media/all3.png) 63 | 64 | 65 | ###Vars 66 | ``` 67 | "Vars" => array( 68 | "firstname" => "Emmanuel6", 69 | "step" => "message", 70 | "messagecontent" => "Just a small Hello !!" 71 | ) 72 | ``` 73 | ###Result 74 | 75 | ![Example 1](media/all4.png) 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /tutorials/email_sender/v0.1/services/mjml-api.js: -------------------------------------------------------------------------------- 1 | const request = require('request'); 2 | 3 | // MJML API has a single /render endpoint for now. We hardcode it. 4 | const endpoint = 'https://api.mjml.io/v1/render'; 5 | 6 | class Client { 7 | // the mjml-api client needs valid credentials 8 | constructor(applicationID, APIPrivateKey) { 9 | if (typeof applicationID !== 'string' || typeof APIPrivateKey !== 'string') { 10 | throw new Error('missing or invalid parameters: applicationID and APIPrivateKey are both required and should be strings'); 11 | } 12 | this.applicationID = applicationID; 13 | this.APIPrivateKey = APIPrivateKey; 14 | } 15 | 16 | // accepts a string and returns a Promise with the MJML API answer payload (see https://mjml.io/api/documentation/#tag-render) 17 | render(mjml) { 18 | if (typeof mjml !== 'string') { 19 | throw new Error('missing or invalid parameters: MJML is required and should be a string'); 20 | } 21 | 22 | return new Promise((resolve, reject) => { 23 | request({ 24 | url: endpoint, 25 | 'auth': { 26 | 'username': this.applicationID, 27 | 'password': this.APIPrivateKey, 28 | 'sendImmediately': true 29 | }, 30 | headers: { 31 | 'content-type': 'application/json', 32 | }, 33 | method: 'POST', 34 | json: true, 35 | body: { mjml } 36 | }, function(error, response, body) { 37 | if (response.statusCode === 200 && !error) { 38 | resolve(body); 39 | } else { 40 | reject(response); 41 | } 42 | }); 43 | }); 44 | } 45 | } 46 | 47 | module.exports = Client; 48 | -------------------------------------------------------------------------------- /tutorials/abandoned_cart/variables.json: -------------------------------------------------------------------------------- 1 | { 2 | "order": { 3 | "items": [ 4 | { 5 | "title": "Brown shoes", 6 | "image_URL": "https://s13.postimg.org/r3otqmynn/shoes.png", 7 | "price": { 8 | "currency": "$", 9 | "separator": ".", 10 | "amount": 79.99 11 | }, 12 | "size": "9.5", 13 | "color": "Brown" 14 | }, 15 | { 16 | "title": "Blue T-shirt", 17 | "image_URL": "https://s13.postimg.org/onn0csgkz/t_shirt.png", 18 | "price": { 19 | "currency": "$", 20 | "separator": ".", 21 | "amount": 29.99 22 | }, 23 | "size": "S", 24 | "color": "Blue" 25 | }, 26 | { 27 | "title": "Pale blue shirt", 28 | "image_URL": "https://s13.postimg.org/shgglxxwz/shirt.png", 29 | "price": { 30 | "currency": "$", 31 | "amount": 24.99 32 | }, 33 | "size": "S", 34 | "color": "Blue" 35 | } 36 | ], 37 | "subtotal": { 38 | "currency": "$", 39 | "amount": 134.97 40 | } 41 | }, 42 | "suggestions": [ 43 | { 44 | "title": "light grey t-shirt", 45 | "link": "https://clothes-men.com/123456", 46 | "image_URL": "https://s13.postimg.org/7gqf10uer/men1.png" 47 | }, 48 | { 49 | "title": "dark grey t-shirt", 50 | "link": "https://clothes-men.com/123456", 51 | "image_URL": "https://s13.postimg.org/62ys5pv5f/men2.png" 52 | }, 53 | { 54 | "title": "brown sweat-shirt", 55 | "link": "https://clothes-men.com/123456", 56 | "image_URL": "https://s13.postimg.org/51yjgle5v/men3.png" 57 | } 58 | ] 59 | } 60 | -------------------------------------------------------------------------------- /tutorials/email_sender/v0.1/templates/abandoned_cart/variables.json: -------------------------------------------------------------------------------- 1 | { 2 | "order": { 3 | "items": [ 4 | { 5 | "title": "Brown shoes", 6 | "image_URL": "https://s13.postimg.org/r3otqmynn/shoes.png", 7 | "price": { 8 | "currency": "$", 9 | "separator": ".", 10 | "amount": 79.99 11 | }, 12 | "size": "9.5", 13 | "color": "Brown" 14 | }, 15 | { 16 | "title": "Blue T-shirt", 17 | "image_URL": "https://s13.postimg.org/onn0csgkz/t_shirt.png", 18 | "price": { 19 | "currency": "$", 20 | "separator": ".", 21 | "amount": 29.99 22 | }, 23 | "size": "S", 24 | "color": "Blue" 25 | }, 26 | { 27 | "title": "Pale blue shirt", 28 | "image_URL": "https://s13.postimg.org/shgglxxwz/shirt.png", 29 | "price": { 30 | "currency": "$", 31 | "amount": 24.99 32 | }, 33 | "size": "S", 34 | "color": "Blue" 35 | } 36 | ], 37 | "subtotal": { 38 | "currency": "$", 39 | "amount": 134.97 40 | } 41 | }, 42 | "suggestions": [ 43 | { 44 | "title": "light grey t-shirt", 45 | "link": "https://clothes-men.com/123456", 46 | "image_URL": "https://s13.postimg.org/7gqf10uer/men1.png" 47 | }, 48 | { 49 | "title": "dark grey t-shirt", 50 | "link": "https://clothes-men.com/123456", 51 | "image_URL": "https://s13.postimg.org/62ys5pv5f/men2.png" 52 | }, 53 | { 54 | "title": "brown sweat-shirt", 55 | "link": "https://clothes-men.com/123456", 56 | "image_URL": "https://s13.postimg.org/51yjgle5v/men3.png" 57 | } 58 | ] 59 | } 60 | -------------------------------------------------------------------------------- /samples/ecommerce_receipt/test.php: -------------------------------------------------------------------------------- 1 | "POST", 17 | "FromEmail" => $sender, 18 | "FromName" => "Mailjet Pilot", 19 | "Subject" => 'Your receipt', 20 | "Html-part" => $html_part, 21 | "MJ-TemplateLanguage" => true, 22 | "Vars" => array ( 23 | 'products' => [ 24 | [ 25 | 'name' => 'Minibar', 26 | 'number' => 10, 27 | 'price' => '$5.00', 28 | 'totalprice' => '$50.00' 29 | ], 30 | [ 31 | 'name' => 'Foot massage', 32 | 'number' => 1, 33 | 'price' => '$10.00', 34 | 'totalprice' => '$10.00' 35 | ], 36 | [ 37 | 'name' => 'Dinner', 38 | 'number' => 2, 39 | 'price' => '$50.00', 40 | 'totalprice' => '$100.00' 41 | ], 42 | [ 43 | 'name' => 'Nights', 44 | 'number' => 2, 45 | 'price' => '$150.00', 46 | 'totalprice' => '$300.00' 47 | ] 48 | 49 | ] , 50 | 'vat'=> "$100.00", 51 | 'totalprice'=> "$460.00" 52 | ), 53 | "Recipients" => array( 54 | array( 55 | "Email" => $recipients[0], 56 | ) 57 | 58 | ) 59 | ); 60 | 61 | print_r($params); 62 | 63 | $response = $mj->post(Resources::$Email, ['body' => $params]); 64 | 65 | var_dump($response->request->getUrl()); 66 | 67 | var_dump($response->request->getFilters()); 68 | 69 | var_dump($response->request->getBody()); 70 | 71 | $response->success() && var_dump($response->getData()); 72 | 73 | ?> 74 | 75 | -------------------------------------------------------------------------------- /tutorials/digest/variables.json: -------------------------------------------------------------------------------- 1 | { 2 | "blogposts": [ 3 | { 4 | "title": "URBAN FASHION", 5 | "content": "It’s quite clear that the phenomenon of urban style is here for decades. Just one quick pass during New York Fashion Week, and you’ll witnesses hoardes of style-setters getting snapped by photographers. But what is really urban style?", 6 | "image_URL": "https://s30.postimg.org/b8xytfuo1/main1.png" 7 | }, 8 | { 9 | "title": "WEAR YOUR STYLE", 10 | "content": "Mornings are the worst. Is there something more annoying than hitting the snooze button again and again, only to be forced to run all around trying to find the perfect clothes in a hurry. And that's it, you’re late.", 11 | "image_URL": "https://s30.postimg.org/iq768nk75/main2.png" 12 | }, 13 | { 14 | "title": "DON'T WAIT", 15 | "content": "Our fashion expert Nick Cage, left us with some very wise words yesterday that kept me thinking throughout the day today. He said \"don't wait for opportunities, create them\" and I was once again reminded that the power is all in me.", 16 | "image_URL": "https://s30.postimg.org/utchw7v9d/main3.png" 17 | } 18 | ], 19 | "suggestions": [ 20 | { 21 | "title": "light grey t-shirt", 22 | "link": "https://mailjet.clothes-men.com/123456", 23 | "image_URL": "https://s13.postimg.org/7gqf10uer/men1.png" 24 | }, 25 | { 26 | "title": "dark grey t-shirt", 27 | "link": "https://mailjet.clothes-men.com/123456", 28 | "image_URL": "https://s13.postimg.org/62ys5pv5f/men2.png" 29 | }, 30 | { 31 | "title": "brown sweat-shirt", 32 | "link": "https://mailjet.clothes-men.com/123456", 33 | "image_URL": "https://s13.postimg.org/51yjgle5v/men3.png" 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /samples/white_label/README.md: -------------------------------------------------------------------------------- 1 | #White Label 2 | 3 | This example can be used to handle several brands on one template or to customize the design depending on the configuration of a software : 4 | 5 | - change colors 6 | - change base url 7 | - change twitter account link 8 | - change the logo 9 | 10 | ## Result 11 | 12 | ###Vars 13 | ``` 14 | "Vars" => array( 15 | "firstname" => "Emmanuel1", 16 | "header" => "http://oi08.mjt.lu/img/oi08/b/14ky5/vs3r.png", 17 | "header_color" => "#ffffff", 18 | "bg_color" => "#d6dde5", 19 | "namesupport" => "Your Nukleus Support", 20 | "twitter" => "igra_fan", 21 | "base_url" => "http://www.mailjet.com", 22 | "request_number" => 11111 23 | ) 24 | ``` 25 | ###Result 26 | 27 | ![Example 1](media/white_label1.png) 28 | 29 | 30 | ###Vars 31 | ``` 32 | "Vars" => array( 33 | "firstname" => "Emmanuel2", 34 | "header" => "https://raw.githubusercontent.com/eboisgon/mailjet-template-api-samples/master/white_label/img/mailjet.jpg", 35 | "header_color" => "#2f323b", 36 | "bg_color" => "#d6dde5", 37 | "namesupport" => "Mailjet", 38 | "twitter" => "mailjet", 39 | "base_url" => "http://www.mailjet.com", 40 | "request_number" => 11111 41 | ) 42 | ``` 43 | ###Result 44 | 45 | ![Example 2](media/white_label2.png) 46 | 47 | 48 | ###Vars 49 | ``` 50 | "Vars" => array( 51 | "firstname" => "Emmanuel3", 52 | "header" => "https://raw.githubusercontent.com/eboisgon/mailjet-template-api-samples/master/white_label/img/mailjet.jpg", 53 | "header_color" => "#2f323b", 54 | "bg_color" => "#FFCC4D", 55 | "namesupport" => "Mailjet Developers", 56 | "twitter" => "mailjetdev", 57 | "base_url" => "http://dev.mailjet.com", 58 | "request_number" => 11111 59 | ) 60 | ``` 61 | ###Result 62 | 63 | ![Example 3](media/white_label3.png) 64 | 65 | 66 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![alt text](http://cdn.appstorm.net/web.appstorm.net/files/2012/02/mailjet_logo_200x200.png "Mailjet") 2 | 3 | # Mailjet API V3 templating samples 4 | 5 | The samples leverage the Mailjet Templating language for Transactional Emailing. 6 | 7 | ## Documentation 8 | 9 | [Full guide for Mailjet Transactional templating](http://dev.mailjet.com/guides/#transactional-templating) 10 | 11 | The Mailjet templating language offers : 12 | - [Data substitution](http://dev.mailjet.com/guides/#variables) with `{{ ... }}` 13 | - [Conditional statements](http://dev.mailjet.com/guides/#conditional-statements): `if`, `else`, `elseif` and `endif` 14 | - [Loop statements](http://dev.mailjet.com/guides/#loop-statements): `for in` and `endfor` 15 | 16 | 17 | ## List of samples 18 | 19 | - [All in one transactional](all_in_one_transac/) : one template rules all your simple transactional messages. Make it easy to manage a single canvas for all your messages 20 | - [Mailjet Air Electronic ticket](electronic_ticket/) : depending on the destination, the seat class and booking of a car to the airport, the layout changes and offers specific call to actions 21 | - [Question / Answers / Comment notifications](question_answer/) : alerts for new question, comment and answer (Quandora like) with specific call to action depending on the alerts 22 | - [Ecommerce purchase steps](ecommerce/) : one template to handle all the purchasing communication to the clients 23 | - [White label](white_label/) : one template to handle multiple branding 24 | - [RSS to email](rss_to_email/) : pull a RSS feed and send it by email (simple loop sample) 25 | - [Product list](products_list/) : simple product list 26 | - [Product list in zigzag](zigzag_loop/) : product list with alternative image side 27 | - [Ecommerce receipt](ecommerce_receipt/) : list of product purchased and total price of purchase 28 | 29 | 30 | More to come soon, so come back ;) 31 | -------------------------------------------------------------------------------- /samples/README.md: -------------------------------------------------------------------------------- 1 | ![alt text](http://cdn.appstorm.net/web.appstorm.net/files/2012/02/mailjet_logo_200x200.png "Mailjet") 2 | 3 | # Mailjet API V3 templating samples 4 | 5 | The samples leverage the Mailjet Templating language for Transactional Emailing. 6 | 7 | ##Documentation 8 | 9 | [Full guide for Mailjet Transactional templating](http://dev.mailjet.com/guides/#transactional-templating) 10 | 11 | The Mailjet templating language offers : 12 | - [Data substitution](http://dev.mailjet.com/guides/#variables) with `{{ ... }}` 13 | - [Conditional statements](http://dev.mailjet.com/guides/#conditional-statements): `if`, `else`, `elseif` and `endif` 14 | - [Loop statements](http://dev.mailjet.com/guides/#loop-statements): `for in` and `endfor` 15 | 16 | 17 | ##List of samples 18 | 19 | - [All in one transactional](all_in_one_transac/) : one template rules all your simple transactional messages. Make it easy to manage a single canvas for all your messages 20 | - [Mailjet Air Electronic ticket](electronic_ticket/) : depending on the destination, the seat class and booking of a car to the airport, the layout changes and offers specific call to actions 21 | - [Question / Answers / Comment notifications](question_answer/) : alerts for new question, comment and answer (Quandora like) with specific call to action depending on the alerts 22 | - [Ecommerce purchase steps](ecommerce/) : one template to handle all the purchasing communication to the clients 23 | - [White label](white_label/) : one template to handle multiple branding 24 | - [RSS to email](rss_to_email/) : pull a RSS feed and send it by email (simple loop sample) 25 | - [Product list](products_list/) : simple product list 26 | - [Product list in zigzag](zigzag_loop/) : product list with alternative image side 27 | - [Ecommerce receipt](ecommerce_receipt/) : list of product purchased and total price of purchase 28 | 29 | 30 | More to come soon, so come back ;) 31 | -------------------------------------------------------------------------------- /samples/products_list/test.php: -------------------------------------------------------------------------------- 1 | "POST", 17 | "FromEmail" => $sender, 18 | "FromName" => "Mailjet Pilot", 19 | "Subject" => 'Our products', 20 | "Html-part" => $html_part, 21 | "MJ-TemplateLanguage" => true, 22 | "Vars" => array ( 23 | 'products' => [ 24 | [ 25 | [ 26 | 'img' => 'http://191n.mj.am/img/191n/3s/x41.jpg', 27 | 'name' => 'MAVA PULLOVER', 28 | 'price' => '55€' 29 | ],[ 30 | 'img' => 'http://191n.mj.am/img/191n/3s/x4l.jpg', 31 | 'name' => 'NEOS PURPLE SKIRT', 32 | 'price' => '45€' 33 | ],[ 34 | 'img' => 'http://191n.mj.am/img/191n/3s/x4m.jpg', 35 | 'name' => 'JENSEN TOP', 36 | 'price' => '78€' 37 | ] 38 | ], 39 | [ 40 | [ 41 | 'img' => 'http://191n.mj.am/img/191n/3s/x42.jpg', 42 | 'name' => 'LEADY JACKET', 43 | 'price' => '110€' 44 | ], 45 | [ 46 | 'img' => 'http://191n.mj.am/img/191n/3s/x4p.jpg', 47 | 'name' => 'FUNKY PANTS', 48 | 'price' => '73€' 49 | ], 50 | [ 51 | 'img' => 'http://191n.mj.am/img/191n/3s/x43.jpg', 52 | 'name' => 'PINKY DRESS', 53 | 'price' => '60€' 54 | ] 55 | ] 56 | ] 57 | ), 58 | "Recipients" => array( 59 | array( 60 | "Email" => $recipients[0], 61 | ) 62 | 63 | ) 64 | ); 65 | 66 | print_r($params); 67 | 68 | $response = $mj->post(Resources::$Email, ['body' => $params]); 69 | 70 | var_dump($response->request->getUrl()); 71 | 72 | var_dump($response->request->getFilters()); 73 | 74 | var_dump($response->request->getBody()); 75 | 76 | $response->success() && var_dump($response->getData()); 77 | 78 | ?> 79 | 80 | -------------------------------------------------------------------------------- /samples/zigzag_loop/test.php: -------------------------------------------------------------------------------- 1 | "POST", 16 | "FromEmail" => $sender, 17 | "FromName" => "Mailjet Pilot", 18 | "Subject" => 'Our products', 19 | "Html-part" => $html_part, 20 | 'MJ-TemplateErrorDeliver' => 0, 21 | "Vars" => array ( 22 | 'products' => [ 23 | [ 24 | 'img' => 'http://191n.mj.am/img/191n/3s/x41.jpg', 25 | 'name' => 'MAVA PULLOVER', 26 | 'price' => '55€', 27 | 'id' => 1 28 | ],[ 29 | 'img' => 'http://191n.mj.am/img/191n/3s/x4l.jpg', 30 | 'name' => 'NEOS PURPLE SKIRT', 31 | 'price' => '45€', 32 | 'id' => 2 33 | ],[ 34 | 'img' => 'http://191n.mj.am/img/191n/3s/x4m.jpg', 35 | 'name' => 'JENSEN TOP', 36 | 'price' => '78€', 37 | 'id' => 3 38 | ], 39 | [ 40 | 'img' => 'http://191n.mj.am/img/191n/3s/x42.jpg', 41 | 'name' => 'LEADY JACKET', 42 | 'price' => '110€', 43 | 'id' => 4 44 | ], 45 | [ 46 | 'img' => 'http://191n.mj.am/img/191n/3s/x4p.jpg', 47 | 'name' => 'FUNKY PANTS', 48 | 'price' => '73€', 49 | 'id' => 5 50 | ], 51 | [ 52 | 'img' => 'http://191n.mj.am/img/191n/3s/x43.jpg', 53 | 'name' => 'PINKY DRESS', 54 | 'price' => '60€', 55 | 'id' => 6 56 | ] 57 | ] 58 | ), 59 | "Recipients" => array( 60 | array( 61 | "Email" => $recipients[0], 62 | ) 63 | 64 | ) 65 | ); 66 | 67 | print_r($params); 68 | 69 | $response = $mj->post(Resources::$Email, ['body' => $params]); 70 | 71 | var_dump($response->request->getUrl()); 72 | 73 | var_dump($response->request->getFilters()); 74 | 75 | var_dump($response->request->getBody()); 76 | 77 | $response->success() && var_dump($response->getData()); 78 | 79 | ?> 80 | 81 | -------------------------------------------------------------------------------- /samples/zigzag_loop/README.md: -------------------------------------------------------------------------------- 1 | #PRODUCT LIST IN ZIGZAG 2 | 3 | This example show how with the loops you can repeat pieces of your template. 4 | 5 | ## Vars 6 | 7 | ```php 8 | "Vars" => array ( 9 | 'products' => [ 10 | [ 11 | 'img' => 'http://191n.mj.am/img/191n/3s/x41.jpg', 12 | 'name' => 'MAVA PULLOVER', 13 | 'price' => '55€', 14 | 'id' => 1 15 | ],[ 16 | 'img' => 'http://191n.mj.am/img/191n/3s/x4l.jpg', 17 | 'name' => 'NEOS PURPLE SKIRT', 18 | 'price' => '45€', 19 | 'id' => 2 20 | ],[ 21 | 'img' => 'http://191n.mj.am/img/191n/3s/x4m.jpg', 22 | 'name' => 'JENSEN TOP', 23 | 'price' => '78€', 24 | 'id' => 3 25 | ], 26 | [ 27 | 'img' => 'http://191n.mj.am/img/191n/3s/x42.jpg', 28 | 'name' => 'LEADY JACKET', 29 | 'price' => '110€', 30 | 'id' => 4 31 | ], 32 | [ 33 | 'img' => 'http://191n.mj.am/img/191n/3s/x4p.jpg', 34 | 'name' => 'FUNKY PANTS', 35 | 'price' => '73€', 36 | 'id' => 5 37 | ], 38 | [ 39 | 'img' => 'http://191n.mj.am/img/191n/3s/x43.jpg', 40 | 'name' => 'PINKY DRESS', 41 | 'price' => '60€', 42 | 'id' => 6 43 | ] 44 | ] 45 | ), 46 | 47 | ``` 48 | 49 | ## Template source 50 | 51 | ```html 52 | {% for product in var:products %} 53 | {% if (product.id mod 2) = 1 %} 54 | 55 | 56 | {{product.name}}
{{product.price}} 57 | 58 | {% else %} 59 | 60 | {{product.name}}
{{product.price}} 61 | 62 | 63 | {% endif %} 64 | {% endfor %} 65 | ``` 66 | 67 | ## Result 68 | 69 | ###Simple example: 70 | 71 | The placement of the image is switching between left and right. 72 | The background color is rotating over 3 variants using the id of the product with the mod function of the templating language. 73 | 74 | ![Example 1](media/zigzag.png) 75 | 76 | ###Advanced example: 77 | 78 | ![Example 1](media/zigzag_design.png) 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /samples/zigzag_loop/test_design.php: -------------------------------------------------------------------------------- 1 | "POST", 17 | "FromEmail" => $sender, 18 | "FromName" => "Mailjet Pilot", 19 | "Subject" => 'Our products', 20 | "Html-part" => $html_part, 21 | "MJ-TemplateLanguage" => true, 22 | "Vars" => array ( 23 | 'products' => [ 24 | [ 25 | 'img' => 'http://191n.mj.am/img/191n/3s/x0o.png', 26 | 'name' => 'TREK 1 :', 27 | 'date' => '12 - 13 - 14 JUNE', 28 | 'desc' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Magna efficitur, eu semper augue semper. Aliquam erat volutpat.', 29 | 'id' => 1 30 | ], 31 | [ 32 | 'img' => 'http://191n.mj.am/img/191n/3s/xmr.png', 33 | 'name' => 'TREK 2 :', 34 | 'date' => '12 - 13 - 14 JULY', 35 | 'desc' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Magna efficitur, eu semper augue semper. Aliquam erat volutpat.', 36 | 'id' => 2 37 | ], 38 | [ 39 | 'img' => 'http://191n.mj.am/img/191n/3s/xm7.png', 40 | 'name' => 'TREK 3 :', 41 | 'date' => '12 - 13 - 14 AUGUST', 42 | 'desc' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Magna efficitur, eu semper augue semper. Aliquam erat volutpat.', 43 | 'id' => 3 44 | ], 45 | [ 46 | 'img' => 'http://191n.mj.am/img/191n/3s/xmr.png', 47 | 'name' => 'TREK 4 :', 48 | 'date' => '12 - 13 - 14 SEPTEMBER', 49 | 'desc' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Magna efficitur, eu semper augue semper. Aliquam erat volutpat.', 50 | 'id' => 4 51 | ] 52 | ] 53 | ), 54 | "Recipients" => array( 55 | array( 56 | "Email" => $recipients[0], 57 | ) 58 | 59 | ) 60 | ); 61 | 62 | print_r($params); 63 | 64 | $response = $mj->post(Resources::$Email, ['body' => $params]); 65 | 66 | var_dump($response->request->getUrl()); 67 | 68 | var_dump($response->request->getFilters()); 69 | 70 | var_dump($response->request->getBody()); 71 | 72 | $response->success() && var_dump($response->getData()); 73 | 74 | ?> 75 | 76 | -------------------------------------------------------------------------------- /tutorials/receipt/variables.json: -------------------------------------------------------------------------------- 1 | { 2 | "user": { 3 | "name": "Matthew", 4 | "gender": "male", 5 | "address": { 6 | "billing_address": { 7 | "full_name": "Betty S. Bronson", 8 | "address_line_1": "102 Duck Creek Road", 9 | "city": "Palo Alto", 10 | "state": "CA", 11 | "postal_code": "94306" 12 | }, 13 | "shipping_address": { 14 | "full_name": "Betty S. Bronson", 15 | "address_line_1": "3628 Creekside Lane", 16 | "city": "Santa Barbara", 17 | "state": "CA", 18 | "postal_code": "93101" 19 | } 20 | } 21 | }, 22 | "order": { 23 | "items": [ 24 | { 25 | "title": "Brown shoes", 26 | "image_URL": "http://bit.ly/mj-tpl-tuto-shoes-simple", 27 | "price": { 28 | "currency": "$", 29 | "separator": ".", 30 | "amount": 79.99 31 | }, 32 | "size": "9.5", 33 | "quantity": 1 34 | }, 35 | { 36 | "title": "Blue T-shirt", 37 | "image_URL": "http://bit.ly/mj-tpl-lang-tuto-tshirt-simple", 38 | "price": { 39 | "currency": "$", 40 | "separator": ".", 41 | "amount": 29.99 42 | }, 43 | "size": "S", 44 | "quantity": 1 45 | }, 46 | { 47 | "title": "Pale blue shirt", 48 | "image_URL": "http://bit.ly/mj-tpl-lang-tuto-shirt-simple", 49 | "price": { 50 | "currency": "$", 51 | "amount": 24.99 52 | }, 53 | "size": "S", 54 | "quantity": 1 55 | } 56 | ], 57 | "delivery_date": "Apr 5, 2017", 58 | "sales_taxes_percentage": 0.0825, 59 | "shipping": { 60 | "currency": "$", 61 | "amount": 10 62 | }, 63 | "total": { 64 | "currency": "$", 65 | "amount": 134.97 66 | }, 67 | "number": 123456789 68 | }, 69 | "suggestions": [ 70 | { 71 | "title": "light grey t-shirt", 72 | "link": "https://clothes-men.mailjet.com/123456", 73 | "image_URL": "http://bit.ly/mj-tpl-tuto-men1" 74 | }, 75 | { 76 | "title": "dark grey t-shirt", 77 | "link": "https://clothes-men.mailjet.com/123456", 78 | "image_URL": "http://bit.ly/mj-tpl-tuto-men2" 79 | }, 80 | { 81 | "title": "brown sweat-shirt", 82 | "link": "https://clothes-men.mailjet.com/123456", 83 | "image_URL": "http://bit.ly/mj-tpl-tuto-men3" 84 | } 85 | ] 86 | } 87 | -------------------------------------------------------------------------------- /samples/electronic_ticket/test.php: -------------------------------------------------------------------------------- 1 | "POST", 15 | "FromEmail" => $sender, 16 | "FromName" => "Mailjet Pilot", 17 | "Subject" => 'Your ticket to {{var:destination}}', 18 | "MJ-TemplateLanguage" => true, 19 | "Html-part" => $html_part, 20 | "Vars" => array( 21 | "author" => "Emmanuel", 22 | "url" => "http://www.example.com", 23 | "question" => "How to create a notification system for questions?", 24 | "questiondetail" => "I would like to do a nice notification system", 25 | "answer" => "Use this example", 26 | "comment" => "Just commenting for fun", 27 | "view" => 1, 28 | "vote" => 2 29 | ), 30 | "Recipients" => array( 31 | array( 32 | "Email" => $recipients[0], 33 | "Vars" => array( 34 | "firstclass" => true, 35 | "chaufferedcar" => true, 36 | "business" => false, 37 | "destination" => 'London' 38 | ) 39 | ), 40 | array( 41 | "Email" => $recipients[1], 42 | "Vars" => array( 43 | "firstclass" => true, 44 | "chaufferedcar" => false, 45 | "business" => false, 46 | "destination" => 'Paris' 47 | ) 48 | ), 49 | array( 50 | "Email" => $recipients[2], 51 | "Vars" => array( 52 | "firstclass" => false, 53 | "chaufferedcar" => false, 54 | "business" => false, 55 | "destination" => 'London' 56 | ) 57 | ), 58 | array( 59 | "Email" => $recipients[3], 60 | "Vars" => array( 61 | "firstclass" => true, 62 | "chaufferedcar" => true, 63 | "business" => false, 64 | "destination" => 'New York' 65 | ) 66 | ), 67 | array( 68 | "Email" => $recipients[4], 69 | "Vars" => array( 70 | "firstclass" => true, 71 | "chaufferedcar" => true, 72 | "business" => false, 73 | "destination" => 'London' 74 | ) 75 | ), 76 | 77 | ) 78 | ); 79 | 80 | $response = $mj->post(Resources::$Email, ['body' => $params]); 81 | 82 | var_dump($response->request->getUrl()); 83 | 84 | var_dump($response->request->getFilters()); 85 | 86 | var_dump($response->request->getBody()); 87 | 88 | $response->success() && var_dump($response->getData()); 89 | 90 | ?> 91 | 92 | -------------------------------------------------------------------------------- /samples/all_in_one_transac/test.php: -------------------------------------------------------------------------------- 1 | "POST", 15 | "FromEmail" => $sender, 16 | "FromName" => "Mailjet Pilot", 17 | "Subject" => '{{var:firstname}}, {% if var:step == "registration" %}Thank you for registering{% elseif var:step == "confirmation" %}Please confirm your email{% elseif var:step == "3day" %}3 days already with us!!!{% elseif var:step == "badge" %}A new badge for you{% else %}Small message from us{% endif %}', 18 | "Html-part" => $html_part, 19 | "MJ-TemplateLanguage" => true, 20 | "Vars" => array ( 21 | "firstname" => "", 22 | "step" => "", 23 | "badge" => "", 24 | "level" => 0, 25 | "messagecontent" => "" 26 | ), 27 | "Recipients" => array( 28 | array( 29 | "Email" => $recipients[0], 30 | "Vars" => array( 31 | "firstname" => "Emmanuel1", 32 | "step" => "confirmation", 33 | ) 34 | ), 35 | array( 36 | "Email" => $recipients[1], 37 | "Vars" => array( 38 | "firstname" => "Emmanuel2", 39 | "step" => "registration", 40 | ) 41 | ), 42 | array( 43 | "Email" => $recipients[2], 44 | "Vars" => array( 45 | "firstname" => "Emmanuel3", 46 | "step" => "badge", 47 | "badge" => "writer", 48 | "level" => 1, 49 | ) 50 | ), 51 | array( 52 | "Email" => $recipients[3], 53 | "Vars" => array( 54 | "firstname" => "Emmanuel4", 55 | "step" => "badge", 56 | "badge" => "contributor", 57 | "level" => 4, 58 | ) 59 | ), 60 | array( 61 | "Email" => $recipients[4], 62 | "Vars" => array( 63 | "firstname" => "Emmanuel5", 64 | "step" => "3day" 65 | ) 66 | ), 67 | array( 68 | "Email" => $recipients[5], 69 | "Vars" => array( 70 | "firstname" => "Emmanuel6", 71 | "step" => "message", 72 | "messagecontent" => "Just a small Hello !!" 73 | ) 74 | ), 75 | 76 | ) 77 | ); 78 | 79 | $response = $mj->post(Resources::$Email, ['body' => $params]); 80 | 81 | var_dump($response->request->getUrl()); 82 | 83 | var_dump($response->request->getFilters()); 84 | 85 | var_dump($response->request->getBody()); 86 | 87 | $response->success() && var_dump($response->getData()); 88 | 89 | ?> 90 | 91 | -------------------------------------------------------------------------------- /tutorials/email_sender/v0.1/templates/receipt/variables.json: -------------------------------------------------------------------------------- 1 | { 2 | "user": { 3 | "name": "Matthew", 4 | "gender": "male", 5 | "address": { 6 | "billing_address": { 7 | "full_name": "Betty S. Bronson", 8 | "address_line_1": "102 Duck Creek Road", 9 | "city": "Palo Alto", 10 | "state": "CA", 11 | "postal_code": "94306" 12 | }, 13 | "shipping_address": { 14 | "full_name": "Betty S. Bronson", 15 | "address_line_1": "3628 Creekside Lane", 16 | "city": "Santa Barbara", 17 | "state": "CA", 18 | "postal_code": "93101" 19 | } 20 | } 21 | }, 22 | "order": { 23 | "items": [ 24 | { 25 | "title": "Brown shoes", 26 | "image_URL": "http://bit.ly/mj-tpl-tuto-shoes-simple", 27 | "price": { 28 | "currency": "$", 29 | "separator": ".", 30 | "amount": 79.99 31 | }, 32 | "size": "9.5", 33 | "quantity": 1 34 | }, 35 | { 36 | "title": "Blue T-shirt", 37 | "image_URL": "http://bit.ly/mj-tpl-lang-tuto-tshirt-simple", 38 | "price": { 39 | "currency": "$", 40 | "separator": ".", 41 | "amount": 29.99 42 | }, 43 | "size": "S", 44 | "quantity": 1 45 | }, 46 | { 47 | "title": "Pale blue shirt", 48 | "image_URL": "http://bit.ly/mj-tpl-lang-tuto-shirt-simple", 49 | "price": { 50 | "currency": "$", 51 | "amount": 24.99 52 | }, 53 | "size": "S", 54 | "quantity": 1 55 | } 56 | ], 57 | "delivery_date": "Apr 5, 2017", 58 | "sales_taxes_percentage": 0.0825, 59 | "shipping": { 60 | "currency": "$", 61 | "amount": 10 62 | }, 63 | "total": { 64 | "currency": "$", 65 | "amount": 134.97 66 | }, 67 | "number": 123456789 68 | }, 69 | "suggestions": [ 70 | { 71 | "title": "light grey t-shirt", 72 | "link": "https://clothes-men.mailjet.com/123456", 73 | "image_URL": "http://bit.ly/mj-tpl-tuto-men1" 74 | }, 75 | { 76 | "title": "dark grey t-shirt", 77 | "link": "https://clothes-men.mailjet.com/123456", 78 | "image_URL": "http://bit.ly/mj-tpl-tuto-men2" 79 | }, 80 | { 81 | "title": "brown sweat-shirt", 82 | "link": "https://clothes-men.mailjet.com/123456", 83 | "image_URL": "http://bit.ly/mj-tpl-tuto-men3" 84 | } 85 | ] 86 | } 87 | -------------------------------------------------------------------------------- /samples/question_answer/template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 |
7 | 8 |

9 | 10 | {{var:author}} 11 | {% if var:comment!="" and var:answer=="" %} commented on {% elseif var:comment!="" %} commented an answer on {% elseif var:answer!="" %} answered {% else %} asked {% endif %} 12 | {{var:question}}: 13 | 14 |

15 | {% if var:comment=="" and var:answer!="" %} 16 |

Answer:

17 |
18 | {{var:answer}} 19 |
20 | {% endif %} 21 | 22 | {% if var:comment!="" %} 23 |
24 | {{var:comment}} 25 |
26 | {% endif %} 27 | 28 | {% if var:answer!="" and var:comment!="" %} 29 |

Answer:

30 |
32 | {{var:answer}} 33 |
34 | {% else %} 35 |

Question ({{var:view}} views):

36 | 37 |
38 | {{var:questiondetail}} 39 |
40 | {% endif %} 41 | 42 | 43 | {% if var:comment!="" %} 44 |
45 |
46 | Add Comment 47 |
48 | 49 |
50 | Vote Up | {{var:vote}} | Vote Down 51 |
52 |
53 | {% elseif var:answer!="" %} 54 | 55 |
56 |
57 | Comment this Answer 58 |
59 | 60 |
61 | Vote Up this Answer | {{var:vote}} | Vote Down this Answer 62 |
63 |
64 | 65 | 66 | {% else %} 67 |
68 |
69 | Answer | Comment 70 |
71 | 72 |
73 | Vote Up | {{var:vote}} | Vote Down 74 |
75 |
76 |
77 | {% endif %} 78 | 79 | 80 |
81 |
82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /samples/white_label/test.php: -------------------------------------------------------------------------------- 1 | "POST", 15 | "FromEmail" => $sender, 16 | "FromName" => "Mailjet Pilot", 17 | "Subject" => '{{var:firstname}}, {% if var:step == "registration" %}Thank you for registering{% elseif var:step == "confirmation" %}Please confirm your email{% elseif var:step == "3day" %}3 days already with us!!!{% elseif var:step == "badge" %}A new badge for you{% else %}Small message from us{% endif %}', 18 | "Html-part" => $html_part, 19 | "MJ-TemplateLanguage" => true, 20 | "Vars" => array ( 21 | "firstname" => "", 22 | "step" => "", 23 | "badge" => "", 24 | "level" => 0, 25 | "messagecontent" => "" 26 | ), 27 | "Recipients" => array( 28 | array( 29 | "Email" => $recipients[0], 30 | "Vars" => array( 31 | "firstname" => "Emmanuel1", 32 | "header" => "http://oi08.mjt.lu/img/oi08/b/14ky5/vs3r.png", 33 | "header_color" => "#ffffff", 34 | "bg_color" => "#d6dde5", 35 | "namesupport" => "Your Nukleus Support", 36 | "twitter" => "igra_fan", 37 | "base_url" => "http://www.mailjet.com", 38 | "request_number" => 11111 39 | ) 40 | ), 41 | array( 42 | "Email" => $recipients[1], 43 | "Vars" => array( 44 | "firstname" => "Emmanuel2", 45 | "header" => "https://raw.githubusercontent.com/eboisgon/mailjet-template-api-samples/master/white_label/img/mailjet.jpg", 46 | "header_color" => "#2f323b", 47 | "bg_color" => "#d6dde5", 48 | "namesupport" => "Mailjet", 49 | "twitter" => "mailjet", 50 | "base_url" => "http://www.mailjet.com", 51 | "request_number" => 11111 52 | ) 53 | ), 54 | array( 55 | "Email" => $recipients[2], 56 | "Vars" => array( 57 | "firstname" => "Emmanuel3", 58 | "header" => "https://raw.githubusercontent.com/eboisgon/mailjet-template-api-samples/master/white_label/img/mailjet.jpg", 59 | "header_color" => "#2f323b", 60 | "bg_color" => "#FFCC4D", 61 | "namesupport" => "Mailjet Developers", 62 | "twitter" => "mailjetdev", 63 | "base_url" => "http://dev.mailjet.com", 64 | "request_number" => 11111 65 | ) 66 | ) 67 | 68 | ) 69 | ); 70 | 71 | $response = $mj->post(Resources::$Email, ['body' => $params]); 72 | 73 | var_dump($response->request->getUrl()); 74 | 75 | var_dump($response->request->getFilters()); 76 | 77 | var_dump($response->request->getBody()); 78 | 79 | $response->success() && var_dump($response->getData()); 80 | 81 | ?> 82 | 83 | -------------------------------------------------------------------------------- /samples/question_answer/test.php: -------------------------------------------------------------------------------- 1 | "POST", 15 | "FromEmail" => $sender, 16 | "FromName" => "Mailjet Pilot", 17 | "Subject" => '{{var:author}}{% if var:comment!="" and var:answer=="" %} commented on {% elseif var:comment!="" %} commented an answer on {% elseif var:answer!="" %} answered {% else %} asked {% endif %} {{var:question}}', 18 | "MJ-TemplateLanguage" => true, 19 | "Html-part" => $html_part, 20 | "Vars" => array( 21 | "author" => "Emmanuel", 22 | "url" => "http://www.example.com", 23 | "question" => "How to create a notification system for questions?", 24 | "questiondetail" => "I would like to do a nice notification system", 25 | "answer" => "Use this example", 26 | "comment" => "Just commenting for fun", 27 | "view" => 1, 28 | "vote" => 2 29 | ), 30 | "Recipients" => array( 31 | array( 32 | "Email" => $recipients[0], 33 | "Vars" => array( 34 | "author" => "Emmanuel", 35 | "url" => "http://www.example.com", 36 | "question" => "How to create a notification system for questions?", 37 | "questiondetail" => "I would like to do a nice notification system", 38 | "answer" => "", 39 | "comment" => "", 40 | "view" => 1, 41 | "vote" => 2 42 | ) 43 | ), 44 | array( 45 | "Email" => $recipients[1], 46 | "Vars" => array( 47 | "author" => "Emmanuel", 48 | "url" => "http://www.example.com", 49 | "question" => "How to create a notification system for questions?", 50 | "questiondetail" => "I would like to do a nice notification system", 51 | "answer" => "Use this example", 52 | "comment" => "", 53 | "view" => 1, 54 | "vote" => 2 55 | ) 56 | ), 57 | array( 58 | "Email" => $recipients[2], 59 | "Vars" => array( 60 | "author" => "Emmanuel", 61 | "url" => "http://www.example.com", 62 | "question" => "How to create a notification system for questions?", 63 | "questiondetail" => "I would like to do a nice notification system", 64 | "answer" => "", 65 | "comment" => "Just commenting for fun", 66 | "view" => 1, 67 | "vote" => 2 68 | ) 69 | ), 70 | array( 71 | "Email" => $recipients[3], 72 | "Vars" => array( 73 | "author" => "Emmanuel", 74 | "url" => "http://www.example.com", 75 | "question" => "How to create a notification system for questions? dsf dsf dsfdsaf dsfds dfdasfd", 76 | "questiondetail" => "I would like to do a nice notification system fgfdfs df dsf dff fdsaf fdsfdsa", 77 | "answer" => "Use this example", 78 | "comment" => "Just commenting for fun", 79 | "view" => 1, 80 | "vote" => 2 81 | ) 82 | ), 83 | 84 | ) 85 | ); 86 | 87 | $response = $mj->post(Resources::$Email, ['body' => $params]); 88 | 89 | var_dump($response->request->getUrl()); 90 | 91 | var_dump($response->request->getFilters()); 92 | 93 | var_dump($response->request->getBody()); 94 | 95 | $response->success() && var_dump($response->getData()); 96 | 97 | ?> 98 | 99 | -------------------------------------------------------------------------------- /samples/ecommerce/README.md: -------------------------------------------------------------------------------- 1 | #Ecommerce 2 | 3 | This example can be used to handle the different steps of a online purchase : 4 | 5 | - Confirmation of purchase 6 | - Confirmation of shipping 7 | - Unavailability notice 8 | - Refund confirmation 9 | - Feedback email (sent after delivery) 10 | 11 | In the test.php script, you can see that the subject also rely on templating language: 12 | 13 | ``` 14 | {{ var:firstname }}, {% if var:step == "confirmorder" %}Confirmation of purchase: {{ var:productname:"" }}{% elseif var:step == "confirmshipping" %}Your {{ var:productname:"" }} is coming your way{% elseif var:step == "unavailable" %}Your purchase is unavailable: {{ var:productname:"" }}{% elseif var:step == "refund" %}Refund of your purchase {{ var:productname:"" }}{% elseif var:step == "feedback" %}Please give us some feedback about your {{ var:productname:"" }}{% endif %} 15 | ``` 16 | 17 | 18 | 19 | ## Result 20 | 21 | ###Vars 22 | ``` 23 | "Vars" => array( 24 | "firstname" => "Emmanuel1", 25 | "step" => "confirmorder", 26 | "productname" => "Camera", 27 | "productdescription" => "Description", 28 | "productimg" => "https://raw.githubusercontent.com/eboisgon/mailjet-template-api-samples/master/ecommerce/img/photo1.jpg", 29 | "order_id" => "1111111", 30 | "delivery" => "2 EUR", 31 | "total_price" => "30 EUR" 32 | ) 33 | ``` 34 | ###Result 35 | 36 | ![Example 1](media/ecommerce1.png) 37 | 38 | 39 | ###Vars 40 | ``` 41 | "Vars" => array( 42 | "firstname" => "Emmanuel2", 43 | "step" => "confirmshipping", 44 | "productname" => "Shoes", 45 | "productdescription" => "Description", 46 | "productimg" => "https://raw.githubusercontent.com/eboisgon/mailjet-template-api-samples/master/ecommerce/img/photo2.jpg", 47 | "deliverytrackurl" => "#", 48 | "delivery" => "UPS", 49 | ) 50 | ``` 51 | ###Result 52 | 53 | ![Example 2](media/ecommerce2.png) 54 | 55 | 56 | ###Vars 57 | ``` 58 | "Vars" => array( 59 | "firstname" => "Emmanuel3", 60 | "step" => "unavailable", 61 | "reasonunavailable" => "Restocking", 62 | "productname" => "rubik's cube", 63 | "productdescription" => "Description", 64 | "productimg" => "https://raw.githubusercontent.com/eboisgon/mailjet-template-api-samples/master/ecommerce/img/photo3.jpg", 65 | ) 66 | ``` 67 | ###Result 68 | 69 | ![Example 3](media/ecommerce3.png) 70 | 71 | 72 | ###Vars 73 | ``` 74 | "Vars" => array( 75 | "firstname" => "Emmanuel4", 76 | "step" => "refund", 77 | "productname" => "Camera", 78 | "productdescription" => "Description", 79 | "productimg" => "https://raw.githubusercontent.com/eboisgon/mailjet-template-api-samples/master/ecommerce/img/photo1.jpg", 80 | "order_id" => "1111111", 81 | "delivery" => "2 EUR", 82 | "total_price" => "30 EUR" 83 | ) 84 | 85 | ``` 86 | ###Result 87 | 88 | ![Example 4](media/ecommerce4.png) 89 | 90 | ###Vars 91 | ``` 92 | "Vars" => array( 93 | "firstname" => "Emmanuel5", 94 | "step" => "feedback", 95 | "productname" => "Shoes", 96 | "productdescription" => "Description", 97 | "productimg" => "https://raw.githubusercontent.com/eboisgon/mailjet-template-api-samples/master/ecommerce/img/photo2.jpg", 98 | ) 99 | 100 | ``` 101 | ###Result 102 | 103 | ![Example 5](media/ecommerce5.png) 104 | -------------------------------------------------------------------------------- /samples/question_answer/README.md: -------------------------------------------------------------------------------- 1 | #QUESTION, ANSWER and COMMENT notification (Quandora like) 2 | 3 | This example can be used for notification of new question, new comment on a question, new comment on an answer and new answer. 4 | 5 | In the test.php script, you can see that the subject also rely on templating language: 6 | 7 | ``` 8 | {{var:author}}{% if var:comment!="" and var:answer=="" %} commented on {% elseif var:comment!="" %} commented an answer on {% elseif var:answer!="" %} answered {% else %} asked {% endif %} {{var:question}} 9 | ``` 10 | 11 | ## Vars 12 | 13 | ``` 14 | "Vars" => array( 15 | "author" => "Emmanuel", 16 | "url" => "http://www.example.com", 17 | "question" => "How to create a notification system for questions?", 18 | "questiondetail" => "I would like to do a nice notification system", 19 | "answer" => "", 20 | "comment" => "", 21 | "view" => 1, 22 | "vote" => 2 23 | ) 24 | 25 | ``` 26 | 27 | ## Template skeleton 28 | 29 | ``` 30 | 31 | {% if var:comment!="" and var:answer=="" %} commented on {% elseif var:comment!="" %} commented an answer on {% elseif var:answer!="" %} answered {% else %} asked {% endif %} 32 | 33 | {% if var:comment=="" and var:answer!="" %} 34 | 35 | {% endif %} 36 | 37 | {% if var:comment!="" %} 38 | 39 | {% endif %} 40 | 41 | {% if var:answer!="" and var:comment!="" %} 42 | 43 | {% else %} 44 | 45 | {% endif %} 46 | 47 | 48 | {% if var:comment!="" %} 49 | 50 | {% elseif var:answer!="" %} 51 | 52 | {% else %} 53 | 54 | {% endif %} 55 | 56 | ``` 57 | 58 | 59 | ## Result 60 | 61 | ###Vars 62 | ``` 63 | "Vars" => array( 64 | "author" => "Emmanuel", 65 | "url" => "http://www.example.com", 66 | "question" => "How to create a notification system for questions?", 67 | "questiondetail" => "I would like to do a nice notification system", 68 | "answer" => "", 69 | "comment" => "", 70 | "view" => 1, 71 | "vote" => 2 72 | ) 73 | ``` 74 | ###Result 75 | 76 | ![Example 1](media/question1.png) 77 | 78 | 79 | ###Vars 80 | ``` 81 | "Vars" => array( 82 | "author" => "Emmanuel", 83 | "url" => "http://www.example.com", 84 | "question" => "How to create a notification system for questions?", 85 | "questiondetail" => "I would like t", 86 | "answer" => "Use this example", 87 | "comment" => "Just commenting for fun", 88 | "view" => 1, 89 | "vote" => 2 90 | ) 91 | ``` 92 | ###Result 93 | 94 | ![Example 2](media/question2.png) 95 | 96 | 97 | ###Vars 98 | ``` 99 | "Vars" => array( 100 | "author" => "Emmanuel", 101 | "url" => "http://www.example.com", 102 | "question" => "How to create a notification system for questions?", 103 | "questiondetail" => "I would like to do a nice notification system", 104 | "answer" => "", 105 | "comment" => "Just commenting for fun", 106 | "view" => 1, 107 | "vote" => 2 108 | ) 109 | ``` 110 | ###Result 111 | 112 | ![Example 3](media/question3.png) 113 | 114 | 115 | ###Vars 116 | ``` 117 | "Vars" => array( 118 | "author" => "Emmanuel", 119 | "url" => "http://www.example.com", 120 | "question" => "How to create a notification system for questions?", 121 | "questiondetail" => "I would like to do a nice notification system", 122 | "answer" => "Use this example", 123 | "comment" => "", 124 | "view" => 1, 125 | "vote" => 2 126 | ) 127 | 128 | ``` 129 | ###Result 130 | 131 | ![Example 4](media/question4.png) 132 | -------------------------------------------------------------------------------- /tutorials/README.md: -------------------------------------------------------------------------------- 1 | # Templating language for everyone, from beginners to power users 2 | 3 | We are developers, like you. And what we hate above all in coding is to repeat ourselves. [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) isn’t just a concept for us, and we strongly recommend code reuse... So when it comes to writing email templates, we want to provide our users with the best tools to produce content in the most efficient way possible. 4 | 5 | To speed up the development of responsive emails, you may already know [MJML](https://mjml.io?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial), the open-source email framework we’ve created. If you’re not familiar with it, [go check it out right away](https://mjml.io?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial). You can thank us later. 6 | 7 | But even if MJML can help you save quite a lot of time and ease the process, you’ll probably want more. We hear you. 8 | 9 | 10 | ## MJML and templating language, a superhero duo 11 | 12 | Today, flexibility and personalization are a must-have in the email industry. Transactional emails imply more and more complex business logic, and one can often struggle trying to juggle a lot of different templates, when they could just have one personalized email that adapts to several use cases. Having a separate template for men and another one for women, or creating specific campaigns to recommend different things based on your customer's previous purchases is not viable. 13 | 14 | It is in this kind of situations that a templating language comes in handy. OK, let’s be a bit naive and accept that you could write your own. But to be able to implement a tokenizer and a grammar, you need to have a good knowledge in the field and, at the end of the day, you might just be reinventing the wheel when you could have been focusing on your core business instead... You could instead use nice libraries such as [Handlebars](http://handlebarsjs.com/), [Jinja](http://jinja.pocoo.org/) or [Twig](http://twig.sensiolabs.org/), but then you’ll still need to write or host a dedicated service to handle the templating processing. 15 | 16 | 17 | ## OK. Too hard. So how can I master this, once and for all? 18 | 19 | We have the solution. Because at Mailjet we know the value of a fully integrated templating language, we created [our own](https://dev.mailjet.com/guides/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#transactional-templating), following the good patterns of the libraries mentioned previously, and with our [Transactional Send API](https://dev.mailjet.com/guides/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#send-transactional-email) in mind. Our idea: one template to rule them all, just with a single API call. 20 | 21 | ## Pretty awesome, we know. 22 | 23 | So, let’s recap: MJML for building responsive HTML emails without effort, plus a templating language to bring them to life with conditional blocks and variables. This combo can change your life as a developer. But, enough words, you’ll definitely want some action. 24 | 25 | In this repository, you'll find four tutorials that will explain you step by step how to solve very common issues in template creation. 26 | 27 | ## Let's start! 28 | 29 | Ready to start? Jump on our tutorials: 30 | * How to create an e-receipt email template 31 | * How to create a welcome email template 32 | * How to create an abandoned cart email template 33 | * How to create a personalized digest email template 34 | -------------------------------------------------------------------------------- /tutorials/email_sender/v0.1/README.md: -------------------------------------------------------------------------------- 1 | # Mailjet templating language console tool 2 | 3 | This email sender tool is to be used in your console. 4 | 5 | It has been built to help you test Mailjet's templating language and MJML. 6 | 7 | ## Prerequisites 8 | 9 | First of all, you will need [Node.js](https://nodejs.org/en/download/) (this tool has been tested for versions >= v7.2.1). 10 | 11 | You should have also a [Mailjet](https://www.mailjet.com/) account and a [valid API key](https://app.mailjet.com/support/what-are-the-api-key-and-secret-keys-how-should-i-use-them,109.htm). If you're not a client yet, you can [subscribe for a free account](https://app.mailjet.com/signup) (and send immediately up to 6000 free emails a month!). __Warning:__ don't use a disposable email address (gmail, yahoo, etc included), as you'll be likely to be blocked by our anti-spammer policy. 12 | 13 | Finally, you'll need an access to the [MJML API](https://mjml.io/api), actually in [open beta](https://mjml.io/api). 14 | 15 | ## Installation 16 | 17 | Download this tool directly or clone the parent directory. 18 | 19 | To install dependencies, run: `npm install` 20 | 21 | ## Configuration 22 | 23 | This tool uses two sets of API keys (_Send API_ and _MJML API_). You must provide the tool with a `.credentials` file, that contains the following environment variables: 24 | 25 | ```sh 26 | MAILJET_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 27 | MAILJET_API_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 28 | MJML_APPLICATION_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 29 | MJML_SECRET_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 30 | ``` 31 | 32 | ## About your templates 33 | 34 | A template is composed of two files, one for MJML, and the other to declare templating language's variables data. 35 | 36 | These files must be created in a specific directory, matching the following pattern: `./templates/template-name`. 37 | 38 | Your MJML file must be named `index.mjml`. 39 | 40 | Your JSON variables file must be named `variables.json`. 41 | 42 | ## Run the tool 43 | 44 | To run the tool, you can use the `start` script, with your template name as the single argument. For instance: `npm start template-name` 45 | 46 | ## Testing 47 | 48 | If you want to modify this tool, we've provided you with a very succinct test suite (using [chai](chaijs.com) and [mocha](mochajs.org)). Feel free to improve it or write your own. 49 | 50 | To run it, simply hit: `npm run test` 51 | 52 | ## Any questions? 53 | 54 | Contact us via [api@mailjet.com](mailto://api@mailjet.com) or ping us on [Twitter](https://twitter.com/mailjetdev). We'll be glad to answer you and listen to your feedback. 55 | 56 | ## License 57 | 58 | MIT License 59 | 60 | Copyright (c) 2017 Mailjet 61 | 62 | Permission is hereby granted, free of charge, to any person obtaining a copy 63 | of this software and associated documentation files (the "Software"), to deal 64 | in the Software without restriction, including without limitation the rights 65 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 66 | copies of the Software, and to permit persons to whom the Software is 67 | furnished to do so, subject to the following conditions: 68 | 69 | The above copyright notice and this permission notice shall be included in all 70 | copies or substantial portions of the Software. 71 | 72 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 73 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 74 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 75 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 76 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 77 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 78 | SOFTWARE. 79 | -------------------------------------------------------------------------------- /samples/ecommerce/test.php: -------------------------------------------------------------------------------- 1 | "POST", 15 | "FromEmail" => $sender, 16 | "FromName" => "Mailjet Pilot", 17 | "Subject" => '{{ var:firstname }}, {% if var:step == "confirmorder" %}Confirmation of purchase: {{ var:productname:"" }}{% elseif var:step == "confirmshipping" %}Your {{ var:productname:"" }} is coming your way{% elseif var:step == "unavailable" %}Your purchase is unavailable: {{ var:productname:"" }}{% elseif var:step == "refund" %}Refund of your purchase {{ var:productname:"" }}{% elseif var:step == "feedback" %}Please give us some feedback about your {{ var:productname:"" }}{% endif %}', 18 | "Html-part" => $html_part, 19 | "MJ-TemplateLanguage" => true, 20 | "Vars" => array ( 21 | "firstname" => "", 22 | "step" => "", 23 | "badge" => "", 24 | "level" => 0, 25 | "messagecontent" => "" 26 | ), 27 | "Recipients" => array( 28 | array( 29 | "Email" => $recipients[0], 30 | "Vars" => array( 31 | "firstname" => "Emmanuel1", 32 | "step" => "confirmorder", 33 | "productname" => "Camera", 34 | "productdescription" => "Description", 35 | "productimg" => "https://raw.githubusercontent.com/eboisgon/mailjet-template-api-samples/master/ecommerce/img/photo1.jpg", 36 | "order_id" => "1111111", 37 | "delivery" => "2 EUR", 38 | "total_price" => "30 EUR" 39 | ) 40 | ), 41 | array( 42 | "Email" => $recipients[1], 43 | "Vars" => array( 44 | "firstname" => "Emmanuel2", 45 | "step" => "confirmshipping", 46 | "productname" => "Shoes", 47 | "productdescription" => "Description", 48 | "productimg" => "https://raw.githubusercontent.com/eboisgon/mailjet-template-api-samples/master/ecommerce/img/photo2.jpg", 49 | "deliverytrackurl" => "#", 50 | "delivery" => "UPS", 51 | ) 52 | ), 53 | array( 54 | "Email" => $recipients[2], 55 | "Vars" => array( 56 | "firstname" => "Emmanuel3", 57 | "step" => "unavailable", 58 | "reasonunavailable" => "Restocking", 59 | "productname" => "rubik's cube", 60 | "productdescription" => "Description", 61 | "productimg" => "https://raw.githubusercontent.com/eboisgon/mailjet-template-api-samples/master/ecommerce/img/photo3.jpg", 62 | ) 63 | ), 64 | array( 65 | "Email" => $recipients[3], 66 | "Vars" => array( 67 | "firstname" => "Emmanuel4", 68 | "step" => "refund", 69 | "productname" => "Camera", 70 | "productdescription" => "Description", 71 | "productimg" => "https://raw.githubusercontent.com/eboisgon/mailjet-template-api-samples/master/ecommerce/img/photo1.jpg", 72 | "order_id" => "1111111", 73 | "delivery" => "2 EUR", 74 | "total_price" => "30 EUR" 75 | ) 76 | ), 77 | array( 78 | "Email" => $recipients[4], 79 | "Vars" => array( 80 | "firstname" => "Emmanuel5", 81 | "step" => "feedback", 82 | "productname" => "Shoes", 83 | "productdescription" => "Description", 84 | "productimg" => "https://raw.githubusercontent.com/eboisgon/mailjet-template-api-samples/master/ecommerce/img/photo2.jpg", 85 | ) 86 | ) 87 | 88 | ) 89 | ); 90 | 91 | $response = $mj->post(Resources::$Email, ['body' => $params]); 92 | 93 | var_dump($response->request->getUrl()); 94 | 95 | var_dump($response->request->getFilters()); 96 | 97 | var_dump($response->request->getBody()); 98 | 99 | $response->success() && var_dump($response->getData()); 100 | 101 | ?> 102 | 103 | -------------------------------------------------------------------------------- /tutorials/digest/index.mjml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | html, body { background-color: lightgrey; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } 18 | a { color: #333333; } 19 | 20 | table[style='background:#ffffff;border:1px solid transparent;vertical-align:middle;'] { 21 | box-shadow: 0px 2px 4px #ccc; 22 | } 23 | 24 | 25 | 26 | 27 | 28 | 34 | 35 | 36 | 37 | YOU CAN'T MISS THAT! 38 | 39 | 40 | 41 | 42 | 43 | 46 | 47 | 48 | BLOGPOST 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | {% for blogpost in var:blogposts %} 59 | 60 | 65 | 66 | 67 | {{ blogpost.title }} 68 | 69 | 70 | {{ blogpost.content }} 71 | Read more… 72 | 73 | 74 | 75 | 76 | {% endfor %} 77 | 78 | 79 | 80 | 81 | {% if !HasOpenedSince(30) %} 82 | 83 | 86 | 87 | 88 | SALES 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | {% for suggestion in var:suggestions %} 101 | 102 | 103 | 104 | 111 | 112 | 113 | {% endfor %} 114 | 115 | 116 | 117 | {% endif %} 118 | 119 | 120 | 121 | 122 | 123 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | Any question?  162 | clothes-men 163 | 164 |  • Unsubscribe 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | -------------------------------------------------------------------------------- /tutorials/receipt/index.mjml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | html, body { background-color: lightgrey; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } 15 | a { color: #333333; } 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | Hi {{ var:user.name }},
33 | Thanks for your recent order. Please find all the details below.
34 | If you have any questions, feel free to contact us. 35 |
36 |
37 |
38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | Order number: {{ var:order.number }} 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | Billing Address
60 | {{ var:user.address.billing_address.full_name }}
61 | {{ var:user.address.billing_address.address_line_1 }}
62 | {{ var:user.address.billing_address.city }},  63 | {{ var:user.address.billing_address.state }}  64 | {{ var:user.address.billing_address.postal_code }} 65 |
66 |
67 | 68 | 69 | Shipping Address
70 | {{ var:user.address.billing_address.full_name }}
71 | {{ var:user.address.billing_address.address_line_1 }}
72 | {{ var:user.address.billing_address.city }},  73 | {{ var:user.address.billing_address.state }}  74 | {{ var:user.address.billing_address.postal_code }} 75 |
76 |
77 |
78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | {% for item in var:order.items %} 89 | 90 | 91 | 92 | 93 | 101 | 102 | 103 | 104 | 105 | 106 | {{ item.title }}
107 | Size: {{ item.size }}
108 | Quantity: {{ item.quantity }} 109 |
110 |
111 | 112 | 113 | 114 | Price: {{ item.price.currency }}{{ item.price.amount }} 115 | 116 | 117 |
118 |
119 | 120 | {% endfor %} 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | Your estimated delivery date:
135 | {{ var:order.delivery_date }} 136 |
137 |
138 | 139 | 140 | Shipping: {{ var:order.shipping.currency }}{{ var:order.shipping.amount }}
141 | Tax: {{ var:order.total.currency }}{{ Round(var:order.total.amount * var:order.sales_taxes_percentage / 100, 2) }}
142 | Total: {{ var:order.total.currency }}{{ var:order.total.amount }} 143 |
144 | 145 | View Online Receipt 146 | 147 |
148 |
149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | YOU WILL LOVE THAT 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | {% for suggestion in var:suggestions %} 169 | 170 | 171 | 172 | 179 | 180 | 181 | {% endfor %} 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | Any question?  201 | clothes-men 202 |  • 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 |
211 |
212 |
213 | -------------------------------------------------------------------------------- /tutorials/email_sender/v0.1/templates/receipt/index.mjml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | html, body { background-color: lightgrey; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } 15 | a { color: #333333; } 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | Hi {{ var:user.name }},
33 | Thanks for your recent order. Please find all the details below.
34 | If you have any questions, feel free to contact us. 35 |
36 |
37 |
38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | Order number: {{ var:order.number }} 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | Billing Address
60 | {{ var:user.address.billing_address.full_name }}
61 | {{ var:user.address.billing_address.address_line_1 }}
62 | {{ var:user.address.billing_address.city }},  63 | {{ var:user.address.billing_address.state }}  64 | {{ var:user.address.billing_address.postal_code }} 65 |
66 |
67 | 68 | 69 | Shipping Address
70 | {{ var:user.address.billing_address.full_name }}
71 | {{ var:user.address.billing_address.address_line_1 }}
72 | {{ var:user.address.billing_address.city }},  73 | {{ var:user.address.billing_address.state }}  74 | {{ var:user.address.billing_address.postal_code }} 75 |
76 |
77 |
78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | {% for item in var:order.items %} 89 | 90 | 91 | 92 | 93 | 101 | 102 | 103 | 104 | 105 | 106 | {{ item.title }}
107 | Size: {{ item.size }}
108 | Quantity: {{ item.quantity }} 109 |
110 |
111 | 112 | 113 | 114 | Price: {{ item.price.currency }}{{ item.price.amount }} 115 | 116 | 117 |
118 |
119 | 120 | {% endfor %} 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | Your estimated delivery date:
135 | {{ var:order.delivery_date }} 136 |
137 |
138 | 139 | 140 | Shipping: {{ var:order.shipping.currency }}{{ var:order.shipping.amount }}
141 | Tax: {{ var:order.total.currency }}{{ Round(var:order.total.amount * var:order.sales_taxes_percentage / 100, 2) }}
142 | Total: {{ var:order.total.currency }}{{ var:order.total.amount }} 143 |
144 | 145 | View Online Receipt 146 | 147 |
148 |
149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | YOU WILL LOVE THAT 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | {% for suggestion in var:suggestions %} 169 | 170 | 171 | 172 | 179 | 180 | 181 | {% endfor %} 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | Any question?  201 | clothes-men 202 |  • 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 |
211 |
212 |
213 | -------------------------------------------------------------------------------- /tutorials/email_sender/v0.1/templates/welcome/index.mjml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | html, body { background-color: lightgrey; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } 14 | a { color: #333333; } 15 | 16 | td[background="left"] { 17 | padding-left: 30px !important; 18 | padding-right: 8px !important; 19 | } 20 | td[background="right"] { 21 | padding-right: 30px !important; 22 | padding-left: 8px !important; 23 | } 24 | 25 | @media all and (max-width: 480px) { 26 | td[background="left"] { 27 | padding-left: 0 !important; 28 | padding-right: 0 !important; 29 | padding-bottom: 30px !important; 30 | } 31 | td[background="right"] { 32 | padding-right: 0 !important; 33 | padding-left: 0 !important; 34 | padding-bottom: 30px !important; 35 | } 36 | } 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | JACKETS 49 | PANTS 50 | JUMPER 51 | SHIRTS 52 | SHOES 53 | 54 | 55 | 56 | 57 | 58 | 59 |
60 | {% set gender = var:user.gender %} 61 | {% set background-url = "http://bit.ly/mj-tpl-tuto-hero-girl" %} 62 | {% if gender == "male" %} 63 | {% set background-url = "http://bit.ly/mj-tpl-tuto-hero" %} 64 | {% endif %} 65 |
66 |
67 | 73 | 74 | 75 | 82 | HELLO {{ Upper(var:user.name) }}, THANKS FOR JOINING CLOTHES! 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 |

1Discover

111 |

112 | Classy products
113 | for men in tune
114 | with the times 115 |

116 |
117 |
118 | 119 | 120 |

2Shop

121 |

122 | Our new catalog
123 | with 1000+
124 | products and refs 125 |

126 |
127 |
128 | 129 | 130 |

3Follow

131 |

132 | A trend that
133 | will never be
134 | outdated 135 |

136 |
137 |
138 |
139 |
140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | Any question?  190 | clothes-men 191 | 192 |  • Unsubscribe 193 | 194 | 195 | 196 | 197 |
198 |
199 |
200 | -------------------------------------------------------------------------------- /tutorials/abandoned_cart/index.mjml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | html, body { background-color: lightgrey; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } 15 | a { color: #333333; } 16 | 17 | table[style='background:#ffffff;border:1px solid transparent;vertical-align:middle;'] { 18 | box-shadow: 0px 2px 4px #ccc; 19 | } 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 38 | JACKETS 39 | PANTS 40 | JUMPER 41 | SHIRTS 42 | SHOES 43 | 44 | 45 | 46 | 47 | 48 | 54 | 55 | 56 | 57 | 64 | YOU LEFT SOMETHING BEHIND 65 | 66 | 70 | return to your shopping bag 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | {% for item in var:order.items %} 81 | 82 | 83 | 90 | 91 | 92 | {{ item.title }}
93 | Color: {{ item.color }}
94 | Size: {{ item.size }}
95 | Price: {{ item.price.currency }}{{ item.price.amount }} 96 | 97 | 98 | {% endfor %} 99 |
100 | 101 | 102 | 103 | 104 | 105 | 106 | SUBTOTAL:{{ var:order.subtotal.currency }}{{ var:order.subtotal.amount }} 107 | 108 | 109 | 110 | 111 | continue checkout 112 | 113 | 114 | edit cart 115 | 116 |
117 |
118 |
119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | YOU WILL LOVE THAT 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | {% for suggestion in var:suggestions %} 139 | 140 | 141 | 142 | 149 | 150 | 151 | {% endfor %} 152 | 153 | 154 | 155 | 156 | 157 | 158 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | Any question?  197 | clothes-men 198 | 199 |  • Unsubscribe 200 | 201 | 202 | 203 | 204 |
205 |
206 |
207 | -------------------------------------------------------------------------------- /tutorials/welcome/index.mjml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | html, body { background-color: lightgrey; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } 14 | a { color: #333333; } 15 | 16 | td[background="left"] { 17 | padding-left: 30px !important; 18 | padding-right: 8px !important; 19 | } 20 | td[background="right"] { 21 | padding-right: 30px !important; 22 | padding-left: 8px !important; 23 | } 24 | 25 | @media all and (max-width: 480px) { 26 | td[background="left"] { 27 | padding-left: 0 !important; 28 | padding-right: 0 !important; 29 | padding-bottom: 30px !important; 30 | } 31 | td[background="right"] { 32 | padding-right: 0 !important; 33 | padding-left: 0 !important; 34 | padding-bottom: 30px !important; 35 | } 36 | } 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 55 | JACKETS 56 | PANTS 57 | JUMPER 58 | SHIRTS 59 | SHOES 60 | 61 | 62 | 63 | 64 | 65 | 66 |
67 | {% set gender = var:user.gender %} 68 | {% set background-url = "http://bit.ly/mj-tpl-tuto-hero-girl" %} 69 | {% if gender == "male" %} 70 | {% set background-url = "http://bit.ly/mj-tpl-tuto-hero" %} 71 | {% endif %} 72 |
73 |
74 | 80 | 81 | 82 | 89 | HELLO {{ Upper(var:user.name) }}, THANKS FOR JOINING CLOTHES! 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 |

1Discover

118 |

119 | Classy products
120 | for men in tune
121 | with the times 122 |

123 |
124 |
125 | 126 | 127 |

2Shop

128 |

129 | Our new catalog
130 | with 1000+
131 | products and refs 132 |

133 |
134 |
135 | 136 | 137 |

3Follow

138 |

139 | A trend that
140 | will never be
141 | outdated 142 |

143 |
144 |
145 |
146 |
147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | Any question?  197 | clothes-men 198 | 199 |  • Unsubscribe 200 | 201 | 202 | 203 | 204 |
205 |
206 |
207 | -------------------------------------------------------------------------------- /tutorials/email_sender/v0.1/templates/abandoned_cart/index.mjml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | html, body { background-color: lightgrey; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } 16 | a { color: #333333; } 17 | 18 | table[style='background:#ffffff;border:1px solid transparent;vertical-align:middle;'] { 19 | box-shadow: 0px 2px 4px #ccc; 20 | } 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | JACKETS 33 | PANTS 34 | JUMPER 35 | SHIRTS 36 | SHOES 37 | 38 | 39 | 40 | 41 | 42 | 48 | 49 | 50 | 57 | YOU LEFT SOMETHING BEHIND 58 | 59 | 64 | return to your shopping bag 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | {% for item in var:order.items %} 75 | 76 | 77 | 84 | 85 | 86 | {{ item.title }}
87 | Color: {{ item.color }}
88 | Size: {{ item.size }}
89 | Price: {{ item.price.currency }}{{ item.price.amount }} 90 | 91 | 92 | {% endfor %} 93 |
94 | 95 | 96 | 97 | 98 | 99 | 100 | SUBTOTAL:{{ var:order.subtotal.currency }}{{ var:order.subtotal.amount }} 101 | 102 | 103 | 104 | continue checkout 105 | 106 | 107 | edit cart 108 | 109 |
110 |
111 |
112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | YOU WILL LOVE THAT 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | {% for suggestion in var:suggestions %} 132 | 133 | 134 | 135 | 142 | 143 | 144 | {% endfor %} 145 | 146 | 147 | 148 | 149 | 150 | 151 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | Any question?  190 | clothes-men 191 | 192 |  • Unsubscribe 193 | 194 | 195 | 196 | 197 |
198 |
199 |
200 | -------------------------------------------------------------------------------- /tutorials/digest/README.md: -------------------------------------------------------------------------------- 1 | _Welcome to our templating language and MJML tutorials series. You can find all the tutorials [here](../README.md#lets-start-)_. 2 | # How to create an digest email template 3 | 4 | A digest email is a summary sent on a regular basis (daily or weekly, for instance). These emails convey information in a “digestible” way, mimicking paper publications such as the old popular Reader’s Digest.This format is fast and convenient to read and, therefore, very well received by users.
5 | In this tutorial, leveraging the power of our [templating language](http://dev.mailjet.com/template-language/reference/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial), we will show you how to create a customized digest email from a single template. 6 | 7 | ## Table of Contents 8 | 9 | 23 | 24 | 25 | ## Prerequisites 26 | 27 | Obviously, you should have a [Mailjet](https://www.mailjet.com/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial) account. If you're not a client yet, you can [subscribe for a free account](https://app.mailjet.com/signup?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial) (and send immediately up to 6,000 free emails a month!). 28 | 29 | Some basic knowledge about [MJML](https://mjml.io/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial) is a plus, but isn't mandatory. MJML is an open source markup language making responsive email easy: you can catch its self-explanatory syntax based on rows (``) and columns (``) in a minute. If you prefer to code your email in HTML, we provide you with a ready-to-use `index.html` file that you can find at the root of this repository.You could also play with the code using the  Try it live links below the code snippets. 30 | 31 | If you're a [MJML API](https://mjml.io/api?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial) user (if not, join us, it's currently in [open beta](https://mjml.io/api?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial)), you'll also be able to use our email sender tool we built especially for this tutorial. Go check the tool's [README](../email_sender/v0.1/) for more informations. 32 | 33 |
34 | 35 | 🔝 36 | 37 |
38 | 39 | ## What will you achieve? 40 | 41 | The well-known men clothing shop _clothes-men.mailjet.com_ has just hired you to create their new digest email template. 42 | 43 | Their brief: you have to create a template that mainly displays... 44 | 45 | * a catchy hero to grab their customers' attention 46 | * a list of blogposts curated for a specific user 47 | * an optional sales section that is displayed if the user hasn't opened a marketing campaign in the last 30 days 48 | 49 | They provide you with a `variables.json` file, containing some mockup data. 50 | 51 | Their designer, who has hosted all the assets online, has just sent you the final design: 52 | 53 | 54 | 55 | Enough theory, it's time to write some code. 56 | 57 |
58 | 59 | 🔝 60 | 61 |
62 | 63 | ## Time to code! 64 | 65 | ### We need a hero! 66 | 67 | When their clients open the welcome emails, _clothes-men.mailjet.com_ wants to catch their attention immediately. A hero is a nice way to display catchy text and image. Let's see how we could implement it. 68 | 69 | 70 | 71 | MJML provides us with an interactive component, [``](https://mjml.io/documentation/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#transactional-templating#mjml-hero) that will do the job for us. We just need to set some `background-*` attributes, then add some content and voilà! Could it be simpler? 72 | 73 | ```XML 74 | 75 | 81 | 82 | 83 | 84 | YOU CAN'T MISS THAT! 85 | 86 | 87 | 88 | ``` 89 |  Try it live 90 | 91 |
92 | 93 | 🔝 94 | 95 |
96 | 97 | ### The perfect content handcrafted just for you 98 | 99 | What would be a digest without content? But cool content isn't enough. It has to be content specially curated for each user. They have to feel unique. _clothes-men.mailjet.com_ handles the backend algorithms that provide you with this content, but relies on you to build the customization logic in your template. Here's the data in JSON format as you can find it in `variables.json`: 100 | 101 | ```JSON 102 | "blogposts": [ 103 | { 104 | "title": "URBAN FASHION", 105 | "content": "It’s quite clear that the phenomenon of urban style is here for decades. Just one quick pass during New York Fashion Week, and you’ll witnesses hoardes of style-setters getting snapped by photographers. But what is really urban style?", 106 | "image_URL": "https://s30.postimg.org/b8xytfuo1/main1.png" 107 | }, 108 | { 109 | "title": "WEAR YOUR STYLE", 110 | "content": "Mornings are the worst. Is there something more annoying than hitting the snooze button again and again, only to be forced to run all around trying to find the perfect clothes in a hurry. And that's it, you’re late.", 111 | "image_URL": "https://s30.postimg.org/iq768nk75/main2.png" 112 | }, 113 | { 114 | "title": "DON'T WAIT", 115 | "content": "Our fashion expert Nick Cage, left us with some very wise words yesterday that kept me thinking throughout the day today. He said \"don't wait for opportunities, create them\" and I was once again reminded that the power is all in me.", 116 | "image_URL": "https://s30.postimg.org/utchw7v9d/main3.png" 117 | } 118 | ] 119 | ``` 120 | 121 | To exploit this array of objects, Mailjet templating language enables you use [loops](http://dev.mailjet.com/template-language/reference/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#transactional-templating#loop-statements). and [variables](http://dev.mailjet.com/template-language/reference/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#transactional-templating#variables). 122 | 123 | In the snippet below, let's try to spot loops and variables. 124 | 125 | ```XML 126 | 127 | 128 | {% for blogpost in var:blogposts %} 129 | 130 | 135 | 136 | 137 | {{ blogpost.title }} 138 | 139 | 140 | {{ blogpost.content }} 141 | Read more… 142 | 143 | 144 | 145 | 146 | {% endfor %} 147 | 148 | ``` 149 | 150 | You've seen it! The loop iterates over the `blogposts` array and creates each time a new variable named `blogpost`. 151 | 152 | The code contained between the `{% for... %}` and `{% endfor %}` is then repeated for each element of the array. And you can access the properties using the `{{ variable.property }}` syntax. 153 | 154 | Note that, to use templating language [`for` loops](http://dev.mailjet.com/template-language/reference/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#transactional-templating#loop-statements) with MJML, __you have to wrap your instructions in [``](https://mjml.io/documentation/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#transactional-templating#mjml-raw) tags__ so MJML doesn't remove them when transpiling to HTML. 155 | 156 | 157 | The result, three sections, top down, displaying a cool image as a background, plus a catchy title and summary to make them feel like to click on the link! 158 | 159 | 160 | 161 |  Try it live 162 | 163 |
164 | 165 | 🔝 166 | 167 |
168 | 169 | ### Sales! (Because we really want you to buy these things) 170 | 171 | The last marketing campaign of _clothes-men.mailjet.com_ was quite a success with an open rate up to 50%. But, as they do know that [transactional messages are opened from 2 to 5 times more than marketing email](https://www.mailjet.com/blog/transactional-emails/how-to-take-transactional-email-to-the-next-level-with-our-transactional-suite), they want to benefit from this situation and try to sell their products to the other 50% without annoying the one who already opened the campaign. 172 | 173 | 174 | 175 | Mailjet's templating language comes to the rescue with [conditional statements](https://dev.mailjet.com/template-language/reference/#conditional-statements) and [built-in functions](http://dev.mailjet.com/template-language/reference/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#transactional-templating#functions). The `HasOpenedSince(number_of_days)` function especially comes in handy for our matter. If the user hasn't opened any marketing campaign for the last 30 days, the piece of code contained between `{% if ... %}` and `{% endif %}` will be displayed. A good chance to trigger more sells, while the aficionados won't feel being spammed. Isn't it a win-win situation? 😎 176 | 177 | ```XML 178 | 179 | 180 | {% if !HasOpenedSince(30) %} 181 | 182 | 185 | 186 | 187 | SALES 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | {% for suggestion in var:suggestions %} 200 | 201 | 202 | 203 | 210 | 211 | 212 | {% endfor %} 213 | 214 | 215 | 216 | {% endif %} 217 | 218 | ``` 219 | 220 |  Try it live 221 | 222 |
223 | 224 | 🔝 225 | 226 |
227 | 228 | 229 | ### Facebook, Instagram, Twitter and consorts... 230 | 231 | We've already covered that part in our previous tutorials. Want to discover how to implement this section? Go [this way](../welcome/#the-social-network). 232 | 233 | 234 | ## Conclusion 235 | 236 | Here we are! Now, thanks to your very cool and practical digest email, _clothes-men.mailjet.com_ readers will love reading company's blogposts that look like they've been written for them only. 237 | 238 | We'd love to have your feedback about this tutorial, so ping us on [Twitter](https://twitter.com/mailjetdev) or come and chat on the [MJML slack channel](https://slack.mjml.io/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial)! 239 | 240 | You want to be informed about other tutorials and nice tech articles? Subscribe to our [dev only newsletter](https://dev.mailjet.com/community/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#newsletter) to stay tuned! 241 | 242 |
243 | 244 | 🔝 245 | -------------------------------------------------------------------------------- /tutorials/welcome/README.md: -------------------------------------------------------------------------------- 1 | _Welcome to our templating language and MJML tutorials series. You can find all the tutorials [here](../README.md#lets-start-)_. 2 | 3 | # How to create a welcome email template 4 | 5 | Welcome emails are a powerful way to communicate with your users, because they expect to be greeted when they subscribe to your website. It is then important to welcome they warmly, and, most-of-all, personally. We can see you starting to panic: you can't write a dedicated template for each of them... Don’t freak out! In this tutorial, leveraging the power of our [templating language](http://dev.mailjet.com/template-language/reference/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial), we will show you how to create a customized welcome series from a single template. 6 | 7 | ## Table of Contents 8 | 9 | 23 | 24 | 25 | ## Prerequisites 26 | 27 | Obviously, you should have a [Mailjet](https://www.mailjet.com/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial) account. If you're not a client yet, you can [subscribe for a free account](https://app.mailjet.com/signup?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial) (and send immediately up to 6,000 free emails a month!). 28 | 29 | Some basic knowledge about [MJML](https://mjml.io/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial) is a plus, but isn't mandatory. MJML is an open source markup language making responsive email easy: you can catch its self-explanatory syntax based on rows (``) and columns (``) in a minute. If you prefer to code your email in HTML, we provide you with a ready-to-use `index.html` file that you can find at the root of this repository.You could also play with the code using the  Try it live links below the code snippets. 30 | 31 | If you're a [MJML API](https://mjml.io/api?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial) user (if not, join us, it's currently in [open beta](https://mjml.io/api?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial)), you'll also be able to use our email sender tool we built especially for this tutorial. Go check the tool's [README](../email_sender/v0.1/) for more informations. 32 | 33 |
34 | 35 | 🔝 36 | 37 |
38 | 39 | ## What will you achieve? 40 | 41 | The well-known men clothing shop _clothes-men.mailjet.com_ has just hired you to create their new welcome template email. 42 | 43 | Their brief: you have to create a template that mainly displays... 44 | 45 | * the different categories of items a client can be interested in 46 | * a personalized hero, based on the gender of the client 47 | * the company social accounts links to engage their audience 48 | 49 | They provide you with a `variables.json` file, containing some mockup data. 50 | 51 | Their designer, who has hosted all the assets online, has just sent you the final design: 52 | 53 | 54 | 55 | Enough theory, it's time to write some code. 56 | 57 |
58 | 59 | 🔝 60 | 61 |
62 | 63 | ## Time to code! 64 | 65 | ### Starting with a simple header 66 | 67 | Let's implement the header. It is composed of the company logo and a navigation bar with links that lead to the website categories. 68 | 69 | 70 | 71 | As you may notice in the code below, the main container is not a `` but a [``](https://mjml.io/documentation/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#mjml-navbar). Indeed, even if writing a template is a child's play with MJML, we can still ease this flow leveraging pre-made interactive components. Moreover, this component has been thought to be mobile-first, [behaving like a burger menu on compatible email clients](https://mjml.io/documentation/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#mjml-navbar)! 72 | 73 | This [``](https://mjml.io/documentation/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#mjml-navbar) is composed of two [``](https://mjml.io/documentation/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#mjml-column). 74 | 75 | The first one contains a [``](https://mjml.io/documentation/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#mjml-image) that displays the logo. 76 | 77 | The second [``](https://mjml.io/documentation/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#mjml-column) hosts a `` component that will create your links based on a list of `` children. Way cleaner than a forest of `` and ``, right? A little of style customization with inline CSS attributes and a [``](https://mjml.io/documentation/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#mjml-attributes): 78 | 79 | ```XML 80 | 81 | 82 | 83 | 84 | [...] 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | JACKETS 94 | PANTS 95 | JUMPER 96 | SHIRTS 97 | SHOES 98 | 99 | 100 | 101 | ``` 102 |  Try it live 103 | 104 |
105 | 106 | 🔝 107 | 108 |
109 | 110 | ### I want a hero! 111 | 112 | When their clients open the welcome emails, _clothes-men.mailjet.com_ crew wants them to feel as if they were greeted personally. A hero with a custom image based on the client's gender and greeting him using the client's first name will do the trick. 113 | 114 | 115 | 116 | Mailjet templating language enables you to set and use [variables](http://dev.mailjet.com/template-language/reference/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#transactional-templating#variables) to personalize your template with custom data. 117 | 118 | Here, you're interested in the `user.name` and `user.gender` properties, whose value are `Matthew` and `male` for this example respectively. 119 | 120 | Let's set a custom `background-url` variable whose value is the hero image URL. By default, we set this value to the `hero-girl.png` URL, but if the `user.gender` value is `male`, then we set this value to `hero.png` URL. 121 | 122 |
123 | 124 | ```XML 125 | 126 | 127 |
128 | {% set gender = var:user.gender %} 129 | {% set background-url = "http://bit.ly/mj-tpl-tuto-hero-girl" %} 130 | {% if gender == "male" %} 131 | {% set background-url = "http://bit.ly/mj-tpl-tuto-hero" %} 132 | {% endif %} 133 |
134 |
135 | ``` 136 | 137 | In the snippet below, look how we use the `background-url` variable we've just set. When the templating language will be rendered, it will display the correct hero image based on the JSON data you'll provide. You wanna try? Test it yourself using our [email sender tool](../email_sender/v0.1/README.md). 138 | 139 | As you can see, we're also using a new built-in interactive component: [``](https://mjml.io/documentation/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#mjml-hero). 140 | 141 | Finally, look at the `Upper` function. As you can imagine, it will __at run time__ transform the case of the `user.name` variable. Look at the [documentation](https://dev.mailjet.com/template-language/reference/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#functions) to discover all the built-in functions you may need! You miss some? [We're open for suggestions. 📩](mailto:api@mailjet.com?subject=%F0%9F%91%8B%20Hey%20Mailjet!%20I%20have%20an%20idea%20of%20a%20new%20templating%20language%20function) 142 | 143 | ```XML 144 | 150 | 151 | 152 | 159 | HELLO {{ Upper(var:user.name) }}, THANKS FOR JOINING CLOTHES! 160 | 161 | 162 | 163 | ``` 164 |  Try it live 165 | 166 |
167 | 168 | 🔝 169 | 170 |
171 | 172 | ### I don't want to buy this! 173 | 174 | Some never wear shirts and prefer hoodies. But `Matthew` loves fancy pairs of shoes. Let's make his wishes come true. 175 | 176 | 177 | 178 | In the `variables.json` file, you'll find this list of categories: 179 | 180 | ```JSON 181 | "categories": { 182 | "top_left": { 183 | "title": "Shoes", 184 | "link": "/shoes", 185 | "image_URL": "http://bit.ly/mj-tpl-tuto-shoes" 186 | }, 187 | "top_right": { 188 | "title": "Jumper", 189 | "link": "/t-shirt", 190 | "image_URL": "http://bit.ly/mj-tpl-lang-tuto-tshirt" 191 | }, 192 | "bottom_left": { 193 | "title": "Shirt", 194 | "link": "/shirt", 195 | "image_URL": "http://bit.ly/mj-tpl-lang-tuto-shirt" 196 | }, 197 | "bottom_right": { 198 | "title": "Accessories", 199 | "link": "/accessories", 200 | "image_URL": "http://bit.ly/mj-tpl-lang-tuto-accessories" 201 | } 202 | } 203 | ``` 204 | 205 | This data has been generated only for `Matthew`. Using our [templating language variables](http://dev.mailjet.com/template-language/reference/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#variables), we can build a 2 x 2 `` grid he can't resist to click on! 206 | 207 |
208 | 209 | ```XML 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | ``` 228 |  Try it live 229 | 230 |
231 | 232 | 🔝 233 | 234 |
235 | 236 | ### The social network 237 | 238 | _clothes-men.mailjet.com_ is active on the social networks and likes to interact with the community. 239 | 240 | 241 | 242 | Today, displaying a list of social networks links with their respective icons is so common that you may feel reinventing the wheel coding always the feature with a bunch of inextricable `
`. MJML comes to your rescue and provide you with another interactive component: [``](https://mjml.io/documentation/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#mjml-social). You can use predefined social networks (Facebook, Twitter, Instagram...) or create your own. Here, we want a custom brown icon for every social network, so we create `my-social_network_name-*` attributes to configure them sharply. 243 | 244 |
245 | 246 | ```XML 247 | 248 | 249 | 250 | 269 | 270 | 271 | ``` 272 |  Try it live 273 | 274 |
275 | 276 | 🔝 277 | 278 |
279 | 280 | ## Conclusion 281 | 282 | And that's it. We do recommend you to have a look to the whole file and tweak it as you wish! You'll thank us later when you shoot welcome emails faster than [Lucky Luke](https://s22.postimg.org/vp9be0x9d/ff5b6f459fa043de0f2b5bfa7e77b8b2.jpg) ;) 283 | 284 | We'd love to have your feedback about this first tutorial, so ping us on [Twitter](https://twitter.com/mailjetdev) or come and chat on the [MJML slack channel](https://slack.mjml.io/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial)! 285 | 286 | You want to be informed about other tutorials and nice tech articles? Subscribe to our [dev only newsletter](https://dev.mailjet.com/community/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#newsletter) to stay tuned! 287 | 288 |
289 | 290 | 🔝 291 | -------------------------------------------------------------------------------- /tutorials/abandoned_cart/README.md: -------------------------------------------------------------------------------- 1 | _Welcome to our templating language and MJML tutorials series. You can find all the tutorials [here](../README.md#lets-start-)_. 2 | 3 | # How to create an abandoned cart email template 4 | 5 | When a customer adds products to their cart but fails to check out, it doesn’t mean the sale is definitively over. Indeed, sending an email is a remarkably effective tactic to reduce your churn rate. Here are some numbers for you: 50% of abandoned cart emails are opened, and more than a third of them trigger clicks to redirect customers to the website. 6 | In this tutorial, leveraging the power of our [templating language](http://dev.mailjet.com/template-language/reference/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial), we will show you how to create a customized abandoned cart email from a single template. 7 | 8 | ## Table of Contents 9 | 10 | 32 | 33 | 34 | ## Prerequisites 35 | 36 | Obviously, you should have a [Mailjet](https://www.mailjet.com/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial) account. If you're not a client yet, you can [subscribe for a free account](https://app.mailjet.com/signup?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial) (and send immediately up to 6,000 free emails a month!). 37 | 38 | Some basic knowledge about [MJML](https://mjml.io/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial) is a plus, but isn't mandatory. MJML is an open source markup language making responsive email easy: you can catch its self-explanatory syntax based on rows (``) and columns (``) in a minute. If you prefer to code your email in HTML, we provide you with a ready-to-use `index.html` file that you can find at the root of this repository.You could also play with the code using the  Try it live links below the code snippets. 39 | 40 | If you're a [MJML API](https://mjml.io/api?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial) user (if not, join us, it's currently in [open beta](https://mjml.io/api?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial)), you'll also be able to use our email sender tool we built especially for this tutorial. Go check the tool's [README](../email_sender/v0.1/) for more informations. 41 | 42 |
43 | 44 | 🔝 45 | 46 |
47 | 48 | ## What will you achieve? 49 | 50 | The well-known men clothing shop _clothes-men.mailjet.com_ has just hired you to create their new abandoned cart email template. 51 | 52 | Their brief: you have to create a template that mainly displays... 53 | 54 | * the items left in the cart 55 | * some new articles the customer may be interested in 56 | 57 | They provide you with a `variables.json` file, containing some mockup data. 58 | 59 | Their designer, who has hosted all the assets online, has just sent you the final design: 60 | 61 | 62 | 63 | Enough theory, it's time to write some code. 64 | 65 |
66 | 67 | 🔝 68 | 69 |
70 | 71 | ## Time to code! 72 | 73 | ### Starting with a simple header 74 | 75 | Let's implement the header. It is composed of the company logo and a navigation bar with links that lead to the website categories. 76 | 77 | 78 | 79 | As you may notice in the code below, the main container is not a `` but a [``](https://mjml.io/documentation/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#mjml-navbar). Indeed, even if writing a template is a child's play with MJML, we can still ease this flow leveraging pre-made interactive components. Moreover, this component has been thought to be mobile-first, [behaving like a burger menu on compatible email clients](https://mjml.io/documentation/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#mjml-navbar)! 80 | 81 | This [``](https://mjml.io/documentation/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#mjml-navbar) is composed of two [``](https://mjml.io/documentation/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#mjml-column). 82 | 83 | The first one contains a [``](https://mjml.io/documentation/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#mjml-image) that displays the logo. 84 | 85 | The second [``](https://mjml.io/documentation/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#mjml-column) hosts a `` component that will create your links based on a list of `` children. Way cleaner than a forest of `` and `
`, right? A little of style customization with inline CSS attributes and a [``](https://mjml.io/documentation/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#mjml-attributes): 86 | 87 | ```XML 88 | 89 | 90 | 91 | 92 | [...] 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 109 | JACKETS 110 | PANTS 111 | JUMPER 112 | SHIRTS 113 | SHOES 114 | 115 | 116 | 117 | ``` 118 |  Try it live 119 | 120 |
121 | 122 | 🔝 123 | 124 |
125 | 126 | ### Sir, we found an abandoned cart. 127 | 128 | When their clients open the abandoned cart emails, _clothes-men.mailjet.com_ crew wants its customers to resume their shopping experience just where they left it. The best way to do it? Using a design very close to the original cart, let's reproduce it in our email with easy to identify CTAs that lead back to _clothes-men.mailjet.com_. As this design is a bit ambitious for an email, we'll have to use some MJML tricks to implement it the best way. 129 | 130 | 131 | 132 | #### You're my hero! 133 | 134 | First, as for our [welcome email template](../welcome), we have to implement a hero, i.e. an image (often inspirational) with some catchy text on it. If MJML provides us with an interactive component to do this job, the specific design forces us to use our imagination here. 135 | 136 | As you can see, we're using two nested [``](https://mjml.io/documentation/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#mjml-section). This is because the MJML API we're using for this tutorial does not support yet the [``](https://mjml.io/documentation/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#mjml-wrapper) component. If you're parsing your MJML code yourself, feel free to [play with it!](https://mjml.io/try-it-live/components/wrapper?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial) 137 | 138 | We're using our image as a background image, filling the `background-url` attribute. Then, in our first [``](https://mjml.io/documentation/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#mjml-section), we use two [``](https://mjml.io/documentation/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#mjml-text) to display our catchy sentences. 139 | 140 | ```XML 141 | 142 | 148 | 149 | 150 | 151 | 158 | YOU LEFT SOMETHING BEHIND 159 | 160 | 164 | return to your shopping bag 165 | 166 | 167 | 168 | 169 | 170 | ... 171 | ``` 172 | 173 |  Try it live 174 | 175 |
176 | 177 | 🔝 178 | 179 |
180 | 181 | #### That's my cart! 182 | 183 | Let's focus now on the section section. It's a white card containing the cart itself plus the total and two buttons. 184 | 185 | The cart is a list of items, whose data can be found in the `variables.json` file: 186 | 187 | ```JSON 188 | { 189 | "items": [ 190 | { 191 | "title": "Brown shoes", 192 | "image_URL": "https://s13.postimg.org/r3otqmynn/shoes.png", 193 | "price": { 194 | "currency": "$", 195 | "separator": ".", 196 | "amount": 79.99 197 | }, 198 | "size": "9.5", 199 | "color": "Brown" 200 | }, 201 | { 202 | "title": "Blue T-shirt", 203 | "image_URL": "https://s13.postimg.org/onn0csgkz/t_shirt.png", 204 | "price": { 205 | "currency": "$", 206 | "separator": ".", 207 | "amount": 29.99 208 | }, 209 | "size": "S", 210 | "color": "Blue" 211 | }, 212 | { 213 | "title": "Pale blue shirt", 214 | "image_URL": "https://s13.postimg.org/shgglxxwz/shirt.png", 215 | "price": { 216 | "currency": "$", 217 | "amount": 24.99 218 | }, 219 | "size": "S", 220 | "color": "Blue" 221 | }] 222 | } 223 | ``` 224 | 225 | Using Mailjet's templating language [variables](http://dev.mailjet.com/template-language/reference/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#variables), we can use this data and display it in our emails using the following pattern: `{{ var:property_key:default_value }}`. 226 | 227 | Moreover, as this data is an array source, we can browse it to access each inner object using templating language `for` loops. 228 | 229 | Start your `for` loops with a `{% for single_element in array_variable %}` statement and end it with a `{% endfor %}` statement. Within the loop, a new variable `single_element` is created and updated for each iteration, ready to be used. 230 | 231 | See in the snippet below how we repeat the `
` rows for every item and use its data in variables. 232 | 233 | ```XML 234 | 235 | 236 | 237 | 238 | 239 | 240 | {% for item in var:order.items %} 241 | 242 | 251 | 257 | 258 | {% endfor %} 259 | 260 | ... 261 | ``` 262 | 263 | As you may have noticed, we are using plain html tags instead of MJML ones. That's because you can't nest `` as certain email clients don't support it. When you have to create complex design, the best way is then to stick to the classic `
243 | 250 | 252 | {{ item.title }}
253 | Color: {{ item.color }}
254 | Size: {{ item.size }}
255 | Price: {{ item.price.currency }}{{ item.price.amount }} 256 |
` children tags ( ``, ` 283 | 284 | ``` 285 | 286 |  Try it live 287 | 288 |
289 | 290 | #### Click, click, click. 291 | 292 | Last but not list, we display our two CTAs using two [``](https://mjml.io/documentation/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#mjml-button). 293 | 294 | ```XML 295 | 296 | 297 | continue checkout 298 | 299 | 300 | edit cart 301 | 302 | ``` 303 | 304 |  Try it live 305 | 306 |
307 | 308 | 🔝 309 | 310 |
311 | 312 | ### You will love that 313 | 314 | We've already covered that part in our previous tutorials. Want to discover how to implement this section? Go [this way](../receipt/#i-bet-you-want-to-buy-more-things). 315 | 316 | 317 | ### The social network 318 | 319 | We've already covered that part in our previous tutorials. Want to discover how to implement this section? Go [this way](../welcome/#the-social-network). 320 | 321 | 322 | ## Conclusion 323 | 324 | Here we are! Now, thanks to your very cool and practical abandoned cart email, no cart on your website will be left in despair, longing forever for their customer to come back. Thank you for them! 325 | 326 | We'd love to have your feedback about this first tutorial, so ping us on [Twitter](https://twitter.com/mailjetdev) or come and chat on the [MJML slack channel](https://slack.mjml.io/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial)! 327 | 328 | You want to be informed about other tutorials and nice tech articles? Subscribe to our [dev only newsletter](https://dev.mailjet.com/community/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#newsletter) to stay tuned! 329 | 330 |
331 | 332 | 🔝 333 | --------------------------------------------------------------------------------
`, ``, etc.) wrapped in a [``](https://mjml.io/documentation/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#mjml-table) component. 264 | 265 |
266 | 267 |  Try it live 268 | 269 |
270 | 271 | 🔝 272 | 273 |
274 | 275 | #### How much is it? 276 | 277 | Here again, we use a [``](https://mjml.io/documentation/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#mjml-table) to display two subcolumns. One is left-aligned and contains the `SUBTOTAL:` title, the other is right-aligned and displays the currency and the amount using two templating language [variables](http://dev.mailjet.com/template-language/reference/?utm_source=referrer&utm_medium=github&utm_campaign=tpl_lang_tutorial#variables). 278 | 279 | ```XML 280 | 281 | 282 |
SUBTOTAL:{{ var:order.subtotal.currency }}{{ var:order.subtotal.amount }}