Services like Mailchimp and MailerLite make it easy to create stylish email campaigns. Their templating tools allow you to create elegant HTML messages which are personalised to the recipient.
Wouldn’t it be cool if you could do something similar when sending emails from R? Well, with the latest version of {emayili}
, that’s now possible (although this feature is definitely in its infancy!).
We’ll start by loading {emayili}
and checking that we have the right version (anything beyond 0.7.4 will be fine).
library(emayili)
packageVersion("emayili")
[1] '0.7.4'
To install this version from GitHub you can use:
remotes::install_github("datawookie/emayili", "v0.7.4")
We’ll set a couple of options to ensure that we see the contents of a message as it’s built.
options(envelope.invisible = FALSE)
options(envelope.details = TRUE)
How Does It Work?
You can create a message template using the Jinja template syntax. The template is populated in R with the {jinjar}
package. For the purposes of {emayili}
templates must be stored in a separate directory and must be named either template.txt
or template.html
. We might implement a more flexible system in future, but this works for the moment.
Suppose I create a directory simple
and a file, template.html
, within it with the following content:
<p>Hello {{ name }}!</p>
There is one placeholder in the template for a variable called name
. To use the template in a message you’d call the template()
function, providing a reference to the template as well as values for any placeholders in the template. The template reference can be either:
- the name of a builtin template (part of
{emayili}
) - a relative path or
- an absolute path.
The paths must refer to the directory containing the template file, not the file itself.
Let’s try out our simple template and use "Bob"
for the value of name
.
envelope() %>%
template("./templates/simple", name = "Bob")
Date: Sun, 10 Nov 2024 06:12:31 GMT
X-Mailer: {emayili}-0.9.1
MIME-Version: 1.0
Content-Type: text/html;
charset=utf-8
<html><body><p>Hello Bob!</p></body></html>
The resulting message has the content of the template attached as an HTML body and the {{ name }}
placeholder has been replaced with the specified value. This is not too different to the {glue}
interpolation which is already supported in the text()
and html()
methods. However, there’s actually a lot of scope for doing more because the template syntax also supports some programming structures too like loops and conditionals.
Loops & Conditionals
Okay, so let’s get a little more sophisticated and create a template which uses a loop and a conditional.
{% if greet %}
<p>Hello!</p>
{% endif %}
{% for paragraph in text -%}
<p>{{ paragraph }}</p>
{% endfor %}
Nothing fancy, but it illustrates the principle. Let’s populate the template. Now we need to provide values for both greet
and text
.
envelope() %>%
template(
"./templates/loop-conditional",
greet = TRUE,
text = c(
"Lorem ipsum dolor sit amet, lacus nostra est, id, orci magna bibendum felis dis.",
"Ut laoreet tincidunt netus sed mi habitasse ut blandit, in, auctor nibh.",
"Sem dapibus rhoncus proin dolor, vitae diam sed."
)
)
Date: Sun, 10 Nov 2024 06:12:31 GMT
X-Mailer: {emayili}-0.9.1
MIME-Version: 1.0
Content-Type: text/html;
charset=utf-8
<html><body>
<p>Hello!</p>
<p>Lorem ipsum dolor sit amet, lacus nostra est, id, orci magna bibendum felis dis.</p>
<p>Ut laoreet tincidunt netus sed mi habitasse ut blandit, in, auctor nibh.</p>
<p>Sem dapibus rhoncus proin dolor, vitae diam sed.</p>
</body></html>
Example
Okay, so those examples were cute, but nothing that you’d actually use. I’ve included one template with {emayili}
which will generate a fairly attractive HTML message. The code for populating the template is a little lengthy, but you can look at it here.
This is what the resulting message looks like (as viewed in Thunderbird).
All of the content (text, images and links) was provided by template parameters, so it’s pretty flexible. The articles are populated via a loop, so you can include as many of them as you wish.
Conclusion
As I mentioned earlier, this feature is still pretty fresh and I’ve no doubt that there are bugs. However, I’m very excited about what’s now possible. You can now replicate services like Mailchimp or MailerLite from within R. The only constraints are your imagination and aesthetics (and I’m sorely lacking in the latter). If you create a template which you’d like included in {emayili}
, please swing it my way.