Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/email templates #195

Merged
merged 4 commits into from
Oct 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Improve manual run form
- (docs): add codespaces config to run demo
- Add `allowed_origins` configuration to explicitly set CORS headers
- Add HTML template for email notifications (#52)

### Fixed
- Sometimes logs are appended to an existing logs files of previous runs (#131)
Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
recursive-include src/plombery/static *
recursive-include src/plombery/notifications/email_templates *
include README.md
9 changes: 9 additions & 0 deletions email-templates/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
8 changes: 8 additions & 0 deletions email-templates/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
node_modules
build_local
.vscode
.idea
Thumbs.db
.DS_Store
npm-debug.log
yarn-error.log
21 changes: 21 additions & 0 deletions email-templates/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) Cosmin Popovici

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
68 changes: 68 additions & 0 deletions email-templates/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<div align="center">
<p>
<a href="https://maizzle.com" target="_blank">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/maizzle/maizzle/raw/master/.github/logo-dark.svg">
<img alt="Maizzle Starter" src="https://github.com/maizzle/maizzle/raw/master/.github/logo-light.svg" width="300" height="225" style="max-width: 100%;">
</picture>
</a>
</p>
<p>Quickly build HTML emails with utility-first CSS</p>
<div>

[![Version][npm-version-shield]][npm]
[![Build][github-ci-shield]][github-ci]
[![Downloads][npm-stats-shield]][npm-stats]
[![License][license-shield]][license]

</div>
</div>

## Getting Started

Clone this starter:

```bash
npx degit maizzle/maizzle my-project
```

Install dependencies:

```
cd my-project

npm install
```

Start local development:

```
npm run dev
```

Build emails for production:

```
npm run build
```

## Documentation

Maizzle documentation is available at https://maizzle.com

## Issues

Please open all issues in the [framework repository](https://github.com/maizzle/framework).

## License

The Maizzle framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).

[npm]: https://www.npmjs.com/package/@maizzle/framework
[npm-stats]: https://npm-stat.com/charts.html?package=%40maizzle%2Fframework&from=2019-03-27
[npm-version-shield]: https://img.shields.io/npm/v/@maizzle/framework.svg
[npm-stats-shield]: https://img.shields.io/npm/dt/@maizzle/framework.svg?color=6875f5
[github-ci]: https://github.com/maizzle/framework/actions
[github-ci-shield]: https://github.com/maizzle/framework/actions/workflows/nodejs.yml/badge.svg
[license]: ./LICENSE
[license-shield]: https://img.shields.io/npm/l/@maizzle/framework.svg?color=0e9f6e
25 changes: 25 additions & 0 deletions email-templates/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
|-------------------------------------------------------------------------------
| Development config https://maizzle.com/docs/environments
|-------------------------------------------------------------------------------
|
| The exported object contains the default Maizzle settings for development.
| This is used when you run `maizzle build` or `maizzle serve` and it has
| the fastest build time, since most transformations are disabled.
|
*/

module.exports = {
build: {
templates: {
source: 'src/templates',
destination: {
path: 'build_local',
},
assets: {
source: 'src/images',
destination: 'images',
},
},
},
}
24 changes: 24 additions & 0 deletions email-templates/config.production.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
|-------------------------------------------------------------------------------
| Production config https://maizzle.com/docs/environments
|-------------------------------------------------------------------------------
|
| This is where you define settings that optimize your emails for production.
| These will be merged on top of the base config.js, so you only need to
| specify the options that are changing.
|
*/

module.exports = {
build: {
templates: {
destination: {
path: '../src/plombery/notifications/email_templates',
},
},
},
inlineCSS: true,
removeUnusedCSS: true,
shorthandCSS: true,
prettify: true,
}
13 changes: 13 additions & 0 deletions email-templates/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"private": true,
"scripts": {
"dev": "maizzle serve",
"build": "maizzle build production"
},
"dependencies": {
"@maizzle/framework": "latest",
"tailwindcss-box-shadow": "^2.0.0",
"tailwindcss-email-variants": "^2.0.0",
"tailwindcss-mso": "^1.3.0"
}
}
38 changes: 38 additions & 0 deletions email-templates/src/components/button.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<script props>
module.exports = {
align: {
left: 'text-left',
center: 'text-center',
right: 'text-right',
}[props.align],
href: props.href,
msoPt: props['mso-pt'] || '16px',
msoPr: props['mso-pr'] || '32px',
msoPb: props['mso-pb'] || '30px',
msoPl: props['mso-pl'] || '32px',
}
</script>

<div class="{{ align }}">
<a
attributes
href="{{ href }}"
class="inline-block py-4 px-6 text-base leading-none font-semibold rounded text-slate-50 bg-indigo-700 [text-decoration:none]"
>
<outlook>
<i
class="mso-font-width-[-100%]"
style="letter-spacing: {{ msoPl }}; mso-text-raise: {{ msoPb }};"
hidden
>&nbsp;</i>
</outlook>
<span style="mso-text-raise: {{ msoPt }}"><content /></span>
<outlook>
<i
class="mso-font-width-[-100%]"
style="letter-spacing: {{ msoPr }};"
hidden
>&nbsp;</i>
</outlook>
</a>
</div>
29 changes: 29 additions & 0 deletions email-templates/src/components/divider.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<script props>
// https://maizzle.com/docs/components/divider
module.exports = {
height: props.height || '1px',
color: props.color, // any CSS color value
top: props.top, // top margin
bottom: props.bottom, // bottom margin
left: props.left, // left margin
right: props.right, // right margin
spaceY: props['space-y'] || '24px', // top and bottom margin
spaceX: props['space-x'], // right and left margin
}
</script>

<div
role="separator"
class="{{ !color && 'bg-slate-300' }}"
style="height: {{ height }};
line-height: {{ height }};
{{ color && `background-color: ${color}` }};
margin: 0;
{{ spaceY && `margin-top: ${spaceY}; margin-bottom: ${spaceY}` }};
{{ spaceX && `margin-left: ${spaceX}; margin-right: ${spaceX}` }};
{{ top && `margin-top: ${top}` }};
{{ bottom && `margin-bottom: ${bottom}` }};
{{ left && `margin-left: ${left}` }};
{{ right && `margin-right: ${right}` }};
"
>&zwj;</div>
20 changes: 20 additions & 0 deletions email-templates/src/components/spacer.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<script props>
// https://maizzle.com/docs/components/spacer
module.exports = {
height: props.height,
msoHeight: props['mso-height'],
}
</script>

<if condition="height">
<div
attributes
role="separator"
style="{{ height && `line-height: ${height}` }};
{{ msoHeight && `mso-line-height-alt: ${msoHeight}` }};
"
>&zwj;</div>
</if>
<else>
<div role="separator">&zwj;</div>
</else>
13 changes: 13 additions & 0 deletions email-templates/src/components/v-fill.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<script props>
module.exports = {
width: props.width || '600px',
image: props.image || 'https://via.placeholder.com/600x400'
}
</script>

<!--[if mso]>
<v:rect stroke="f" style="width: {{ width }}" xmlns:v="urn:schemas-microsoft-com:vml">
<v:fill type="frame" src="{{{ image }}}" />
<v:textbox inset="0,0,0,0" style="mso-fit-shape-to-text: true"><div><![endif]-->
<content />
<!--[if mso]></div></v:textbox></v:rect><![endif]-->
14 changes: 14 additions & 0 deletions email-templates/src/components/v-image.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script props>
module.exports = {
width: props.width || '600px',
height: props.height || '400px',
image: props.image || 'https://via.placeholder.com/600x400'
}
</script>

<!--[if mso]>
<v:image src="{{{ image }}}" style="width: {{ width }}; height: {{ height }};" xmlns:v="urn:schemas-microsoft-com:vml" />
<v:rect fill="f" stroke="f" style="position: absolute; width: {{ width }}; height: {{ height }};" xmlns:v="urn:schemas-microsoft-com:vml">
<v:textbox inset="0,0,0,0"><div><![endif]-->
<content />
<!--[if mso]></div></v:textbox></v:rect><![endif]-->
13 changes: 13 additions & 0 deletions email-templates/src/css/resets.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Here is where you can add your global email CSS resets.
*
* We use a custom, email-specific CSS reset, instead
* of Tailwind's web-optimized `base` layer.
*
* Styles defined here will be inlined.
*/

img {
@apply max-w-full leading-none align-middle;
border: 0;
}
17 changes: 17 additions & 0 deletions email-templates/src/css/tailwind.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* Your custom CSS resets for email */
@import "resets";

/* Tailwind CSS components */
@import "tailwindcss/components";

/**
* @import here any custom CSS components - that is, CSS that
* you'd want loaded before the Tailwind utilities, so the
* utilities can still override them.
*/

/* Tailwind CSS utility classes */
@import "tailwindcss/utilities";

/* Your custom utility classes */
@import "utilities";
15 changes: 15 additions & 0 deletions email-templates/src/css/utilities.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Here is where you can define your custom utility classes.
*
* We wrap them in the `utilities` @layer directive, so
* that Tailwind moves them to the correct location.
*
* More info:
* https://tailwindcss.com/docs/functions-and-directives#layer
*/

@layer utilities {
.break-word {
word-break: break-word;
}
}
Empty file.
41 changes: 41 additions & 0 deletions email-templates/src/layouts/main.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<!DOCTYPE {{{ page.doctype || 'html' }}}>
<html lang="{{ page.language || 'en' }}" xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<meta charset="{{ page.charset || 'utf-8' }}">
<meta name="x-apple-disable-message-reformatting">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="format-detection" content="telephone=no, date=no, address=no, email=no, url=no">
<meta name="color-scheme" content="light dark">
<meta name="supported-color-schemes" content="light dark">
<!--[if mso]>
<noscript>
<xml>
<o:OfficeDocumentSettings xmlns:o="urn:schemas-microsoft-com:office:office">
<o:PixelsPerInch>96</o:PixelsPerInch>
</o:OfficeDocumentSettings>
</xml>
</noscript>
<style>
td,th,div,p,a,h1,h2,h3,h4,h5,h6 {font-family: "Segoe UI", sans-serif; mso-line-height-rule: exactly;}
</style>
<![endif]-->
<if condition="page.title">
<title>{{{ page.title }}}</title>
</if>
<style>
{{{ page.css }}}
</style>
<stack name="head" />
</head>
<body class="m-0 p-0 w-full [word-break:break-word] [-webkit-font-smoothing:antialiased] {{ page.bodyClass || '' }}">
<if condition="page.preheader">
<div class="hidden">
{{{ page.preheader }}}
<each loop="item in Array.from(Array(150))">&#8199;&#65279;&#847; </each>
</div>
</if>
<div role="article" aria-roledescription="email" aria-label="{{{ page.title || '' }}}" lang="{{ page.language || 'en' }}">
<content />
</div>
</body>
</html>
Loading
Loading