mirror of
https://github.com/wneessen/go-mail.git
synced 2024-11-08 23:12:54 +01:00
#13: Both html/template and text/template support added
- Switched the previous implementation to support text/template as well as html/template - Added SetBody*Template() methods to use a template directly as message body - Added AddAlternative*Template() methods to use a template directly as alternative message part
This commit is contained in:
parent
f24a86a4c6
commit
8919d64ca1
1 changed files with 100 additions and 17 deletions
117
msg.go
117
msg.go
|
@ -5,7 +5,7 @@ import (
|
|||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"html/template"
|
||||
ht "html/template"
|
||||
"io"
|
||||
"math/rand"
|
||||
"mime"
|
||||
|
@ -14,6 +14,7 @@ import (
|
|||
"os/exec"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
tt "text/template"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -390,10 +391,7 @@ func (m *Msg) GetRecipients() ([]string, error) {
|
|||
// SetBodyString sets the body of the message.
|
||||
func (m *Msg) SetBodyString(ct ContentType, b string, o ...PartOption) {
|
||||
buf := bytes.NewBufferString(b)
|
||||
w := func(w io.Writer) (int64, error) {
|
||||
nb, err := w.Write(buf.Bytes())
|
||||
return int64(nb), err
|
||||
}
|
||||
w := writeFuncFromBuffer(buf)
|
||||
m.SetBodyWriter(ct, w, o...)
|
||||
}
|
||||
|
||||
|
@ -404,13 +402,34 @@ func (m *Msg) SetBodyWriter(ct ContentType, w func(io.Writer) (int64, error), o
|
|||
m.parts = []*Part{p}
|
||||
}
|
||||
|
||||
// SetBodyHTMLTemplate sets the body of the message from a given html/template.Template pointer
|
||||
// The content type will be set to text/html automatically
|
||||
func (m *Msg) SetBodyHTMLTemplate(t *ht.Template, d interface{}, o ...PartOption) error {
|
||||
buf := bytes.Buffer{}
|
||||
if err := t.Execute(&buf, d); err != nil {
|
||||
return fmt.Errorf("failed to execute template: %w", err)
|
||||
}
|
||||
w := writeFuncFromBuffer(&buf)
|
||||
m.SetBodyWriter(TypeTextHTML, w, o...)
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetBodyTextTemplate sets the body of the message from a given text/template.Template pointer
|
||||
// The content type will be set to text/plain automatically
|
||||
func (m *Msg) SetBodyTextTemplate(t *tt.Template, d interface{}, o ...PartOption) error {
|
||||
buf := bytes.Buffer{}
|
||||
if err := t.Execute(&buf, d); err != nil {
|
||||
return fmt.Errorf("failed to execute template: %w", err)
|
||||
}
|
||||
w := writeFuncFromBuffer(&buf)
|
||||
m.SetBodyWriter(TypeTextPlain, w, o...)
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddAlternativeString sets the alternative body of the message.
|
||||
func (m *Msg) AddAlternativeString(ct ContentType, b string, o ...PartOption) {
|
||||
buf := bytes.NewBufferString(b)
|
||||
w := func(w io.Writer) (int64, error) {
|
||||
nb, err := w.Write(buf.Bytes())
|
||||
return int64(nb), err
|
||||
}
|
||||
w := writeFuncFromBuffer(buf)
|
||||
m.AddAlternativeWriter(ct, w, o...)
|
||||
}
|
||||
|
||||
|
@ -421,6 +440,30 @@ func (m *Msg) AddAlternativeWriter(ct ContentType, w func(io.Writer) (int64, err
|
|||
m.parts = append(m.parts, p)
|
||||
}
|
||||
|
||||
// AddAlternativeHTMLTemplate sets the alternative body of the message to a html/template.Template output
|
||||
// The content type will be set to text/html automatically
|
||||
func (m *Msg) AddAlternativeHTMLTemplate(t *ht.Template, d interface{}, o ...PartOption) error {
|
||||
buf := bytes.Buffer{}
|
||||
if err := t.Execute(&buf, d); err != nil {
|
||||
return fmt.Errorf("failed to execute template: %w", err)
|
||||
}
|
||||
w := writeFuncFromBuffer(&buf)
|
||||
m.AddAlternativeWriter(TypeTextHTML, w, o...)
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddAlternativeTextTemplate sets the alternative body of the message to a text/template.Template output
|
||||
// The content type will be set to text/plain automatically
|
||||
func (m *Msg) AddAlternativeTextTemplate(t *tt.Template, d interface{}, o ...PartOption) error {
|
||||
buf := bytes.Buffer{}
|
||||
if err := t.Execute(&buf, d); err != nil {
|
||||
return fmt.Errorf("failed to execute template: %w", err)
|
||||
}
|
||||
w := writeFuncFromBuffer(&buf)
|
||||
m.AddAlternativeWriter(TypeTextPlain, w, o...)
|
||||
return nil
|
||||
}
|
||||
|
||||
// AttachFile adds an attachment File to the Msg
|
||||
func (m *Msg) AttachFile(n string, o ...FileOption) {
|
||||
f := fileFromFS(n)
|
||||
|
@ -436,9 +479,19 @@ func (m *Msg) AttachReader(n string, r io.Reader, o ...FileOption) {
|
|||
m.attachments = m.appendFile(m.attachments, f, o...)
|
||||
}
|
||||
|
||||
// AttachTemplate adds the output of a template.Template pointer as File attachment to the Msg
|
||||
func (m *Msg) AttachTemplate(n string, t *template.Template, d interface{}, o ...FileOption) error {
|
||||
f, err := fileFromTemplate(n, t, d)
|
||||
// AttachHTMLTemplate adds the output of a html/template.Template pointer as File attachment to the Msg
|
||||
func (m *Msg) AttachHTMLTemplate(n string, t *ht.Template, d interface{}, o ...FileOption) error {
|
||||
f, err := fileFromHTMLTemplate(n, t, d)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to attach template: %w", err)
|
||||
}
|
||||
m.attachments = m.appendFile(m.attachments, f, o...)
|
||||
return nil
|
||||
}
|
||||
|
||||
// AttachTextTemplate adds the output of a text/template.Template pointer as File attachment to the Msg
|
||||
func (m *Msg) AttachTextTemplate(n string, t *tt.Template, d interface{}, o ...FileOption) error {
|
||||
f, err := fileFromTextTemplate(n, t, d)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to attach template: %w", err)
|
||||
}
|
||||
|
@ -461,9 +514,19 @@ func (m *Msg) EmbedReader(n string, r io.Reader, o ...FileOption) {
|
|||
m.embeds = m.appendFile(m.embeds, f, o...)
|
||||
}
|
||||
|
||||
// EmbedTemplate adds the output of a template.Template pointer as embedded File to the Msg
|
||||
func (m *Msg) EmbedTemplate(n string, t *template.Template, d interface{}, o ...FileOption) error {
|
||||
f, err := fileFromTemplate(n, t, d)
|
||||
// EmbedHTMLTemplate adds the output of a html/template.Template pointer as embedded File to the Msg
|
||||
func (m *Msg) EmbedHTMLTemplate(n string, t *ht.Template, d interface{}, o ...FileOption) error {
|
||||
f, err := fileFromHTMLTemplate(n, t, d)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to embed template: %w", err)
|
||||
}
|
||||
m.embeds = m.appendFile(m.embeds, f, o...)
|
||||
return nil
|
||||
}
|
||||
|
||||
// EmbedTextTemplate adds the output of a text/template.Template pointer as embedded File to the Msg
|
||||
func (m *Msg) EmbedTextTemplate(n string, t *tt.Template, d interface{}, o ...FileOption) error {
|
||||
f, err := fileFromTextTemplate(n, t, d)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to embed template: %w", err)
|
||||
}
|
||||
|
@ -689,8 +752,18 @@ func fileFromReader(n string, r io.Reader) *File {
|
|||
}
|
||||
}
|
||||
|
||||
// fileFromTemplate returns a File pointer form a given template.Template
|
||||
func fileFromTemplate(n string, t *template.Template, d interface{}) (*File, error) {
|
||||
// fileFromHTMLTemplate returns a File pointer form a given html/template.Template
|
||||
func fileFromHTMLTemplate(n string, t *ht.Template, d interface{}) (*File, error) {
|
||||
buf := bytes.Buffer{}
|
||||
if err := t.Execute(&buf, d); err != nil {
|
||||
return nil, fmt.Errorf("failed to execute template: %w", err)
|
||||
}
|
||||
f := fileFromReader(n, &buf)
|
||||
return f, nil
|
||||
}
|
||||
|
||||
// fileFromTextTemplate returns a File pointer form a given text/template.Template
|
||||
func fileFromTextTemplate(n string, t *tt.Template, d interface{}) (*File, error) {
|
||||
buf := bytes.Buffer{}
|
||||
if err := t.Execute(&buf, d); err != nil {
|
||||
return nil, fmt.Errorf("failed to execute template: %w", err)
|
||||
|
@ -710,3 +783,13 @@ func getEncoder(e Encoding) mime.WordEncoder {
|
|||
return mime.QEncoding
|
||||
}
|
||||
}
|
||||
|
||||
// writeFuncFromBuffer is a common method to convert a byte buffer into a writeFunc as
|
||||
// often required by this library
|
||||
func writeFuncFromBuffer(buf *bytes.Buffer) func(io.Writer) (int64, error) {
|
||||
w := func(w io.Writer) (int64, error) {
|
||||
nb, err := w.Write(buf.Bytes())
|
||||
return int64(nb), err
|
||||
}
|
||||
return w
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue