A mailplate template is generally divided into two parts:
- auto-selection criteria;
- and mail message (which in turn is split into headers, body, and signature)
When you start up mailplate for the first time, a
default template will be generated, along with a default configuration file.
The following is one of my templates, which shows off most of the functionality:
1: * 10 ^(?:To|Cc|From): .+@(?:.+\.)*debian\.(org|net)
2: * 8 ^(?:To|Cc): .+@(?:.+\.)*backports\.org
3: * 8 ^(?:To|Cc): .+@(?:.+\.)*debconf\.org
4: From: martin f krafft <madduck@deXXXn.org>
5: @KEEP_STD_HEADERS
6: Organization: The Debian project
7: X-OS: Debian GNU/Linux $(get_debian_version) kernel $(get_kernel)
8: X-Motto: Keep the good times rollin'
9:
10: @KEEP_BODY
11:
12: --
13: .''`. martin f. krafft <madduck@deXXXn.org>
14: : :' : proud Debian developer, author, administrator, and user
15: `. `'` http://people.debian.org/~madduck - http://debiansystem.info
16: `- Debian - when you have better things to do than fixing systems
17:
18: $(get_quote)
Let’s see if we can make sense of these 18 lines:
-
1-3: prefixed by
*and a number, these lines define (Python) regular expressions (which are ugly, yes, I know…), which helpmailplate --automake a decision as to which template to use. Selection works on a simple scoring system: the template with the highest cumulative score gets used. Regular expressions are matched case-insensitively.In this case, if you are drafting a mail from a
debian.orgaddress and addressed to adebconf.orgaddress, the score would be 18, since the first and third regular expressions matched. -
4-8: these lines define the mail header.
-
5:
@KEEP_STD_HEADERSis one of three header slots you can use:KEEP_FROM_HEADER: preserves theFrom:header from the existing mail (which effectively disables mutt’s reverse_name setting; use with caution!KEEP_STD_HEADERS: preserves theTo/Cc/Bcc/Subject/Reply-To/In-Reply-Toheaders.KEEP_ALL_HEADERS: equivalent to the previous two combined.
In addition, you can preserve any existing header by adding a line such as
X-Debbugs-Cc: @KEEP
to the template, which will cause the
X-Debbugs-Ccheader to be preserved, if present, but not added if not present in the mail you feed tomailplate. If you find yourself using this a lot, considermailplate’s--keep-unknownoption.Note that ordering is of relevance. For instance, if you want to override the
Reply-Toheader but also useKEEP_STD_HEADERS, you have to put it underKEEP_STD_HEADERSin the template. Headers are read top-to-bottom and later ones overwrite earlier ones. -
7: a construct like
$(get_debian_version)will get replaced with the output of that command, which has to be defined in the configuration file in order to be usable. -
10:
@KEEP_BODYis another slot, which gets replaced by the entire body of the message, up until the signature, if one exists. -
12-18: these define the signature to use for mails sent with this identity. In line 18, another command is used, just like in line 7. The slot
@KEEP_SIGNATUREcould be used to preserve an existing signature.
Advanced interpolation
As you can see from the above, mailplate can
interpolate parts of the template, and it wouldn’t be much use if
it could not. But it gets better: mailplate can also
interpolate two additional types of data sources. We shall use
another, contrived example to show this off:
1: * 1 ^(?:To|Cc): (?P<rname>[^ ]+).+$
2: @KEEP_ALL_HEADERS
3:
4: Hello %(rname)s,
5:
6: my shell of choice is ${SHELL}.
7:
8: --·
9: martin
-
1: again, a regular expression, but this time we use a names group
rnameto store the recipient’s first name (up until the first space). -
2: keeps all headers
-
4: this now uses the named match of the regular expression, Python style. Note that this also works when
--autois not run, meaning that the regular expressions are still run even if you explicitly select a template. -
6: yes, we can also interpolate from the standard environment.
Running commands during scoring
Instead of regular expressions, you can also run commands during
the automatic template selection process. If the command returns
with a zero exit code, the score is added. Commands are executed by
the shell, and they have to swallow stdin, which is
arguably a bit bulky and could be improved, but:
! 99 cat; case "$(date +%a)" in Sat|Sun) exit 0;; esac; exit 1
@KEEP_ALL_HEADERS
I don't work on weekends!
--
martin
A more sensible use-case would be to call egrep in
case you hate Python regular expressions (like me).

