RObservations #42: Using the jinjar and tidyRSS packages to make a simple newsletter template

[This article was first published on r – bensstats, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Introduction

Jinja is a powerful templating engine that is useful in a variety of contexts. Recently, I discovered how its possible to use the power of Jinja syntax in R with the jinjar package written by David C Hall. With jinjar and the tidyRSS package by Robert Myles it is possible to make an email template that can provide short and informative updates. In his blog, I’m going to share how the jinjar and tidyRSS packages work and show how to combine them to make a simple daily email newsletter.

How jinjar Works

jinjar allows for users to create templates with regular text (or HTML or Markdown) and Jinja code. While the jinjar package has some limitations (as mentioned by the author), it is still very powerful.As an example, I’ll use the bee colonies data made available by Thomas Mock’s TidyTuesday repository to make a template that returns the average annual bee colony loss and total number of bees lost.

First, lets transform the data appropriately:

library(tidyverse)

# Load the data
bee_colonies <-
  readr::read_csv(
    'https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2022/2022-01-11/colony.csv',
    show_col_types = FALSE
  )

# Some aggregation
annual_bee_loss <- bee_colonies %>%
  group_by(year) %>%
  summarize(
    average_colony_loss_pct = round(mean(colony_lost_pct, na.rm = T), 2),
    total_colony_loss = sum(colony_lost, na.rm =
                              T) %>% scales::comma()
  )

annual_bee_loss


## # A tibble: 7 × 3
##    year average_colony_loss_pct total_colony_loss
##   <dbl>                   <dbl> <chr>            
## 1  2015                   12.2  3,444,720        
## 2  2016                   11.4  3,316,520        
## 3  2017                   11.5  2,814,400        
## 4  2018                   12.1  3,034,140        
## 5  2019                   11.9  2,483,820        
## 6  2020                    9.96 3,097,220        
## 7  2021                   10.4  1,256,980

Once the data is appropriately formatted, we can use jinjar to put the relevant data in a Markdown template:

library(jinjar)

# Jinja template
template<- '
## Annual Bee Colony Loss In The United States

{% for loss in losses -%}
* {{loss.year}}: {{loss.average_colony_loss_pct}}% ({{loss.total_colony_loss}} bees)

{% endfor -%}
'
# Render the template with the annual bee loss data
template %>%
  jinjar::render(losses = annual_bee_loss) %>%
  writeLines()


## 
## ## Annual Bee Colony Loss In The United States
## 
## * 2015: 12.15% (3,444,720 bees)
## 
## * 2016: 11.36% (3,316,520 bees)
## 
## * 2017: 11.47% (2,814,400 bees)
## 
## * 2018: 12.1% (3,034,140 bees)
## 
## * 2019: 11.86% (2,483,820 bees)
## 
## * 2020: 9.96% (3,097,220 bees)
## 
## * 2021: 10.35% (1,256,980 bees)

We can even convert the Markdown text to a html file by rendering the text:

library(htmltools)
library(markdown)
template %>%
  jinjar::render(losses = annual_bee_loss) %>%
  renderMarkdown(text = .) %>%
  markdownToHTML(text = .) %>%
  htmlTemplate(text_ = .) %>%
  html_print()

This gives the following output:

How tidyRSS Works

The tidyRSS package enables users to convert an RSS feed to a data frame with one function.

Suppose I’m interested in the latest R-Bloggers posts from today and yesterday. All that needs to be done is to supply the feed link to the tidyfeed() function, filter the publication date with dplyr‘s filter() function and use lubridate to parse dates accordingly.

(using glimpse() to show all the columns of data)

library(tidyRSS)
library(lubridate)

tidyfeed("R-bloggers.com/feed") %>%
  filter(as.Date(item_pub_date) == today() |
           as.Date(item_pub_date) == today() - 1) %>%
  glimpse()


## Rows: 13
## Columns: 14
## $ feed_title           <chr> "R-bloggers", "R-bloggers", "R-bloggers", "R-bloggers", "R-bloggers", "R-bloggers", "R-bloggers"…
## $ feed_link            <chr> "https://www.r-bloggers.com", "https://www.r-bloggers.com", "https://www.r-bloggers.com", "https…
## $ feed_description     <chr> "R news and tutorials contributed by hundreds of R bloggers", "R news and tutorials contributed …
## $ feed_language        <chr> "en-US", "en-US", "en-US", "en-US", "en-US", "en-US", "en-US", "en-US", "en-US", "en-US", "en-US…
## $ feed_pub_date        <dttm> 2022-11-20 13:32:06, 2022-11-20 13:32:06, 2022-11-20 13:32:06, 2022-11-20 13:32:06, 2022-11-20 …
## $ feed_last_build_date <dttm> 2022-11-20 13:32:06, 2022-11-20 13:32:06, 2022-11-20 13:32:06, 2022-11-20 13:32:06, 2022-11-20 …
## $ feed_category        <chr> "R bloggers", "R bloggers", "R bloggers", "R bloggers", "R bloggers", "R bloggers", "R bloggers"…
## $ feed_generator       <chr> "https://wordpress.org/?v=5.5.11", "https://wordpress.org/?v=5.5.11", "https://wordpress.org/?v=…
## $ item_title           <chr> "PCA for Categorical Variables in R", "Whisperings in the Academy", "Some problems related to Di…
## $ item_link            <chr> "https://www.r-bloggers.com/2022/11/pca-for-categorical-variables-in-r/", "https://www.r-blogger…
## $ item_description     <chr> "The post PCA for Categorical Variables in R appeared first on finnstats.If you are interested t…
## $ item_pub_date        <dttm> 2022-11-20 13:32:06, 2022-11-20 13:12:43, 2022-11-19 15:08:18, 2022-11-19 15:07:53, 2022-11-19 …
## $ item_guid            <chr> "https://finnstats.com/?p=16971", "https://www.weirddatascience.net/?p=4385", "https://r-posts.c…
## $ item_category        <chr> "R bloggers", "R bloggers", "R bloggers", "R bloggers", "R bloggers", "R bloggers", "R bloggers"…

Now that we know how to use the jinjar and tidyRSS packages, lets put them together to make a automated newsletter called “Ben’s R Update”!

Using jinjar and tidyRSS to make an R related newsletter

In my hypothetical newsletter “Ben’s R Update”, I share recent R Blogs, r/Rlanguage posts and some available R job postings that are available. This can all be gathered from the R-Bloggers, r/RLanguage and Indeed RSS feeds with tidyRSS and templated with jinjar.

The code to do this is:

library(tidyRSS)
library(dplyr)
library(lubridate)
library(jinjar)
library(htmltools)
library(markdown)

template<- '# Ben\'s R Update {{date}}

## Some R Blogs you might have missed

{% for blog in blogs -%}
* {{blog.item_title}} : {{blog.item_link}} ({{blog.feed_pub_date}})

{% endfor -%}

## New Reddit posts on r/RProgramming

{% for posts in redditPosts -%}

* {{posts.entry_title}} : {{posts.entry_link}} ({{posts.entry_published}})

{% endfor -%}

## New Job Postings For R Programmers 

{% for job in jobPostings -%}

* {{job.item_title}} : {{job.item_link}} ({{job.item_pub_date}})

{% endfor -%}
'

# Make Email Template and Write to Markdown File
template %>%
  jinjar::render(
    blogs =
      tidyRSS::tidyfeed("R-bloggers.com/feed") %>%
      filter(
        as.Date(item_pub_date) == today() |
          as.Date(item_pub_date) == today() - 1
      ),
    redditPosts = tidyRSS::tidyfeed("https://www.reddit.com/r/Rlanguage.rss") %>%
      filter(
        as.Date(entry_published) == today() |
          as.Date(entry_published) == today() - 1
      ),
    jobPostings = tidyRSS::tidyfeed("https://rss.indeed.com/rss?q=R+Programming") %>%
      filter(
        as.Date(item_pub_date) >= today() |
          as.Date(item_pub_date) <= today() - 1
      ),
    date = today()
  ) %>%
  renderMarkdown(text = .) %>%
  markdownToHTML(text = .) %>%
  htmlTemplate(text_ = .) %>%
  html_print()

The output is:

And there you have it! A simple automated newsletter ready to send out!

Conclusion

The jinjar package is a powerful library for dynamic rendering and the example that I provided is really basic. Some more sophisticated examples of using jinjar would be rendering HTML in Shiny Apps and Blogdown sites. I haven’t tried these out yet but I’m sure the use cases would be extensive!

This blog also only focused on making the email template. For sending out the newsletter to a list of contacts, check out the emayili package and set up a cron job to automate it. Let me know if you try it!

Thank you for reading!

Want to see more of my content?

Be sure to subscribe and never miss an update!

To leave a comment for the author, please follow the link and comment on their blog: r – bensstats.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)