I started my blogging journey as a homework assignment in grad school. At the time, Jekyll was new, exciting, and easy to spin up. I found a theme I liked, contributed to it on GitHub to add all the elements I needed, got an internship from the person who ran the theme (Thanks, Barry!), and stuck with it till now.
There’s nothing wrong with my (old?) blog, but I’ve been using Quarto docs at work and wanted to experiment with Quarto powering my blog. I don’t write new posts very often, so I also don’t have that many posts to transition. It seemed like a fun challenge!
Task 1: Get old blog file structure into the new file structure
A Quarto blogs file tree look like:
├── 404.html
├── 404.jpg
├── CNAME
├── _quarto.yml
├── about.qmd
├── index.qmd
├── posts
│ ├── _metadata.yml
│ ├── my_first_post
│ │ └── index.qmd
│ │ ├── stockphoto.png
├── profile.png
└── styles.css
Each post has its own sub-folder under the posts directory. The text of each post is inside an index.qmd file, which contains date and tag metadata in the YAML.
On the other hand, my Jekyll blog posts are markdown files under the *_posts* folder, organized by date in the filename.
├── 404.md
├── CNAME
├── _config.yml
├── _includes
├── _layouts
├── _plugins
├── _posts
│ ├── 2015-02-15-my_first_blog.md
├── _sass
├── about.md
├── archive.html
├── images
│ ├── 404.jpg
│ └── stockphoto.png
├── index.html
├── style.scss
├── tag_index.html
So the first task was to convert all my Markdown blog posts into their own subfolder under the posts directory. I would also like to grab any metadata out of the posts while doing so.
library(tidyverse)
# md posts filenames & location
posts <- list.files("eringrand.github.io.raw/_posts/", full.names = TRUE)
posts_raw <- data.frame(post_loc = posts, # full filepath
post_name = basename(posts) # just the file name
) |>
rowwise() |>
# use list-frame to read in post text
mutate(post = list(data.frame(txt = readLines(post_loc))))
# post meta data
posts_info <- posts_raw |>
mutate(date = str_sub(post_name, 1, 10), # Jekyll post filenames all start with the date
author = "Erin Grand"
) |>
# grab metadata from the text of the post itself
mutate(title = filter(post, str_detect(txt, "title:")) |> pull(txt),
title = str_remove(title, "title:") |>
str_remove_all("[[:punct:]]") |>
str_trim(),
# this may be different depending on how your blog does tags
categories = filter(post, str_detect(txt, "tags:")) |>
pull(txt) |>
str_remove("tags:") |>
str_remove_all("[[:punct:]]") |>
str_trim() |>
str_c(collapse = ", "),
) I then cleaned up a bunch of text in my tags/categories, but I ended up rewriting them manually anyway, so I’m going to ignore that code for now.
With all the post information and most of the metadata, I could now write out the new post structure and files.
fill_between <- function(x) {
x_log = str_detect(x, "---")
# Find the indices of the first and last TRUE
first_true_index <- which(x_log)[1]
last_true_index <- which(x_log)[2]
# Create a range of indices to fill
indices_to_fill <- first_true_index:last_true_index
# Set all values within this range to TRUE
return(x[-indices_to_fill])
}
posts_all <- posts_info |>
mutate(post_txt = list(data.frame(x = fill_between(pull(post, txt)))), # continue to use list-frames
# new yaml headers, with date and tags
yml_txt = (con = glue::glue("---
title: {title}
author: {author}
date: {date}
categories: [{categories}]
image: 'image.jpg'
---")
),
yml_txt = list(data.frame(readLines(textConnection(yml_txt)))),
new_post_txt = list(bind_rows(yml_txt, post_txt) |> pull(x)),
dir_title = janitor::make_clean_names(title)
) |>
select(dir_title, new_post_txt)With the posts written the way I wanted them, I just had to create the new sub-folders and write the posts out into individual index files.qmd files.
walk(pull(posts_all, dir_title), ~dir.create(glue::glue("posts/{.x}")))
walk2(pull(posts_all, dir_title), pull(posts_all, new_post_txt), ~writeLines(.y, glue::glue("posts/{.x}/index.qmd")))Task 2: Render the Blog and Fix all the Errors
A significant number of my posts stopped working because links didn’t go anywhere, and I didn’t grab images from the original posts. (Whoops! Next time, automate image file moving as well.) I didn’t have that many blog posts, so it wasn’t a massive lift for me to manually test each post and edit the text to include correct image links (where possible).
I also went in and changed most of the categories because my old tags didn’t make as much sense to me anymore. (It’s an R blog! Does every post need a #tidyverse tag? Probably not.)
Task 3: Make Blog Pretty!
Erin, this blog isn’t any different from the default theme?! Did you finish the new blog??? Dear reader, no, I have not. I’m trying out some themes and taking a stab at CSS and brand.yml, but none of those things are ready for Prime Time yet.
Wrap Up
This is very much a trial run for me. I like Quarto, but I got used to Jekyll and change is not always my favorite thing. Do you have tips I should use for this new adventure?
What blog engine do you use? Do you like the Quarto style of blog, or still use Rmarkdown blogdown or something else? Let’s talk about it on bluesky (Find me @eringrand, because I have not added comments capabilities to this blog yet!)