Intro
We know emails are VERY HARD
to develop from scratch.
Sometimes you can use tool like Maiject, SendPulse, MailerSend, Stripo.email etc. Some of this have cool interfaces with drag and drop and different actions to do.
So why you/your company should use this library?
- you need to produce some html files using layouts and partials for different languages, passing them to a backend witch add maybe some data coming from itself (or another service) and fills your html files with its template engine.
- backend of your company deploy email using with a custom service that use Amazon SES.
- previous providers are not able to customize some parts. For example css rule. Or to do this is very complicated.
- coming from email-foundation-template and you want to try a different tool with advantages (please read below about features).
- having complete control of development without use any Saas is mandatory.
This project wants to mix up MJML, a template engine for variables and a web server, to create a tool able to generate emails with a simple flow and one command. Please keep in mind that Maiject, SendPulse, MailerSend, Stripo.email etc maybe can be already perfect for your purpose.
π Usage
Install (require node >=16)
npm i marilena
Setup
marilena provides a command witch generate a small but working example with eta.js, variables, layout and partials. You can choose to generate this example adding these commands to your package.json
and then run npm run generate-example
.
"scripts": {
"start": "marilena --server --project example/marilena.config.mjs",
"build": "marilena --build --project example/marilena.config.mjs",
"generate-example": "marilena --create-example",
},
Setup (manual)
If you fails to generate the example or you want to build a project from 0 you need to crete marilena.config.mjs
file in the root of your project. Please check below the fields since any of these are required.
import path from "path";
export default {
inputFolder: "./input",
outputFolder: "./output",
textVersion: (emailName, locale) => `${emailName}_text_version-${locale}.txt`,
htmlVersion: (emailName, locale) => `${emailName}-custom.html`,
locales: ["it", "en"],
templateOptions: {
engine: "eta",
prepareEngine: (eta) => {
eta.configure({
views: path.join(process.cwd(), "playground/input"),
});
},
},
mjmlParsingOptions: {
keepComments: false,
},
};
Edit you package.json
. By default marilena
try to find config in the root of your project. If you put the config in a different path, you need to pass --project
argument in the scripts
"scripts": {
"start": "marilena --server",
"build": "marilena --build",
},
create a file structures based on your config. Please remember that each email template requires index.html
as name, and variables are loaded only from variables.json
or variables.yml
. Yes you can use both :)
project
| marilena.config.mjs
β package.json
β input
β βββcommon-en.json // common json variables for all en emails
β βββcommon-it.yaml // common yaml variables for all it emails
β βββbuy // email name
ββββββββββ index.html
ββββββββββ en
ββββββββββββββ variables.json // json variables for en buy email
ββββββββββ it
ββββββββββββββ variables.yaml // yaml variables for it buy email
3 - fill your emails template with MJML syntax
<mjml>
<mj-body>
<mj-section>
<mj-column>
<mj-text>hello <%= it.user %></mj-text>
</mj-column>
</mj-section>
</mj-body>
</mjml>
4 - run one of these 2 commands
npm run start
npm run build
Configuration
Under the hood a default configuration will be loaded but a file marilena.config.mjs
allow us to set:
name | required | description | default |
---|
inputFolder | | folder where email are in the project. Path is relative to marilena.config.mjs | ./input |
outputFolder | | folder used for generated email (when run build command). Path is relative to marilena.config.mjs | ./output |
locales | | array of languages used. If you need only spanish email use an array of single value | ["es"] |
templateOptions | | if you chose to use one of supported engines, this part is mandatory to setup custom partial and other settings for the template engine selected. Read below for some use cases | empty |
mjmlParsingOptions | | options passed to mjml render. See: mjml options | |
htmlVersion | | function of type (emailName: string, locale: string) => string . If set, this function allow to customize the output html filename. The function must return file name es: ${emailName}-${locale}.html | index.html |
textVersion | | function of type (emailName: string, locale: string) => string . If set, this function allow to generate text version of email stripping all html. The function must return file name es: ${emailName}-${locale}-text-version.txt | |
About templateOptions
This project can producte output html from input template. But in a real word probably we store variables in some part and render some content multiple times (example a footer). In this case templateOptions
can define:
engine
: eta
or handlebars
are supported. Apart eta
, which is used also in the project library, all others requires dependency installed since marilena
use lazy import for engines.prepareEngine
: define a callback where we can setup our engine. Basically you can define all things before the render. For example:
templateOptions: {
engine: "eta",
prepareEngine: (eta) => {
eta.configure({
views: path.join(process.cwd(), "input"),
});
eta.loadTemplate(...);
},
},
templateOptions: {
engine: "handlebars",
prepareEngine: (h) => {
h.registerPartial("myPartial", "partial with {{ user }}");
},
},
Use css
If you want to add a css file import in mj-include
tag. Path start from root directory of the project (like package json):
<mjml>
<mj-body>
<mj-include path="input/styles.css" type="css" css-inline="inline"/>
</mj-body>
</mjml>
π Features
ποΈ Roadmap (PRs are welcome π)