@@ -140,34 +140,15 @@ func (camps Campaigns) LoadStats(stmt *sqlx.Stmt) error {
140140// CompileTemplate compiles a campaign body template into its base
141141// template and sets the resultant template to Campaign.Tpl.
142142func (c * Campaign ) CompileTemplate (f template.FuncMap ) error {
143- // If the subject line has a template string, compile it.
144- if hasTplExpr (c .Subject ) {
145- subj := c .Subject
146- for _ , r := range regTplFuncs {
147- subj = r .regExp .ReplaceAllString (subj , r .replace )
148- }
149-
150- var txtFuncs map [string ]any = f
151- subjTpl , err := txttpl .New (ContentTpl ).Funcs (txtFuncs ).Parse (subj )
152- if err != nil {
153- return fmt .Errorf ("error compiling subject: %v" , err )
154- }
155- c .SubjectTpl = subjTpl
143+ var err error
144+ c .SubjectTpl , err = compileTxtTpl ("subject" , c .Subject , f )
145+ if err != nil {
146+ return err
156147 }
157148
158- // If the From header has a template string, compile it.
159- if hasTplExpr (c .FromEmail ) {
160- from := c .FromEmail
161- for _ , r := range regTplFuncs {
162- from = r .regExp .ReplaceAllString (from , r .replace )
163- }
164-
165- var txtFuncs map [string ]any = f
166- fromTpl , err := txttpl .New (ContentTpl ).Funcs (txtFuncs ).Parse (from )
167- if err != nil {
168- return fmt .Errorf ("error compiling from: %v" , err )
169- }
170- c .FromEmailTpl = fromTpl
149+ c .FromEmailTpl , err = compileTxtTpl ("from" , c .FromEmail , f )
150+ if err != nil {
151+ return err
171152 }
172153
173154 // Compile the base template.
@@ -213,7 +194,7 @@ func (c *Campaign) CompileTemplate(f template.FuncMap) error {
213194 }
214195 c .Tpl = out
215196
216- if hasTplExpr (c .AltBody .String ) {
197+ if HasTplExpr (c .AltBody .String ) {
217198 b := c .AltBody .String
218199 for _ , r := range regTplFuncs {
219200 b = r .regExp .ReplaceAllString (b , r .replace )
@@ -228,7 +209,7 @@ func (c *Campaign) CompileTemplate(f template.FuncMap) error {
228209 // Compile any header values that contain template expressions.
229210 for _ , set := range c .Headers {
230211 for _ , val := range set {
231- if hasTplExpr (val ) {
212+ if HasTplExpr (val ) {
232213 c .HeaderTpls = make ([]map [string ]* txttpl.Template , len (c .Headers ))
233214 break
234215 }
@@ -242,25 +223,36 @@ func (c *Campaign) CompileTemplate(f template.FuncMap) error {
242223 for i , set := range c .Headers {
243224 c .HeaderTpls [i ] = make (map [string ]* txttpl.Template , len (set ))
244225 for hdr , val := range set {
245- if ! hasTplExpr (val ) {
246- continue
247- }
248- tpl , err := txttpl .New (ContentTpl ).Funcs (txtFuncs ).Parse (val )
226+ tpl , err := compileTxtTpl (fmt .Sprintf ("header %q" , hdr ), val , txtFuncs )
249227 if err != nil {
250- return fmt .Errorf ("error compiling header %q: %v" , hdr , err )
228+ return err
229+ }
230+ if tpl != nil {
231+ c.HeaderTpls [i ][hdr ] = tpl
251232 }
252- c.HeaderTpls [i ][hdr ] = tpl
253233 }
254234 }
255235 }
256236
257237 return nil
258238}
259239
260- // hasTplExpr checks whether a given string has a Go template expression with {{ and }}.
261- func hasTplExpr (s string ) bool {
262- _ , after , ok := strings .Cut (s , "{{" )
263- return ok && strings .Contains (after , "}}" )
240+ func compileTxtTpl (label , val string , f template.FuncMap ) (* txttpl.Template , error ) {
241+ if ! HasTplExpr (val ) {
242+ return nil , nil
243+ }
244+
245+ for _ , r := range regTplFuncs {
246+ val = r .regExp .ReplaceAllString (val , r .replace )
247+ }
248+
249+ var txtFuncs map [string ]any = f
250+ tpl , err := txttpl .New (ContentTpl ).Funcs (txtFuncs ).Parse (val )
251+ if err != nil {
252+ return nil , fmt .Errorf ("error compiling %s: %v" , label , err )
253+ }
254+
255+ return tpl , nil
264256}
265257
266258// ConvertContent converts a campaign's body from one format to another,
@@ -286,3 +278,9 @@ func (c *Campaign) ConvertContent(from, to string) (string, error) {
286278
287279 return out , nil
288280}
281+
282+ // HasTplExpr checks whether a given string has a Go template expression with {{ and }}.
283+ func HasTplExpr (s string ) bool {
284+ _ , after , ok := strings .Cut (s , "{{" )
285+ return ok && strings .Contains (after , "}}" )
286+ }
0 commit comments