How to create a new post for the site

/ [tutorials]   / #website 

In this article we explain how to contribute new posts and slidedecks for the website.

General workflow for contributing

If you’re new to git and GitHub check out this nifty guide.

The general workflow would include the following steps:

  1. Fork the project from the GitHub RECON learn project:

This will create a copy of the project in your own GitHub account. You will need to clone this archive, and make the modifications there. You git clone would look like:

git clone

If your GitHub user name is johnsnow.

  1. Open the project in Rstudio and run devtools::install()

  2. Add new content, typically in the form of a new .Rmd file and associated media (most often images). See more details in the following section for posts or in the section about slidedecks.

  3. Generate content by knitting your new Rmd via RStudio’s knit button or by running learn::render_new_rmds_to_md() to build the .md files and associated graphics.

  4. git commit and git push all changes; don’t forget to add new images as well (run git status to see which files haven’t been added).

  5. Make a pull request against the main project (master branch), from the GitHub RECON learn project. Make sure you use reconhub/learn, branch master as base fork. Every pull request will trigger a new deploy of the website, so that new versions can be visualised online (see section Visualising the changes below)

Creating posts

Practicals, tutorials, case studies are contributed as R Markdown (.Rmd) documents and generated markdown ready for conversion as .md documents. They are stored in content/post. The best way to create a new document is to use the create_post() function. For instance, this post was created using:

learn::create_post(title = "How to create a new post for the site",
                   slug = "post-creation",
                   category = "tutorials",
                   author = "Locke Data")

See ?create_post() to see further parameters. create_post() creates and opens the Rmd file, creates a default .bib and a blank place-holder image that you can replace with your own header image.


File-naming conventions are as follows:

  • start with practical for practicals, study for case studies (handled by create_post())
  • use an informative slug.
    • use lower case, no special characters
    • be hypen-separated (“-”)

For instance, for a practical using a SEIR model for influenza data:

  • seir-influenza is a good slug
  • SEIR-flu is bad because it has capitalised letters
  • new is bad, as it is non-informative

Editing the YAML header

The YAML header is the beginning of the Rmd document, within the ---. For instance:

title: Phylogenetic tree reconstruction
author: Thibaut Jombart
authors: ["Jombart, Thibaut"]
categories: ["practicals"]
topics: ["genetics"]
date: 2017-11-01
image: img/highres/trees.jpg
showonlyimage: true
bibliography: practical-phylogenetics.bib
licenses: CC-BY
always_allow_html: yes
    variant: markdown_github
    preserve_yaml: true

Fields are mostly self-explanatory, and can be adapted to your needs. The date should respect the format provided. When using create_post as shown earlier, many fields will have been filled for you.

Referencing packages

You can load packages or use functions via the typical methods library("tidyverse"), require("magrittr"), dplyr::mutate() and folks can run learn::get_and_update_dependencies() file to get all packages mentioned in the content/posts directory.

This means you do not need to have mandatory install statements - you can make these eval=FALSE.

Storing and reading data

If you have external example data you want to show users, you should store it in the static/data directory. If it’s more than 5MB, consider storing it on an exeternal service such as

Because the documents are renderd on your machine before they are displayed on the website, there is a bit of unfortunate directory juggling that needs to happen when you attempt to read in your file.

When you read in a file, you need to refer to the path that’s currently on your machine. For example, if you wanted to read in a file that the user would have in data/clean/linelist.rds, you would write it like this:

x <- readRDS(here::here("static/data/clean/linelist.rds"))

Because the readers will not likely have the static/ directory, you should add include = FALSE into the above chunk option and show the next chunk but do not evaluate it:

x <- readRDS(here::here("data/clean/linelist.rds"))

Storing and displaying images

The image will be the image associated with the document on the website. We try using natural, high-resolution, evocative images having a link, if only figurative, with the topic covered. These images are stored in static/img/highres/. Do not forget to add and push this file as well, as it will be required for your post to be successfully integrated. The path to the file provided in the header assumes static/ as root folder (see example above), so that the right path will look like: img/highres/your-image.jpg.

If you need to refer to a static image such as a screenshot, place it in the appropriate img/ subdirectory and be sure to commit the file. When you refer to your image in your document, you should refer to it using a relative path. For example, we would use the following markdown code to refer to the recon logo:

![Logo for the R Epidemics Consortium](../../img/logo/recon.png)

Logo for the R Epidemics Consortium

The reason why you need to refer to images two directories up is because the post will always live in content/post/ relative to the root directory (which is the static/ directory when the site is rendered).

Any images that are rendered as part of the practical will auto-populate.


The bibliography is optional. If provided, it should contain references cited in the document as a bibtex file (.bib). Do not forget to add and push this file as well, as it will be required for your post to be successfully integrated.

create_post create a .bib by default. If you don’t need it, delete it and delete the corresponding YAML field.

HTML widgets (plotly, leaflet…)

If your post features an interactive plot or map, please use the save_and_use_widget function.

map <- leaflet::leaflet() %>%
  addTiles() %>%
  fitBounds(0, 40, 10, 50) %>%
  addPopups(-93.65, 42.0285, "Here is the <b>Department of Statistics</b>, ISU")

learn::save_and_use_widget(map, "map.html")

You will very rarely want to actually show the save_and_use_widget function to the readers of your tutorial or practical. To alleviate this, we suggest to have identical chunks, where the first chunk is not evaluated and the second chunk is not echoed:

<!-- The first part is shown to the reader -->

```{r map_show, eval = FALSE}
map <- leaflet::leaflet() %>%
  addTiles() %>%
  fitBounds(0, 40, 10, 50) %>%
  addPopups(-93.65, 42.0285, "Here is the <b>Department of Statistics</b>, ISU")


<!-- The second part is hidden from the user, but the results are shown -->

```{r map_eval, echo = FALSE}
map <- leaflet::leaflet() %>%
  addTiles() %>%
  fitBounds(0, 40, 10, 50) %>%
  addPopups(-93.65, 42.0285, "Here is the <b>Department of Statistics</b>, ISU")

learn::save_and_use_widget(map, "map.html")


RECONLearn is built via hugo on netlify with support for MathJax, which means that you can include math equations with a small catch. Because the RMarkdown pages are first rendered to plain markdown on your computer via pandoc, you must wrap your math equations in backtics or the equations will not render properly.

Take for example this latex equation: `$$ I_t  ∼  Poisson(\lambda_t)$$`

With Backtics

$$ I_t  ∼  Poisson(\lambda_t)$$

Without Backtics

[ I_t  ∼  Poisson(\lambda_t)]

Be nice

As many files could be generated in one go, please don’t use any rm(list=ls()) types of activities. Make your code play nicely with others – use specific and useful names, don’t mess around with the global environment, and don’t force any package unloads.

Contributing slides

Material for slides is stored in static/slides. Currently, two files are needed for a lecture:

  1. a .Rmd post in content/post (see above) to introduce the lecture and link to the slides; for an example, look at content/post/lecture-reproducibility.Rmd.

  2. the slides themselves, stored in static/slides.

For the slides, we recommended using .Rmd there again, and rendering them before committing them. If your slides use images, store them in static/img/slides. You will be able to refer to them using ../../img/slides/your-image.jpg. For an example of rmarkdown+ioslides slides, look at static/slides/intro_reproducibility_Rmd/intro_reproducibility.Rmd.

Visualising the changes

Once a pull request (PR) has been made against, a new version of the website matching the PR will be deployed online at a new URL with the form where xyz is the number of the pull request. For instance, PR 26 will be deployed at: .

About this document


  • Locke Data: initial version

  • Thibaut Jombart: precisions on cloning and PR deploys

  • Zhian N. Kamvar: Clarificaton of rendering and forking

Contributions are welcome via pull requests.

License: CC-BY Copyright: Locke Data, 2018