@@ -12,6 +12,7 @@ import (
1212 "github.com/jmoiron/sqlx"
1313 "github.com/jmoiron/sqlx/types"
1414 "github.com/lib/pq"
15+ "github.com/preslavrachev/gomjml/mjml"
1516 null "gopkg.in/volatiletech/null.v6"
1617)
1718
@@ -29,6 +30,7 @@ const (
2930 CampaignContentTypeMarkdown = "markdown"
3031 CampaignContentTypePlain = "plain"
3132 CampaignContentTypeVisual = "visual"
33+ CampaignContentTypeMJML = "mjml"
3234)
3335
3436// Campaigns represents a slice of Campaigns.
@@ -156,28 +158,46 @@ func (c *Campaign) CompileTemplate(f template.FuncMap) error {
156158
157159 // Compile the base template.
158160 body := c .TemplateBody
161+ hasBaseTpl := body != ""
159162
160- if body == "" || c .ContentType == CampaignContentTypeVisual {
163+ if ! hasBaseTpl || c .ContentType == CampaignContentTypeVisual {
161164 body = `{{ template "content" . }}`
162165 }
163166
164167 for _ , r := range regTplFuncs {
165168 body = r .regExp .ReplaceAllString (body , r .replace )
166169 }
167170
171+ // For an MJML campaign, the entire body is one MJML document. Substitute
172+ // the campaign body for the `{{ template "content" . }}` placeholder in
173+ // the base, then run mjml.Render once.
174+ if c .ContentType == CampaignContentTypeMJML {
175+ b := regexpTplTag .ReplaceAllLiteralString (body , c .Body )
176+ htmlBody , err := mjml .Render (b )
177+ if err != nil {
178+ return fmt .Errorf ("error compiling MJML: %v" , err )
179+ }
180+ body = htmlBody
181+ }
182+
168183 baseTPL , err := template .New (BaseTpl ).Funcs (f ).Parse (body )
169184 if err != nil {
170185 return fmt .Errorf ("error compiling base template: %v" , err )
171186 }
172187
173- // If the format is markdown, convert Markdown to HTML.
174- if c .ContentType == CampaignContentTypeMarkdown {
188+ // Pick the body to assign to the `content` sub-template.
189+ switch c .ContentType {
190+ case CampaignContentTypeMJML :
191+ body = ""
192+
193+ case CampaignContentTypeMarkdown :
175194 var b bytes.Buffer
176195 if err := markdown .Convert ([]byte (c .Body ), & b ); err != nil {
177196 return err
178197 }
179198 body = b .String ()
180- } else {
199+
200+ default :
181201 body = c .Body
182202 }
183203
@@ -258,12 +278,19 @@ func (c *Campaign) ConvertContent(from, to string) (string, error) {
258278 // If the format is markdown, convert Markdown to HTML.
259279 var out string
260280 if from == CampaignContentTypeMarkdown &&
261- (to == CampaignContentTypeHTML || to == CampaignContentTypeRichtext ) {
281+ (to == CampaignContentTypeHTML || to == CampaignContentTypeRichtext || to == CampaignContentTypeMJML ) {
262282 var b bytes.Buffer
263283 if err := markdown .Convert ([]byte (c .Body ), & b ); err != nil {
264284 return out , err
265285 }
266286 out = b .String ()
287+ } else if from == CampaignContentTypeMJML &&
288+ (to == CampaignContentTypeHTML || to == CampaignContentTypeRichtext ) {
289+ htmlBody , err := mjml .Render (c .Body )
290+ if err != nil {
291+ return out , fmt .Errorf ("error converting MJML: %v" , err )
292+ }
293+ out = htmlBody
267294 } else {
268295 return out , errors .New ("unknown formats to convert" )
269296 }
0 commit comments