Site icon R-bloggers

Moving from Blogdown to Quarto

[This article was first published on pacha.dev/blog, 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.

R and Shiny Training: If you find this blog to be interesting, please note that I offer personalized and group-based training sessions that may be reserved through Buy me a Coffee. Additionally, I provide training services in the Spanish language and am available to discuss means by which I may contribute to your Shiny project.

< section id="motivation" class="level1">

Motivation

Recently, I have to run blogdown::serve_site() and blogdown::build_site several times to get my new posts rendered. I don’t know why, but it was a bit annoying.

I already have a one liner to install Quarto, so I decided to give it a try.

Note: I started using computers in the old DOS days, so I use the terminal more than the average user.

< section id="install-quarto" class="level1">

Install Quarto

I installed Quarto with sudo apt install quarto (I use Linux Mint). To do this, you can visit my repository containing binaries for RStudio Desktop and Quarto.

< section id="create-a-new-project" class="level1">

Create a new project

From RStudio I created a new “Quarto Blog” project, there I copied the complete contents folder from my Blogdown project.

< section id="preserving-links" class="level1">

Preserving links

< section id="renaming-files" class="level2">

Renaming files

My posts were files of the form YYYY-MM-DD-post-title.Rmd, so I had to rename them to make them work with Quarto and preseve the links structure.

Inside contents I created a bash script titled contents/00-reorganize-posts.sh to move each file of the form YYYY-MM-DD-post-title.Rmd to YYYY/MM/DD/index.qmd

This is the bash script.

#!/bin/bash

# move all files of the form YYYY-MM-DD-*.Rmd to YYYY/MM/DD/*/index.qmd
for f in *.Rmd; do
  if [[ $f =~ ^([0-9]{4})-([0-9]{2})-([0-9]{2})-.*\.Rmd$ ]]; then
    mkdir -p ${BASH_REMATCH[1]}/${BASH_REMATCH[2]}/${BASH_REMATCH[3]}
    mv $f ${BASH_REMATCH[1]}/${BASH_REMATCH[2]}/${BASH_REMATCH[3]}/index.qmd
  fi
done

From the terminal I run this.

cd contents
bash 00-reorganize-posts.sh

To rename each file of the form YYYY/MM/DD/*/index.qmd to YYYY/MM/DD/*/post-title/index.qmd I used R, and I created an R script titled contents/01-rename-posts.R with this content.

# list all the files of the form YYYY/MM/DD/index.qmd
finp <- list.files(path = ".", pattern = "index.qmd", recursive = TRUE, full.names = TRUE)
finp <- finp[nchar(finp) == 22L]

# for each file, read the second line, which contains the title
titles <- sapply(finp, function(x) {
  readLines(x, n = 2L)[2L]
})

# remove the "title: "
titles <- gsub("^title: ", "", titles)

clean_titles <- gsub("_", "-", janitor::make_clean_names(titles))

# for each element in finp replace "index.qmd" with title/index.qmd
fout <- finp
for (i in seq_along(finp)) {
  fout[i] <- gsub("index.qmd", paste0(clean_titles[i], "/index.qmd"), fout[i])
}

# extract the folder for each element in finp
folders <- dirname(fout)

# create the folders
for (i in seq_along(folders)) {
  try(dir.create(folders[i], recursive = TRUE))
}

# mov each finp to fout
for (i in seq_along(finp)) {
  file.rename(finp[i], fout[i])
}

res <- list.files(path = ".", pattern = "index.qmd", recursive = TRUE, full.names = TRUE)

res[nchar(res) > 50L]

From R I run this.

source("contents/01-rename-posts.R")

The last step was to rename some very long file names, and I did this manually.

Then I moved all the files inside contents to the root of the project.

< section id="modifying-quarto-yml-headers" class="level2">

Modifying Quarto YML headers

I had to modify Quarto YML headers in my project to be able to render the posts.

In _metadata.yml I changed the freeze parameter.

freeze: auto

In index.qmd I changed the contents parameter.

contents: "."
< section id="moving-images-and-other-files" class="level1">

Moving images and other files

With Blogdown I had folders of the form static/YYYY-MM-DD/post-title with all the images and other files for each post, and I had to move them to each post’s folder and inside img/, pdf/, etc.

Without this change, the images were not rendered and links were incorrect.

For each post that required it I had to change the links of the form

<img src="/blog/images/2017-10-13-rick-and-morty-tidy-data/rick-and-morty.jpg"></img>

to

<img src="img/rick-and-morty.jpg"></img>

I did this manually.

< section id="updating-posts-headers" class="level1">

Updating posts headers

Quarto uses description instead of summary in the YML headers, so I had to change this in each post.

My last C++ post’s header was

---
title: Cpp11 (R package) vendoring
authors: Mauricio "Pachá" Vargas S.
date: 2023-05-23
tags: ["R", "VSCode", "Linear models", "C++", "Linux"]
summary: Copying the code for the dependencies into my project’s source tree.
---

I changed it to

---
title: Cpp11 (R package) vendoring
authors: Mauricio "Pachá" Vargas S.
date: 2023-05-23
categories: ["R", "VSCode", "Linear models", "C++", "Linux"]
description: Copying the code for the dependencies into my project’s source tree.
---

To do this for each post I created a bash script titled contents/02-update-posts-headers.sh with this content.

#!/bin/bash

# for each qmd file, replace the first occurence of "summary: " with "description: "
for file in $(find . -name "*.qmd"); do
    sed -i '0,/summary: /s//description: /' $file
done

# for each qmd file, delete the first line starting with "categories: "
for file in $(find . -name "*.qmd"); do
    sed -i '/categories: /d' $file
done

# for each qmd file, replace the 1st occurrence of "tags: " with "categories: "
for file in $(find . -name "*.qmd"); do
    sed -i '0,/tags: /s//categories: /' $file
done

From the terminal I run this.

bash 02-update-posts-headers.sh
< section id="generating-an-xml-feed-optional" class="level1">

Generating an XML feed (optional)

Because the blog is listed in R-Bloggers, I had to generate a new XML feed, something that blogdown did automatically.

I edited index.qmd in the root of the project and modified the listing part YML header by adding feed: true.

listing:
  contents: "."
  sort: "date desc"
  type: default
  categories: true
  sort-ui: false
  filter-ui: false
  feed: true
< section id="final-comment" class="level1">

Final comment

I am surprised that, besides images and links, everything else worked out of the box. My blog goes back to 2015, when I was starting with R, and I have a lot of posts with a lot of code.

With the exception of two posts that I did not keep copies of the data and that I had to exclude, everything else worked after installing missing R packages. Probably it would have been better to include codes and results as markdown chunks, but I did not know about this when I started blogging.

Also, this blog is not very popular, so I don’t have to worry about breaking links, but I kept most of them. When I started blogging in 2015 I was using Pelican, and I exported the R Markdown outputs as Markdown files to then render the blog with Python. In 2017 I switched to Blogdown, and now I am using Quarto. It has been a long journey!

< section id="references" class="level1">

References

To leave a comment for the author, please follow the link and comment on their blog: pacha.dev/blog.

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.
Exit mobile version