Skip to content

Instantly share code, notes, and snippets.

@saiashirwad
Last active July 15, 2022 11:44
Show Gist options
  • Save saiashirwad/f5204f1a10e46e0ae32bd5318d4caf4c to your computer and use it in GitHub Desktop.
Save saiashirwad/f5204f1a10e46e0ae32bd5318d4caf4c to your computer and use it in GitHub Desktop.
Experimental typesafe email generation with heml, zx
#!/usr/bin/env zx
import Emails from "./templates.js";
const readFile = async (filePath) => fs.readFile(filePath, "utf8");
const populateTemplate = (template, card = "", footer = "") =>
template.replace("__CARD__", card).replace("__FOOTER__", footer);
const writeFile = (path, data) => fs.writeFile(path, data, "utf8");
const outputFolder = "./out/";
const buildTemplate = async (templateName) => {
const BASE = await readFile("./template.heml");
const { template, type } = Emails[templateName];
const res = writeFile(
`${outputFolder}${templateName}.heml`,
populateTemplate(BASE, template, "footer")
);
const build = await $`heml build ${outputFolder}${templateName}.heml`;
if (build) {
const result = await readFile(`${outputFolder}${templateName}.html`);
return { result, type };
}
};
Promise.all(
Object.keys(Emails).map(async (emailName) => {
const { result, type } = await buildTemplate(emailName);
return `export const get${emailName} = (${type}) => \`${result}\``;
})
)
.then((result) => result.join("\n"))
.then((result) => writeFile(`${outputFolder}/templates.ts`, result));
<heml>
<head>
<style>
body {
background-color: #fbfdfe;
}
h1 {
color: DarkViolet;
}
.card {
padding-top: 2em;
margin-left: 2em;
margin-right: 2em;
background-color: white;
margin-top: 4em;
border-radius: 0.2em;
padding: 2em;
box-shadow: rgba(0, 0, 0, 0.1) 0px 0px 5px 0px, rgba(0, 0, 0, 0.1) 0px 0px 1px 0px;
}
button {
margin-top: 2em;
margin-bottom: 2em;
background-color: #2885bd;
box-shadow: rgba(0, 0, 0, 0.1) 0px 0px 5px 0px, rgba(0, 0, 0, 0.1) 0px 0px 1px 0px;
}
.center-button {
margin: auto;
}
p {
color: #364152;
}
.footer {
margin-top: 2em;
color: #97a6ba;
margin-left: 1em;
margin-right: 1em;
padding-left: 1em;
}
</style>
</head>
<body>
<div>
<div class="card">
__CARD__
</div>
<div class="footer">
__FOOTER__
</div>
</div>
</body>
</heml>
module.exports = {
TestEmail: {
type: `a: string`,
template: `
<p>
Hi there \${a}! this is an email!
</p>
<button class="center-button">
Here
</button>
<p>
This sounds like a GREAT IDEA
</p>
`
},
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment