about summary refs log tree commit diff stats
path: root/widgets
diff options
context:
space:
mode:
authorRobert Günzler <r@gnzler.io>2019-12-05 16:23:21 +0100
committerDrew DeVault <sir@cmpwn.com>2019-12-07 14:29:48 -0500
commite88cc08d792eef8c6785f0fba0eca63089e85f5f (patch)
treeb26def83c171fd0cbd541c6080e89e803df4d4b2 /widgets
parent74c13e84b74804f5fc5f2e37d4c9f1af57fc1403 (diff)
downloadaerc-e88cc08d792eef8c6785f0fba0eca63089e85f5f.tar.gz
Parse headers from template
This patch parses the processed template for headers and populates
matching header editors.
Those are then stripped from the template body before prepending the template
and remaining header fields to the composer content.

The main motivation for this is keeping receiver, sender and subject
lines in the template file and generating the message subject from the
date.
Diffstat (limited to 'widgets')
-rw-r--r--widgets/compose.go53
1 files changed, 50 insertions, 3 deletions
diff --git a/widgets/compose.go b/widgets/compose.go
index 62aaafe..24af18c 100644
--- a/widgets/compose.go
+++ b/widgets/compose.go
@@ -179,8 +179,7 @@ func (c *Composer) AddTemplate(template string, data interface{}) error {
 	if err != nil {
 		return err
 	}
-	c.PrependContents(bytes.NewReader(templateText))
-	return nil
+	return c.addTemplate(templateText)
 }
 
 func (c *Composer) AddTemplateFromString(template string, data interface{}) error {
@@ -192,7 +191,55 @@ func (c *Composer) AddTemplateFromString(template string, data interface{}) erro
 	if err != nil {
 		return err
 	}
-	c.PrependContents(bytes.NewReader(templateText))
+	return c.addTemplate(templateText)
+}
+
+func (c *Composer) addTemplate(templateText []byte) error {
+	reader, err := mail.CreateReader(bytes.NewReader(templateText))
+	if err != nil {
+		// encountering an error when reading the template probably
+		// means the template didn't evaluate to a properly formatted
+		// mail file.
+		// This is fine, we still want to support simple body tempaltes
+		// that don't include headers.
+		//
+		// Just prepend the rendered template in that case. This
+		// basically equals the previous behavior.
+		c.PrependContents(bytes.NewReader(templateText))
+		return nil
+	}
+	defer reader.Close()
+
+	// populate header editors
+	header := reader.Header
+	mhdr := (*message.Header)(&header.Header)
+	for _, editor := range c.editors {
+		if mhdr.Has(editor.name) {
+			editor.input.Set(mhdr.Get(editor.name))
+			// remove header fields that have editors
+			mhdr.Del(editor.name)
+		}
+	}
+
+	part, err := reader.NextPart()
+	if err != nil {
+		return errors.Wrap(err, "reader.NextPart")
+	}
+	c.PrependContents(part.Body)
+
+	var (
+		headers string
+		fds     = mhdr.Fields()
+	)
+	for fds.Next() {
+		headers += fmt.Sprintf("%s: %s\n", fds.Key(), fds.Value())
+	}
+	if headers != "" {
+		headers += "\n"
+	}
+
+	// prepend header fields without editors to message body
+	c.PrependContents(bytes.NewReader([]byte(headers)))
 	return nil
 }