Before we get to the process of creating an HTML email message, it’s a good idea to learn about the model of such a message in blastula. Here is a diagram, and it doesn’t contain too many layout components (because simplicity in HTML email is a good thing).
The main components (from top to bottom) are the header, the body, and the footer. The body content is inside of a wrapper that functions to differentiate the main content from whatever is in the header and footer (above and below the body).
Another thing to note is that the HTML used is responsive. Viewing the HTML in a viewport that is greater than or equal to 640 pixels will be different than seeing it with a viewport that’s smaller. This is important because email on mobile devices will often take on the latter view, which is optimized for smaller display widths (e.g., larger font sizes, decreased vertical space between elements, resized images, etc.).
When using blastula, we don’t have to worry much about either view since the API is designed to make emails look their best in both of them. Because we can preview the email message before sending it out, we have a chance to manually resize the browser and inspect the message in a variety of display widths.
For those times where we’d only want to send a simple HTML email
message, we can use the compose_email()
function and focus
on adding text content to the body component. So let’s
create a simple email message using some plain text inside
body
.
compose_email(
body =
"Hello,
I just wanted to let you know that the thing that you asked me for is ready to pick up. So, come over and do that.
Cheers
")
This is how it looks, depending on the display width (wide at top, narrow below that).
A preview of the HTML email message should appear in the Viewer. Try resizing the Viewer to see how it responds to the different width thresholds.
A good strategy for longer and more complicated text inputs is to use
the glue
package. That package allows us to use string interpolation (and avoid
the use of paste()
or paste0()
). Variables in
the global workspace can be included in the curly braces of a
glue()
string expression, and, any R
expressions in { }
will be evaluated.
We can include longer R statements inside of the
curly braces (like
{paste0(format(Sys.time(), "%A, %B "), format(Sys.time(), "%d") %>% as.numeric(), ", ", format(Sys.time(), "%Y"))}
),
however, that would be unwieldy. It’s better to generate local variables
with R statements and just use those variables inside
the { }
.
Here is an example of the same email message body as in the last example, but using glue to preprocess our text:
what <- "thing"
salutation <- "Cheers"
body_text <-
glue(
"
Hello,
I just wanted to let you know that the {what}
that you asked me for is ready to pick up. So,
come over and do that.
{salutation}
"
)
compose_email(body = body_text)
Any literal quotation marks inside the braces should be escaped using
a single \
. Blank lines separating blocks of text result in
new paragraphs.
md()
Function
Markdown text can be used as input for the body
,
header
, and footer
arguments. To opt into
using Markdown formatting, call the md()
text helper
function on any of these text elements. We can use the usual
Markdown-formatting you know and you’ll get italicized text, bold text,
lists, links, etc. Have a look at this reference page to quickly
understand how to use Markdown. The blastula package
internally uses the commonmark R
package to perform the conversion from Markdown to HTML.
A few notes on code style and options. It’s good to left-align the
text in the code example since it will reduce the risk of having four or
more spaces after a line break, which will result in
text like this
when using Markdown formatting through
md()
.
In the next example, let’s first store the result of that statement
in a local variable (sending_date
). Then, the variable will
be placed in the footer of the message (using the
footer
argument) along with leading text.
# Prepare the text inputs
sender_name <- "Shelly"
sending_date <-
paste0(
format(Sys.time(), "%A, %B "),
format(Sys.time(), "%d") %>% as.numeric(),
", ",
format(Sys.time(), "%Y")
)
# Generate the body text
body_text <-
md(glue(
"
Hello,
I just wanted to let you know that the *thing* that
you asked me for is ready to pick up. So, come over
and do that.
Cheers,
{sender_name}
"
))
# Generate the footer text
footer_text <- glue("Sent on {sending_date}.")
# Compose the email message
compose_email(
body = body_text,
footer = footer_text
)
Complicated string formatting goes into variables, the variables go into the email components
Content in the footer and header sections is styled differently than body content (footer text will be somewhat smaller for one thing). The main message typically goes into the body whereas supplementary information works better in the footer.
The blastula package has the
add_image()
function which allows one to add images to an
email message. What add_image
does is generate an HTML
fragment (a piece of HTML that can be included in an HTML document) with
the image transformed to text (using Base64 encoding). Knowing that we
have an HTML fragment is important because it means we need to use the
md()
function to interpret the content as Markdown/HTML (a
Markdown parser will leave any HTML that it sees untouched).
# Prepare the image (as a text input)
img_file_path <-
system.file(
"img", "rickenbacker_4001_1972.jpg",
package = "blastula"
)
image <- add_image(file = img_file_path)
# Generate the body text
body_text <-
md(glue(
"
Hello,
I just wanted to let you know that the **1972 Rickenbacker
4001** is here to pick up. Here is a picture of it:
{image}
Cheers,
{sender_name}
"
))
# Compose the email message
compose_email(body = body_text)
Once you get the hang of add_image()
, this is really easy
There’s also the add_ggplot()
function which can add a
ggplot2 plot object to a message body. Here’s an
example of how that works:
# Create the plot data
variety <- rep(LETTERS[1:7], each = 40)
treatment <- rep(c("high", "low"), each = 20)
note <- seq(1:280) + sample(1:150, 280, replace = TRUE)
data <- data.frame(variety, treatment, note)
# Create the plot
gg <-
ggplot(data, aes(x = variety, y = note, fill = treatment)) +
geom_boxplot()
# Prepare the image (as a text input)
gg_image <- add_ggplot(plot_object = gg)
# Generate the body text
body_text <-
md(glue(
"
Hello,
I just wanted to let you know that the *ggplot* you \\
wanted to see is right here, in this email:
{gg_image}
Cheers,
{sender_name}
"
))
# Compose the email message
compose_email(body = body_text)
A ggplot in your email message
I don’t know about you but I’d love to get a ggplot in my email.