mirror of
https://github.com/knadh/listmonk.git
synced 2024-12-27 17:37:57 +08:00
Make static e-mail template subjects scriptable. Closes #1727.
This commit introduces optional, custom `<title>` tags that can be added to `static/email-templates/*.html` so as to make the subjectlines fully scriptable for system e-mails and notifications. The tag must look like this. ``` <title data-i18n>Stuff {{ .Subscriber.Name }} here!</title> ```
This commit is contained in:
parent
f04798a329
commit
124af1ee29
2 changed files with 31 additions and 5 deletions
|
@ -2,6 +2,8 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/knadh/listmonk/models"
|
"github.com/knadh/listmonk/models"
|
||||||
)
|
)
|
||||||
|
@ -13,6 +15,10 @@ const (
|
||||||
notifSubscriberData = "subscriber-data"
|
notifSubscriberData = "subscriber-data"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
reTitle = regexp.MustCompile(`(?s)<title\s*data-i18n\s*>(.+?)</title>`)
|
||||||
|
)
|
||||||
|
|
||||||
// notifData represents params commonly used across different notification
|
// notifData represents params commonly used across different notification
|
||||||
// templates.
|
// templates.
|
||||||
type notifData struct {
|
type notifData struct {
|
||||||
|
@ -26,18 +32,21 @@ func (app *App) sendNotification(toEmails []string, subject, tplName string, dat
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var b bytes.Buffer
|
var buf bytes.Buffer
|
||||||
if err := app.notifTpls.tpls.ExecuteTemplate(&b, tplName, data); err != nil {
|
if err := app.notifTpls.tpls.ExecuteTemplate(&buf, tplName, data); err != nil {
|
||||||
app.log.Printf("error compiling notification template '%s': %v", tplName, err)
|
app.log.Printf("error compiling notification template '%s': %v", tplName, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
body := buf.Bytes()
|
||||||
|
|
||||||
|
subject, body = getTplSubject(subject, body)
|
||||||
|
|
||||||
m := models.Message{}
|
m := models.Message{}
|
||||||
m.ContentType = app.notifTpls.contentType
|
m.ContentType = app.notifTpls.contentType
|
||||||
m.From = app.constants.FromEmail
|
m.From = app.constants.FromEmail
|
||||||
m.To = toEmails
|
m.To = toEmails
|
||||||
m.Subject = subject
|
m.Subject = subject
|
||||||
m.Body = b.Bytes()
|
m.Body = body
|
||||||
m.Messenger = emailMsgr
|
m.Messenger = emailMsgr
|
||||||
if err := app.manager.PushMessage(m); err != nil {
|
if err := app.manager.PushMessage(m); err != nil {
|
||||||
app.log.Printf("error sending admin notification (%s): %v", subject, err)
|
app.log.Printf("error sending admin notification (%s): %v", subject, err)
|
||||||
|
@ -45,3 +54,14 @@ func (app *App) sendNotification(toEmails []string, subject, tplName string, dat
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getTplSubject extrcts any custom i18n subject rendered in the given rendered
|
||||||
|
// template body. If it's not found, the incoming subject and body are returned.
|
||||||
|
func getTplSubject(subject string, body []byte) (string, []byte) {
|
||||||
|
m := reTitle.FindSubmatch(body)
|
||||||
|
if len(m) != 2 {
|
||||||
|
return subject, body
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.TrimSpace(string(m[1])), reTitle.ReplaceAll(body, []byte(""))
|
||||||
|
}
|
||||||
|
|
|
@ -590,14 +590,20 @@ func handleSelfExportSubscriberData(c echo.Context) error {
|
||||||
makeMsgTpl(app.i18n.T("public.errorTitle"), "", app.i18n.Ts("public.errorProcessingRequest")))
|
makeMsgTpl(app.i18n.T("public.errorTitle"), "", app.i18n.Ts("public.errorProcessingRequest")))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
subject = app.i18n.Ts("email.data.title")
|
||||||
|
body = msg.Bytes()
|
||||||
|
)
|
||||||
|
subject, body = getTplSubject(subject, body)
|
||||||
|
|
||||||
// Send the data as a JSON attachment to the subscriber.
|
// Send the data as a JSON attachment to the subscriber.
|
||||||
const fname = "data.json"
|
const fname = "data.json"
|
||||||
if err := app.messengers[emailMsgr].Push(models.Message{
|
if err := app.messengers[emailMsgr].Push(models.Message{
|
||||||
ContentType: app.notifTpls.contentType,
|
ContentType: app.notifTpls.contentType,
|
||||||
From: app.constants.FromEmail,
|
From: app.constants.FromEmail,
|
||||||
To: []string{data.Email},
|
To: []string{data.Email},
|
||||||
Subject: app.i18n.Ts("email.data.title"),
|
Subject: subject,
|
||||||
Body: msg.Bytes(),
|
Body: body,
|
||||||
Attachments: []models.Attachment{
|
Attachments: []models.Attachment{
|
||||||
{
|
{
|
||||||
Name: fname,
|
Name: fname,
|
||||||
|
|
Loading…
Reference in a new issue