Skip to content

Commit

Permalink
feat: add more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
matcornic committed Mar 30, 2017
1 parent ce121a8 commit aed8caf
Show file tree
Hide file tree
Showing 4 changed files with 595 additions and 18 deletions.
323 changes: 323 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,323 @@
# Contributing

Thanks so much for wanting to help! We really appreciate it.

* Have an idea for a new feature?
* Want to add a new built-in theme?

Excellent! You've come to the right place.

1. If you find a bug or wish to suggest a new feature, please create an issue first
2. Make sure your code & comment conventions are in-line with the project's style (execute gometalinter as in [.travis.yml](.travis.yml) file)
3. Make your commits and PRs as tiny as possible - one feature or bugfix at a time
4. Write detailed commit messages, in-line with the project's commit naming conventions

## Theming Instructions

This file contains instructions on adding themes to Mailgen:

* [Using a Custom Theme](#using-a-custom-theme)
* [Creating a Built-In Theme](#creating-a-built-in-theme)

> We use Golang templates under the hood to inject the e-mail body into themes.
### 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):

1. Create a new struct implementing `Theme` interface ([hermes.go](hermes.go)). An real-life example is in [default.go](default.go)
2. Supply your new theme at hermes creation

```go

type MyCustomTheme struct{}

func (dt *MyCustomTheme) Name() string {
return "mycustomthem"
}

func (dt *MyCustomTheme) HTMLTemplate() string {
// Get the template from a file (if you want to be able to change the template live without retstarting your application)
// Or write the template by returning pure string here (if you want embbeded template and do not bother with external dependencies)
return "<A go html template with wanted information>"
}

func (dt *Default) PlainTextTemplate() string {
// Get the template from a file (if you want to be able to change the template live without retstarting your application)
// Or write the template by returning pure string here (if you want embbeded template and do not bother with external dependencies)
return "<A go plaintext template with wanter information>"
}

h := hermes.Hermes{
Theme: new(MyCustomTheme) // Set your fresh new theme here
Product: hermes.Product{
Name: "Hermes",
Link: "https://example-hermes.com/",
},
}

// ...
// Continue with the rest as usual, create your email and generate the content.
// ...
```

3. That's it.

### Creating a Built-In Theme

If you want to create a new **built-in** Mailgen theme:

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
3. Copy content of [default.go](default.go) file in new file and make any necessary changes
6. Scroll down to the [injection snippets](#injection-snippets) and copy and paste each code snippet into the relevant area of your template markup
7. Test the theme by running the `examples/*.js` scripts (insert your theme name in each script) and observing the template output in `preview.html`
8. Take a screenshot of your theme portraying each example and place it in `screenshots/{theme}/{example}.png`
9. Add the theme name, credit, and screenshots to the `README.md` file's [Supported Themes](README.md#supported-themes) section (copy one of the existing themes' markup and modify it accordingly)
7. Submit a pull request with your changes and we'll let you know if anything's missing!

Thanks again for your contribution!

# Injection Snippets

## Product Branding Injection

The following will inject either the product logo or name into the template.

```html
<a href="<%- product.link %>" target="_blank">
<% if (locals.product.logo) { %>
<img src="<%- product.logo %>" class="email-logo" />
<% } else { %>
<%- product.name %>
<% } %>
</a>
```

It's a good idea to add the following CSS declaration to set `max-height: 50px` for the logo:

```css
.email-logo {
max-height: 50px;
}
```

## Title Injection

The following will inject the e-mail title (Hi John Appleseed,) or a custom title provided by the user:

```html
<%- title %>
```

## Intro Injection

The following will inject the intro text (string or array) into the e-mail:

```html
<% if (locals.intro) { %>
<% intro.forEach(function (introItem) { -%>
<p><%- introItem %></p>
<% }) -%>
<% } %>
```

## Dictionary Injection

The following will inject a `<dl>` of key-value pairs into the e-mail:

```html
<!-- Dictionary -->
<% if (locals.dictionary) { %>
<dl class="dictionary">
<% for (item in dictionary) { -%>
<dt><%- item.charAt(0).toUpperCase() + item.slice(1) %>:</dt>
<dd><%- dictionary[item] %></dd>
<% } -%>
</dl>
<% } %>
```

It's a good idea to add this to the top of the template to improve the styling of the dictionary:

```css
/* Dictionary */
.dictionary {
width: 100%;
overflow: hidden;
margin: 0 auto;
padding: 0;
}
.dictionary dt {
clear: both;
color: #000;
font-weight: bold;
margin-right: 4px;
}
.dictionary dd {
margin: 0 0 10px 0;
}
```

## Table Injection

The following will inject the table into the e-mail:

```html
<!-- Table -->
<% if (locals.table) { %>
<table class="data-table" width="100%" cellpadding="0" cellspacing="0">
<tr>
<% for (var column in table.data[0]) {%>
<th
<% if(locals.table.columns && locals.table.columns.customWidth && locals.table.columns.customWidth[column]) { %>
width="<%= table.columns.customWidth[column] %>"
<% } %>
<% if(locals.table.columns && locals.table.columns.customAlignment && locals.table.columns.customAlignment[column]) { %>
style="text-align:<%= table.columns.customAlignment[column] %>"
<% } %>
>
<p><%- column.charAt(0).toUpperCase() + column.slice(1) %></p>
</th>
<% } %>
</tr>
<% for (var i in table.data) {%>
<tr>
<% for (var column in table.data[i]) {%>
<td
<% if(locals.table.columns && locals.table.columns.customAlignment && locals.table.columns.customAlignment[column]) { %>
style="text-align:<%= table.columns.customAlignment[column] %>"
<% } %>
>
<%- table.data[i][column] %>
</td>
<% } %>
</tr>
<% } %>
</table>
<% } %>
```

It's a good idea to add this to the top of the template to improve the styling of the table:

```css
/* Table */
.data-wrapper {
width: 100%;
margin: 0;
padding: 35px 0;
}
.data-table {
width: 100%;
margin: 0;
}
.data-table th {
text-align: left;
padding: 0px 5px;
padding-bottom: 8px;
border-bottom: 1px solid #DEDEDE;
}
.data-table th p {
margin: 0;
font-size: 12px;
}
.data-table td {
text-align: left;
padding: 10px 5px;
font-size: 15px;
line-height: 18px;
}
```

## Action Injection

The following will inject the action link (or button) into the e-mail:

```html
<!-- Action -->
<% if (locals.action) { %>
<% action.forEach(function (actionItem) { -%>
<p><%- actionItem.instructions %></p>
<a href="<%- actionItem.button.link %>" style="color:<%- actionItem.button.color %>" target="_blank">
<%- actionItem.button.text %>
</a>
<% }) -%>
<% } %>
```

It's a good idea to add this to the top of the template to specify a fallback color for the action buttons in case it wasn't provided by the user:

```html
<%
if (locals.action) {
// Make it possible to override action button color (specify fallback color if no color specified)
locals.action.forEach(function(actionItem) {
if (!actionItem.button.color) {
actionItem.button.color = '#48CFAD';
}
});
}
%>
```

## Outro Injection

The following will inject the outro text (string or array) into the e-mail:

```html
<% if (locals.outro) { %>
<% outro.forEach(function (outroItem) { -%>
<p><%- outroItem %></p>
<% }) -%>
<% } %>
```

## Signature Injection

The following will inject the signature phrase (e.g. Yours truly) along with the product name into the e-mail:

```html
<%- signature %>,
<br />
<%- product.name %>
```

## Copyright Injection

The following will inject the copyright notice into the e-mail:

```html
<%- product.copyright %>
```

## Go-To Action Injection

In order to support Gmail's [Go-To Actions](https://developers.google.com/gmail/markup/reference/go-to-action), add the following anywhere within the template:

```html
<!-- Support for Gmail Go-To Actions -->
<% if (locals.goToAction) { %>
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "EmailMessage",
"potentialAction": {
"@type": "ViewAction",
"url": "<%- goToAction.link %>",
"target": "<%- goToAction.link %>",
"name": "<%- goToAction.text %>"
},
"description": "<%- goToAction.description %>"
}
</script>
<% } %>
```

## Text Direction Injection

In order to support generating RTL e-mails, inject the `textDirection` variable into the `<body>` tag:

```html
<body dir="<%- textDirection %>">
```

14 changes: 3 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

[![Build Status](https://travis-ci.org/matcornic/hermes.svg?branch=master)](https://travis-ci.org/matcornic/hermes)
[![Go Report Card](https://goreportcard.com/badge/github.com/matcornic/hermes)](https://goreportcard.com/report/github.com/matcornic/hermes)
[![Go Coverage](http://gocover.io/_badge/github.com/matcornic/hermes/)](http://gocover.io/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 !
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).
Expand Down Expand Up @@ -257,17 +259,7 @@ email := hermes.Email{
## Contributing

Thanks so much for wanting to help! We really appreciate it.

* Have an idea for a new feature?
* Want to add a new built-in theme?

Excellent! You've come to the right place.

1. If you find a bug or wish to suggest a new feature, please create an issue first
2. Make sure your code & comment conventions are in-line with the project's style
3. Make your commits and PRs as tiny as possible - one feature or bugfix at a time
4. Write detailed commit messages, in-line with the project's commit naming conventions
See [CONTRIBUTING.md](CONTRIBUTING.md)

## License

Expand Down
4 changes: 2 additions & 2 deletions default.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ func (dt *Default) HTMLTemplate() string {

// PlainTextTemplate returns a Golang template that will generate an plain text email.
func (dt *Default) PlainTextTemplate() string {
return `{{.Email.Body.Greeting}} {{.Email.Body.Name}},
return `{{if .Email.Body.Title }}{{ .Email.Body.Title }}{{ else }}{{ .Email.Body.Greeting }} {{ .Email.Body.Name }},{{ end }},
{{ with .Email.Body.Intros }}{{ range $line := . }}{{ $line }}{{ end }}{{ end }}
{{ with .Email.Body.Dictionary }}{{ range $entry := . }}
{{ $entry.Key }}: {{ $entry.Value }}{{ end }}{{ end }}
Expand All @@ -390,7 +390,7 @@ func (dt *Default) PlainTextTemplate() string {
{{ $line }}{{ end }}{{ end }}
{{.Email.Body.Signature}},
{{.Hermes.Product.Name}}
{{.Hermes.Product.Name}} - {{.Hermes.Product.Link}}
{{.Hermes.Product.Copyright}}
`
Expand Down
Loading

0 comments on commit aed8caf

Please sign in to comment.