├── .editorconfig ├── .github ├── logo-dark.svg └── logo-light.svg ├── .gitignore ├── LICENSE ├── README.md ├── build_production ├── content │ ├── newsletter-1.html │ └── newsletter-2.html └── images │ ├── feature.jpg │ ├── insignia.png │ └── logo.png ├── components ├── alert.html ├── button.html ├── divider.html ├── spacer.html └── v-fill.html ├── config.js ├── config.production.js ├── content ├── newsletter-1.md └── newsletter-2.md ├── css └── markdown.css ├── images ├── feature.jpg ├── insignia.png └── logo.png ├── layouts ├── main.html └── secondary.html ├── package.json └── tailwind.config.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /.github/logo-dark.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.github/logo-light.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .vscode 3 | .idea 4 | Thumbs.db 5 | .DS_Store 6 | npm-debug.log 7 | yarn-error.log 8 | package-lock.json 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Cosmin Popovici 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 13 | all 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 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |

3 | 4 | 5 | 6 | Maizzle Starter 7 | 8 | 9 |

10 |

Markdown Starter

11 |
12 | 13 | # About 14 | 15 | This is a Markdown starter project for Maizzle, which you can use to generate HTML emails from Markdown files. 16 | 17 | See the detailed guide for more information: 18 | 19 | [How to create an HTML email newsletter from Markdown files](https://maizzle.com/guides/markdown-emails) 20 | 21 | ## Getting Started 22 | 23 | Run this command: 24 | 25 | ```bash 26 | npx create-maizzle 27 | ``` 28 | 29 | When prompted to select a Starter, choose Custom → Markdown. 30 | 31 | ## Documentation 32 | 33 | Maizzle documentation is available at https://maizzle.com 34 | 35 | ## License 36 | 37 | The Maizzle framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). 38 | -------------------------------------------------------------------------------- /build_production/content/newsletter-1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 22 | Edition #1: Using Markdown to create HTML emails with Maizzle 23 | 24 | 25 | 26 | 110 | 111 | 112 |
113 |
114 |
115 | Maizzle 116 |
117 |
118 | 119 | 120 | 167 | 168 | 169 | 170 | 171 | 172 | 189 | 190 |
121 | 122 | 123 | 164 | 165 |
124 |

Edition #1: Using Markdown to create HTML emails with Maizzle

125 |

Spaceman on planet surface

126 |

This is a Markdown starter project that will help you get started with creating newsletter email templates from Markdown files in Maizzle.

127 |

It supports all the framework features you already know and love:

128 |
    129 |
  • Tailwind CSS
  • 130 |
  • components
  • 131 |
  • expressions
  • 132 |
  • conditionals, loops etc.
  • 133 |
134 |

Ordered lists

135 |
    136 |
  1. Italics
  2. 137 |
  3. Bold text
  4. 138 |
  5. Links
  6. 139 |
140 |
141 |

Components

142 |

You can import Maizzle components right into your Markdown files. For example, the following button is a component:

143 | 150 |

That's the x-button component, defined in components/button.html

151 |
152 |

Styling

153 |

The starter includes CSS styles for common elements like paragraphs, headings, links, images, lists, inline code, or blockquotes:

154 |
155 |

One small step for man, one giant leap for mankind.

156 |
157 |

It even supports code blocks:

158 |
<p class="text-lg">
159 |   <a href="https://maizzle.com">Maizzle</a> is a framework for building responsive HTML emails with Tailwind CSS.
160 | </p>
161 |

Cheers,
162 | The Maizzle Team

163 |
166 |
173 | 174 | 175 | 178 | 186 | 187 |
176 | Maizzle 177 | 179 |

180 | Maizzle Markdown, 101 OSS Road. 181 |
182 | If you no longer wish to receive these emails, 183 | you can unsubscribe. 184 |

185 |
188 |
191 |
192 |
193 | 194 | -------------------------------------------------------------------------------- /build_production/content/newsletter-2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 22 | Edition #2: Using a custom layout 23 | 24 | 25 | 26 | 110 | 111 | 112 |
113 |
114 | 115 | 116 | 125 | 126 |
117 | 118 | 119 | 122 | 123 |
120 | Maizzle 121 |
124 |
127 |
128 | 129 | 130 | 147 | 148 | 149 | 150 | 151 | 152 | 169 | 170 |
131 | 132 | 133 | 144 | 145 |
134 |

Edition #2: Using a custom layout

135 |

This edition uses a custom layout: the header shows a different logo image, which is now also left-aligned instead of centered.

136 |

This is done via the layout property in the front matter:

137 |
---
138 | layout: secondary
139 | ---
140 |

The value of layout must match one of the file names inside the src/layouts directory.

141 |

Cheers,
142 | The Maizzle Team

143 |
146 |
153 | 154 | 155 | 158 | 166 | 167 |
156 | Maizzle 157 | 159 |

160 | Maizzle Markdown, 101 OSS Road. 161 |
162 | If you no longer wish to receive these emails, 163 | you can unsubscribe. 164 |

165 |
168 |
171 |
172 |
173 | 174 | -------------------------------------------------------------------------------- /build_production/images/feature.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maizzle/starter-markdown/971d07b36ab3f31d0f59ada1f5d1ef5ba2e09591/build_production/images/feature.jpg -------------------------------------------------------------------------------- /build_production/images/insignia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maizzle/starter-markdown/971d07b36ab3f31d0f59ada1f5d1ef5ba2e09591/build_production/images/insignia.png -------------------------------------------------------------------------------- /build_production/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maizzle/starter-markdown/971d07b36ab3f31d0f59ada1f5d1ef5ba2e09591/build_production/images/logo.png -------------------------------------------------------------------------------- /components/alert.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 24 | 25 |
17 | 22 | 23 |
26 | -------------------------------------------------------------------------------- /components/button.html: -------------------------------------------------------------------------------- 1 | 40 | 41 |
42 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 |
56 | -------------------------------------------------------------------------------- /components/divider.html: -------------------------------------------------------------------------------- 1 | 69 | 70 |
71 | -------------------------------------------------------------------------------- /components/spacer.html: -------------------------------------------------------------------------------- 1 | 18 | 19 | 20 |
24 |
25 | 26 |
27 |
28 | -------------------------------------------------------------------------------- /components/v-fill.html: -------------------------------------------------------------------------------- 1 | 19 | 20 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /config.js: -------------------------------------------------------------------------------- 1 | /* 2 | |------------------------------------------------------------------------------- 3 | | Development config https://maizzle.com/docs/environments 4 | |------------------------------------------------------------------------------- 5 | | 6 | | This is the base configuration that Maizzle will use when you run commands 7 | | like `npm run build` or `npm run dev`. Additional config files will 8 | | inherit these settings, and can override them when necessary. 9 | | 10 | */ 11 | 12 | import Shiki from '@shikijs/markdown-it' 13 | import markdownItAttrs from 'markdown-it-attrs' 14 | 15 | /** @type {import('@maizzle/framework').Config} */ 16 | export default { 17 | build: { 18 | content: ['content/**/*.md'], 19 | static: { 20 | source: ['images/**/*.*'], 21 | destination: 'images', 22 | }, 23 | }, 24 | markdown: { 25 | markdownit: { 26 | html: true, 27 | }, 28 | plugins: [ 29 | { 30 | plugin: await Shiki({ 31 | theme: 'tokyo-night', 32 | langs: ['html', 'css', 'javascript', 'yaml'], 33 | }), 34 | }, 35 | { 36 | plugin: markdownItAttrs, 37 | }, 38 | ] 39 | }, 40 | beforeRender({html, matter}) { 41 | const layout = matter.layout || 'main' 42 | 43 | return ` 44 | 45 | ${html} 46 | ` 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /config.production.js: -------------------------------------------------------------------------------- 1 | /* 2 | |------------------------------------------------------------------------------- 3 | | Production config https://maizzle.com/docs/environments 4 | |------------------------------------------------------------------------------- 5 | | 6 | | This is where you define settings that optimize your emails for production. 7 | | These will be merged on top of the base config.js, so you only need to 8 | | specify the options that are changing. 9 | | 10 | */ 11 | 12 | /** @type {import('@maizzle/framework').Config} */ 13 | export default { 14 | baseURL: { 15 | url: '../images/', 16 | tags: ['img', 'source'], 17 | }, 18 | build: { 19 | output: { 20 | path: 'build_production', 21 | extension: 'html', 22 | }, 23 | }, 24 | css: { 25 | inline: true, 26 | purge: true, 27 | shorthand: true, 28 | }, 29 | prettify: true, 30 | } 31 | -------------------------------------------------------------------------------- /content/newsletter-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Edition #1: Using Markdown to create HTML emails with Maizzle" 3 | --- 4 | 5 | # {{ page.title }} {.m-0 .mb-5} 6 | 7 | ![Spaceman on planet surface](feature.jpg){width=536} 8 | 9 | This is a ![M](insignia.png){width=20}arkdown starter project that will help you get started with creating newsletter email templates from Markdown files in Maizzle. 10 | 11 | It supports all the framework features you already know and love: 12 | 13 | - Tailwind CSS 14 | - components 15 | - expressions 16 | - conditionals, loops etc. 17 | 18 | ## Ordered lists 19 | 20 | 1. _Italics_ 21 | 2. **Bold text** 22 | 3. [Links](https://maizzle.com) 23 | 24 | *** 25 | 26 | ## Components 27 | 28 | You can import Maizzle components right into your Markdown files. For example, the following button is a component: 29 | 30 | 31 | Read the guide → 32 | 33 | 34 | That's the `x-button` component, defined in `components/button.html` 35 | 36 | *** 37 | 38 | ## Styling 39 | 40 | The starter includes CSS styles for common elements like paragraphs, headings, links, images, lists, inline code, or blockquotes: 41 | 42 | > One small step for man, one giant leap for mankind. 43 | 44 | It even supports code blocks: 45 | 46 | ```html 47 |

48 | Maizzle is a framework for building responsive HTML emails with Tailwind CSS. 49 |

50 | ``` 51 | 52 | Cheers,\ 53 | The Maizzle Team 54 | -------------------------------------------------------------------------------- /content/newsletter-2.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: secondary 3 | title: "Edition #2: Using a custom layout" 4 | --- 5 | 6 | # {{ page.title }} {.m-0 .mb-10} 7 | 8 | This edition uses a custom layout: the header shows a different logo image, which is now also left-aligned instead of centered. 9 | 10 | This is done via the `layout` property in the front matter: 11 | 12 | ```yaml 13 | --- 14 | layout: secondary 15 | --- 16 | ``` 17 | 18 | The value of `layout` must match one of the file names inside the `src/layouts` directory. 19 | 20 | Cheers,\ 21 | The Maizzle Team 22 | -------------------------------------------------------------------------------- /css/markdown.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Here is where you can add your global markdown CSS styles. 3 | * 4 | * This is preferred over using the @tailwindcss/typography 5 | * plugin, because that plugin contains selectors 6 | * that are not supported in HTML emails. 7 | */ 8 | 9 | h1 { 10 | @apply text-3xl/9 text-slate-900; 11 | } 12 | 13 | h2 { 14 | @apply text-2xl/8 text-slate-900; 15 | } 16 | 17 | h3 { 18 | @apply text-xl/7 text-slate-900; 19 | @apply m-0 mb-4; 20 | } 21 | 22 | h4 { 23 | @apply text-lg/6 text-slate-900; 24 | } 25 | 26 | h5 { 27 | @apply text-base/5 text-slate-900; 28 | } 29 | 30 | h6 { 31 | @apply text-base/5 text-slate-900 uppercase; 32 | } 33 | 34 | @screen sm { 35 | h1 { 36 | @apply !text-2xl/8; 37 | } 38 | 39 | h2 { 40 | @apply !text-xl/7; 41 | } 42 | 43 | h3 { 44 | @apply !text-lg/6; 45 | } 46 | 47 | h4 { 48 | @apply !text-base/5; 49 | } 50 | 51 | h5 { 52 | @apply !text-sm; 53 | } 54 | 55 | h6 { 56 | @apply !text-sm; 57 | } 58 | } 59 | 60 | p { 61 | @apply text-base/6 text-slate-600; 62 | @apply m-0 mb-8; 63 | } 64 | 65 | ul, ol { 66 | @apply leading-6 text-slate-600; 67 | } 68 | 69 | blockquote { 70 | @apply m-0 mb-8 pl-4; 71 | border-left: 4px solid #6366f1; 72 | 73 | } 74 | 75 | blockquote p { 76 | @apply m-0 text-lg/7; 77 | } 78 | 79 | hr { 80 | @apply border-0 h-px text-slate-300 bg-slate-300; 81 | @apply my-8; 82 | } 83 | 84 | a { 85 | @apply text-blue-600 underline; 86 | } 87 | 88 | img { 89 | @apply max-w-full align-middle; 90 | } 91 | 92 | pre { 93 | @apply p-6 mb-6 overflow-auto whitespace-pre rounded-lg; 94 | @apply font-mono text-base text-left; 95 | @apply text-slate-300; 96 | hyphens: none; 97 | tab-size: 2; 98 | word-break: normal; 99 | word-spacing: normal; 100 | word-wrap: normal; 101 | } 102 | 103 | /* Inline code */ 104 | :not(pre) > code { 105 | @apply px-1.5 py-0.5 rounded; 106 | @apply text-sm whitespace-normal; 107 | @apply text-pink-500 bg-slate-50 border border-solid border-slate-200; 108 | } 109 | -------------------------------------------------------------------------------- /images/feature.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maizzle/starter-markdown/971d07b36ab3f31d0f59ada1f5d1ef5ba2e09591/images/feature.jpg -------------------------------------------------------------------------------- /images/insignia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maizzle/starter-markdown/971d07b36ab3f31d0f59ada1f5d1ef5ba2e09591/images/insignia.png -------------------------------------------------------------------------------- /images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maizzle/starter-markdown/971d07b36ab3f31d0f59ada1f5d1ef5ba2e09591/images/logo.png -------------------------------------------------------------------------------- /layouts/main.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 23 | 24 | {{{ page.title }}} 25 | 26 | 27 | 28 | 29 | 34 | 35 | 36 | 37 | 38 | 42 | 43 | 44 |
52 | 53 | 54 |
55 | Maizzle 56 |
57 | 58 | 59 | 60 | 61 | 62 | 71 | 72 | 73 | 74 | 75 | 76 | 93 | 94 |
63 | 64 | 65 | 68 | 69 |
66 | 67 |
70 |
77 | 78 | 79 | 82 | 90 | 91 |
80 | Maizzle 81 | 83 |

84 | Maizzle Markdown, 101 OSS Road. 85 |
86 | If you no longer wish to receive these emails, 87 | you can unsubscribe. 88 |

89 |
92 |
95 | 96 | 97 |
98 | 99 | 100 | -------------------------------------------------------------------------------- /layouts/secondary.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 23 | 24 | {{{ page.title }}} 25 | 26 | 27 | 28 | 29 | 34 | 35 | 36 | 37 | 38 | 42 | 43 | 44 |
52 | 53 | 54 | 55 | 56 | 65 | 66 |
57 | 58 | 59 | 62 | 63 |
60 | Maizzle 61 |
64 |
67 | 68 | 69 | 70 | 71 | 72 | 81 | 82 | 83 | 84 | 85 | 86 | 103 | 104 |
73 | 74 | 75 | 78 | 79 |
76 | 77 |
80 |
87 | 88 | 89 | 92 | 100 | 101 |
90 | Maizzle 91 | 93 |

94 | Maizzle Markdown, 101 OSS Road. 95 |
96 | If you no longer wish to receive these emails, 97 | you can unsubscribe. 98 |

99 |
102 |
105 | 106 | 107 |
108 | 109 | 110 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "type": "module", 4 | "scripts": { 5 | "dev": "maizzle serve", 6 | "build": "maizzle build production" 7 | }, 8 | "dependencies": { 9 | "@maizzle/framework": "latest", 10 | "@shikijs/markdown-it": "^1.24.3", 11 | "markdown-it-attrs": "^4.3.0", 12 | "shiki": "^1.24.3", 13 | "tailwindcss-preset-email": "latest" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | presets: [ 4 | require('tailwindcss-preset-email'), 5 | ], 6 | content: [ 7 | './components/**/*.html', 8 | './layouts/**/*.html', 9 | './content/**/*.md', 10 | ], 11 | theme: { 12 | extend: { 13 | fontFamily: { 14 | inter: ['Inter', 'ui-sans-serif', 'system-ui', '-apple-system', '"Segoe UI"', 'sans-serif'], 15 | }, 16 | }, 17 | }, 18 | } 19 | --------------------------------------------------------------------------------