commit
ef71eecb24
|
@ -14,7 +14,7 @@ Excellent! You've come to the right place.
|
||||||
|
|
||||||
## Theming Instructions
|
## Theming Instructions
|
||||||
|
|
||||||
This file contains instructions on adding themes to Mailgen:
|
This file contains instructions on adding themes to Hermes:
|
||||||
|
|
||||||
* [Using a Custom Theme](#using-a-custom-theme)
|
* [Using a Custom Theme](#using-a-custom-theme)
|
||||||
* [Creating a Built-In Theme](#creating-a-built-in-theme)
|
* [Creating a Built-In Theme](#creating-a-built-in-theme)
|
||||||
|
@ -26,7 +26,7 @@ This file contains instructions on adding themes to Mailgen:
|
||||||
|
|
||||||
### Using a Custom Theme
|
### Using a Custom Theme
|
||||||
|
|
||||||
If you want to supply your own **custom theme** for Hermes to use (but don't want it included with Mailgen):
|
If you want to supply your own **custom theme** for Hermes to use (but don't want it included with Hermes):
|
||||||
|
|
||||||
1. Create a new struct implementing `Theme` interface ([hermes.go](hermes.go)). A real-life example is in [default.go](default.go)
|
1. Create a new struct implementing `Theme` interface ([hermes.go](hermes.go)). A real-life example is in [default.go](default.go)
|
||||||
2. Supply your new theme at hermes creation
|
2. Supply your new theme at hermes creation
|
||||||
|
@ -68,7 +68,7 @@ h := hermes.Hermes{
|
||||||
|
|
||||||
### Creating a Built-In Theme
|
### Creating a Built-In Theme
|
||||||
|
|
||||||
If you want to create a new **built-in** Mailgen theme:
|
If you want to create a new **built-in** Hermes theme:
|
||||||
|
|
||||||
1. Fork the repository to your GitHub account and clone it to your computer
|
1. Fork the repository to your GitHub account and clone it to your computer
|
||||||
2. Create a new Go file named after your new theme
|
2. Create a new Go file named after your new theme
|
||||||
|
|
25
README.md
25
README.md
|
@ -5,12 +5,12 @@
|
||||||
[![Go Coverage](https://codecov.io/github/matcornic/hermes/coverage.svg)](https://codecov.io/github/matcornic/hermes/)
|
[![Go Coverage](https://codecov.io/github/matcornic/hermes/coverage.svg)](https://codecov.io/github/matcornic/hermes/)
|
||||||
[![Godoc](https://godoc.org/github.com/matcornic/hermes?status.svg)](https://godoc.org/github.com/matcornic/hermes)
|
[![Godoc](https://godoc.org/github.com/matcornic/hermes?status.svg)](https://godoc.org/github.com/matcornic/hermes)
|
||||||
|
|
||||||
Hermes is the Go port of the great [mailgen](https://github.com/eladnava/mailgen) engine for Node.js. Check their work, it's awesome !
|
Hermes is the Go port of the great [mailgen](https://github.com/eladnava/mailgen) engine for Node.js. Check their work, it's awesome!
|
||||||
It's a package that generates clean, responsive HTML e-mails for sending transactional e-mails (welcome e-mail, reset password e-mails, receipt e-mails and so on).
|
It's a package that generates clean, responsive HTML e-mails for sending transactional e-mails (welcome e-mails, reset password e-mails, receipt e-mails and so on).
|
||||||
|
|
||||||
# Demo
|
# Demo
|
||||||
|
|
||||||
<img src="https://raw.github.com/matcornic/hermes/master/screens/default/welcome.png" height="400" /> <img src="https://raw.github.com/matcornic/hermes/master/screens/default/reset.png" height="400" /> <img src="https://raw.github.com/matcornic/hermes/master/screens/default/receipt.png" height="400" />
|
<img src="screens/default/welcome.png" height="400" /> <img src="screens/default/reset.png" height="400" /> <img src="screens/default/receipt.png" height="400" />
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
|
|
||||||
|
@ -31,8 +31,8 @@ h := hermes.Hermes{
|
||||||
// Appears in header & footer of e-mails
|
// Appears in header & footer of e-mails
|
||||||
Name: "Hermes",
|
Name: "Hermes",
|
||||||
Link: "https://example-hermes.com/",
|
Link: "https://example-hermes.com/",
|
||||||
//Option product logo
|
// Option product logo
|
||||||
//Logo: "http://www.duchess-france.org/wp-content/uploads/2016/01/gopher.png",
|
// Logo: "http://www.duchess-france.org/wp-content/uploads/2016/01/gopher.png",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -62,7 +62,7 @@ email := hermes.Email{
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate an HTML email with the provided contents(for modern clients)
|
// Generate an HTML email with the provided contents (for modern clients)
|
||||||
emailBody, err := h.GenerateHTML(email)
|
emailBody, err := h.GenerateHTML(email)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err) // Tip: Handle error with something else than a panic ;)
|
panic(err) // Tip: Handle error with something else than a panic ;)
|
||||||
|
@ -74,7 +74,7 @@ if err != nil {
|
||||||
panic(err) // Tip: Handle error with something else than a panic ;)
|
panic(err) // Tip: Handle error with something else than a panic ;)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optionnaly, preview the generated HTML e-mail by writing it to a local file
|
// Optionally, preview the generated HTML e-mail by writing it to a local file
|
||||||
err = ioutil.WriteFile("preview.html", []byte(emailBody), 0644)
|
err = ioutil.WriteFile("preview.html", []byte(emailBody), 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err) // Tip: Handle error with something else than a panic ;)
|
panic(err) // Tip: Handle error with something else than a panic ;)
|
||||||
|
@ -83,7 +83,7 @@ if err != nil {
|
||||||
|
|
||||||
This code would output the following HTML template:
|
This code would output the following HTML template:
|
||||||
|
|
||||||
<img src="https://raw.github.com/matcornic/hermes/master/screens/demo.png" height="400" />
|
<img src="screens/demo.png" height="400" />
|
||||||
|
|
||||||
> Theme templates will be embedded in your application binary. If you want to use external templates (for configuration), use your own theme by implementing `hermes.Theme` interface with code searching for your files.
|
> Theme templates will be embedded in your application binary. If you want to use external templates (for configuration), use your own theme by implementing `hermes.Theme` interface with code searching for your files.
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ The following open-source themes are bundled with this package:
|
||||||
|
|
||||||
* `default` by [Postmark Transactional Email Templates](https://github.com/wildbit/postmark-templates)
|
* `default` by [Postmark Transactional Email Templates](https://github.com/wildbit/postmark-templates)
|
||||||
|
|
||||||
<img src="https://raw.github.com/matcornic/hermes/master/screens/default/welcome.png" height="200" /> <img src="https://raw.github.com/matcornic/hermes/master/screens/default/reset.png" height="200" /> <img src="https://raw.github.com/matcornic/hermes/master/screens/default/receipt.png" height="200" />
|
<img src="screens/default/welcome.png" height="200" /> <img src="screens/default/reset.png" height="200" /> <img src="screens/default/receipt.png" height="200" />
|
||||||
|
|
||||||
## RTL Support
|
## RTL Support
|
||||||
|
|
||||||
|
@ -129,13 +129,13 @@ h := hermes.Hermes {
|
||||||
|
|
||||||
## Language Customizations
|
## Language Customizations
|
||||||
|
|
||||||
To customize the e-mail greeting (Hi) or signature (Yours truly), supply custom strings within the e-mail `Body`:
|
To customize the e-mail's greeting ("Hi") or signature ("Yours truly"), supply custom strings within the e-mail's `Body`:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
email := hermes.Email{
|
email := hermes.Email{
|
||||||
Body: hermes.Body{
|
Body: hermes.Body{
|
||||||
Greeting: "Dear",
|
Greeting: "Dear",
|
||||||
Signature: "Sincerly",
|
Signature: "Sincerely",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -146,7 +146,7 @@ To use a custom title string rather than a greeting/name introduction, provide i
|
||||||
email := hermes.Email{
|
email := hermes.Email{
|
||||||
Body: hermes.Body{
|
Body: hermes.Body{
|
||||||
// Title will override `Name`
|
// Title will override `Name`
|
||||||
Title: "Welcome to Mailgen",
|
Title: "Welcome to Hermes",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -176,7 +176,6 @@ Hermes supports injecting custom elements such as dictionaries, tables and actio
|
||||||
|
|
||||||
To inject an action button in to the e-mail, supply the `Actions` object as follows:
|
To inject an action button in to the e-mail, supply the `Actions` object as follows:
|
||||||
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
email := hermes.Email{
|
email := hermes.Email{
|
||||||
Body: hermes.Body{
|
Body: hermes.Body{
|
||||||
|
|
218
default.go
218
default.go
|
@ -227,6 +227,7 @@ func (dt *Default) HTMLTemplate() string {
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<!-- Email Body -->
|
<!-- Email Body -->
|
||||||
<tr>
|
<tr>
|
||||||
<td class="email-body" width="100%">
|
<td class="email-body" width="100%">
|
||||||
|
@ -235,121 +236,124 @@ func (dt *Default) HTMLTemplate() string {
|
||||||
<tr>
|
<tr>
|
||||||
<td class="content-cell">
|
<td class="content-cell">
|
||||||
<h1>{{if .Email.Body.Title }}{{ .Email.Body.Title }}{{ else }}{{ .Email.Body.Greeting }} {{ .Email.Body.Name }},{{ end }}</h1>
|
<h1>{{if .Email.Body.Title }}{{ .Email.Body.Title }}{{ else }}{{ .Email.Body.Greeting }} {{ .Email.Body.Name }},{{ end }}</h1>
|
||||||
{{ with .Email.Body.Intros }}
|
{{ with .Email.Body.Intros }}
|
||||||
{{ if gt (len .) 0 }}
|
{{ if gt (len .) 0 }}
|
||||||
{{ range $line := . }}
|
{{ range $line := . }}
|
||||||
<p>{{ $line }}</p>
|
<p>{{ $line }}</p>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
{{ with .Email.Body.Dictionary }}
|
{{ with .Email.Body.Dictionary }}
|
||||||
{{ if gt (len .) 0 }}
|
{{ if gt (len .) 0 }}
|
||||||
<dl class="body-dictionary">
|
<dl class="body-dictionary">
|
||||||
{{ range $entry := . }}
|
{{ range $entry := . }}
|
||||||
<dt>{{ $entry.Key }}:</dt>
|
<dt>{{ $entry.Key }}:</dt>
|
||||||
<dd>{{ $entry.Value }}</dd>
|
<dd>{{ $entry.Value }}</dd>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</dl>
|
</dl>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
<!-- Table -->
|
<!-- Table -->
|
||||||
{{ with .Email.Body.Table }}
|
{{ with .Email.Body.Table }}
|
||||||
{{ $data := .Data }}
|
{{ $data := .Data }}
|
||||||
{{ $columns := .Columns }}
|
{{ $columns := .Columns }}
|
||||||
{{ if gt (len $data) 0 }}
|
{{ if gt (len $data) 0 }}
|
||||||
<table class="data-wrapper" width="100%" cellpadding="0" cellspacing="0">
|
<table class="data-wrapper" width="100%" cellpadding="0" cellspacing="0">
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<table class="data-table" width="100%" cellpadding="0" cellspacing="0">
|
<table class="data-table" width="100%" cellpadding="0" cellspacing="0">
|
||||||
|
<tr>
|
||||||
|
{{ $col := index $data 0 }}
|
||||||
|
{{ range $entry := $col }}
|
||||||
|
<th
|
||||||
|
{{ with $columns }}
|
||||||
|
{{ $width := index .CustomWidth $entry.Key }}
|
||||||
|
{{ with $width }}
|
||||||
|
width="{{ . }}"
|
||||||
|
{{ end }}
|
||||||
|
{{ $align := index .CustomAlignement $entry.Key }}
|
||||||
|
{{ with $align }}
|
||||||
|
style="text-align:{{ . }}"
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
>
|
||||||
|
<p>{{ $entry.Key }}</p>
|
||||||
|
</th>
|
||||||
|
{{ end }}
|
||||||
|
</tr>
|
||||||
|
{{ range $row := $data }}
|
||||||
|
<tr>
|
||||||
|
{{ range $cell := $row }}
|
||||||
|
<td
|
||||||
|
{{ with $columns }}
|
||||||
|
{{ $align := index .CustomAlignement $cell.Key }}
|
||||||
|
{{ with $align }}
|
||||||
|
style="text-align:{{ . }}"
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
>
|
||||||
|
{{ $cell.Value }}
|
||||||
|
</td>
|
||||||
|
{{ end }}
|
||||||
|
</tr>
|
||||||
|
{{ end }}
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
<!-- Action -->
|
||||||
|
{{ with .Email.Body.Actions }}
|
||||||
|
{{ if gt (len .) 0 }}
|
||||||
|
{{ range $action := . }}
|
||||||
|
<p>{{ $action.Instructions }}</p>
|
||||||
|
<table class="body-action" align="center" width="100%" cellpadding="0" cellspacing="0">
|
||||||
<tr>
|
<tr>
|
||||||
{{ $col := index $data 0 }}
|
<td align="center">
|
||||||
{{ range $entry := $col }}
|
<div>
|
||||||
<th
|
<a href="{{ $action.Button.Link }}" class="button" style="background-color: {{ $action.Button.Color }}" target="_blank">
|
||||||
{{ with $columns }}
|
{{ $action.Button.Text }}
|
||||||
{{ $width := index .CustomWidth $entry.Key }}
|
</a>
|
||||||
{{ with $width }}
|
</div>
|
||||||
width="{{ . }}"
|
</td>
|
||||||
{{ end }}
|
|
||||||
{{ $align := index .CustomAlignement $entry.Key }}
|
|
||||||
{{ with $align }}
|
|
||||||
style="text-align:{{ . }}"
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
>
|
|
||||||
<p>{{ $entry.Key }}</p>
|
|
||||||
</th>
|
|
||||||
{{ end }}
|
|
||||||
</tr>
|
</tr>
|
||||||
{{ range $row := $data }}
|
|
||||||
<tr>
|
|
||||||
{{ range $cell := $row }}
|
|
||||||
<td
|
|
||||||
{{ with $columns }}
|
|
||||||
{{ $align := index .CustomAlignement $cell.Key }}
|
|
||||||
{{ with $align }}
|
|
||||||
style="text-align:{{ . }}"
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
>
|
|
||||||
{{ $cell.Value }}
|
|
||||||
</td>
|
|
||||||
{{ end }}
|
|
||||||
</tr>
|
|
||||||
{{ end }}
|
|
||||||
</table>
|
</table>
|
||||||
</td>
|
{{ end }}
|
||||||
</tr>
|
{{ end }}
|
||||||
</table>
|
{{ end }}
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
<!-- Action -->
|
{{ with .Email.Body.Outros }}
|
||||||
{{ with .Email.Body.Actions }}
|
{{ if gt (len .) 0 }}
|
||||||
{{ if gt (len .) 0 }}
|
{{ range $line := . }}
|
||||||
{{ range $action := . }}
|
<p>{{ $line }}</p>
|
||||||
<p>{{ $action.Instructions }}</p>
|
{{ end }}
|
||||||
<table class="body-action" align="center" width="100%" cellpadding="0" cellspacing="0">
|
{{ end }}
|
||||||
<tr>
|
{{ end }}
|
||||||
<td align="center">
|
|
||||||
<div>
|
|
||||||
<a href="{{ $action.Button.Link }}" class="button" style="background-color: {{ $action.Button.Color }}" target="_blank">{{ $action.Button.Text }}</a>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ with .Email.Body.Outros }}
|
<p>
|
||||||
{{ if gt (len .) 0 }}
|
{{.Email.Body.Signature}},
|
||||||
{{ range $line := . }}
|
<br />
|
||||||
<p>{{ $line }}</p>
|
{{.Hermes.Product.Name}}
|
||||||
{{ end }}
|
</p>
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
<p>
|
{{ with .Email.Body.Actions }}
|
||||||
{{.Email.Body.Signature}},
|
<table class="body-sub">
|
||||||
<br>
|
<tbody>
|
||||||
{{.Hermes.Product.Name}}
|
<tr>
|
||||||
</p>
|
{{ range $action := . }}
|
||||||
|
<td>
|
||||||
{{ with .Email.Body.Actions }}
|
<p class="sub">If you’re having trouble with the button '{{ $action.Button.Text }}', copy and paste the URL below into your web browser.</p>
|
||||||
<table class="body-sub">
|
<p class="sub"><a href="{{ $action.Button.Link }}">{{ $action.Button.Link }}</a></p>
|
||||||
<tbody><tr>
|
</td>
|
||||||
{{ range $action := . }}
|
{{ end }}
|
||||||
<td>
|
</tr>
|
||||||
<p class="sub">If you’re having trouble with the button '{{ $action.Button.Text }}', copy and paste the URL below into your web browser.</p>
|
</tbody>
|
||||||
<p class="sub"><a href="{{ $action.Button.Link }}">{{ $action.Button.Link }}</a></p>
|
</table>
|
||||||
</td>
|
{{ end }}
|
||||||
{{ end }}
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
{{ end }}
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -124,7 +124,7 @@ func setDefaultHermesValues(h *Hermes) error {
|
||||||
Copyright: "Copyright © 2017 Hermes. All rights reserved.",
|
Copyright: "Copyright © 2017 Hermes. All rights reserved.",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
// Merge the given hermes engine coniguration with default one
|
// Merge the given hermes engine configuration with default one
|
||||||
// Default one overrides all zero values
|
// Default one overrides all zero values
|
||||||
err := mergo.Merge(h, defaultHermes)
|
err := mergo.Merge(h, defaultHermes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in New Issue