Using Quarto Blogs for Teaching

Author

Josef Fruehwald

Published

May 3, 2023

This semester I was teaching two R intensive courses: Quantitative Investigations in the Social Sciences and Quantitative Methods in Linguistics. For both courses, I had students maintain Quarto blogs that they pushed to Github Classroom and I thought I’d write up my thoughts on what worked, what didn’t work, and what I wish I’d planned out in advance.

Github Classroom basics

Firstly, I spent relatively little time on the actual Github Classroom site. There may be more functionality to it that’s useful, but largely I didn’t need it. Each “Classroom” creates a Github Organization from which you can access every student’s assignment repository.

Creating assignments

To create an assignment, you first have to set up a template repository on Github (could be under your own account or under the classroom organization) that gets associated with the assignment. Github Classroom generates an invite link that you can post to Canvas/Blackboard/whatever that will auto-fork the template for the student in the organization, and name it {name-of-assignment}-{gh-username}.

Repository Visibility

These repositories are, by default, private! In the example repo I show here, I went in and manually changed it to be public

For example, here’s the repository it created when I clicked the invite link to the mapping project:

https://github.com/A-S500/maps-final-JoFrhwld

The repository isn’t under my personal account, it’s under the A-S500 organization.

Tip 1: Take your time on the templates

For a blog-type assignment that students will be updating across the entire semester, take your time on the template. Get your template blog to be exactly like you want it. Obviously, students can make changes to how the blog will render, but your initial settings will have a major inertia effect.

Here’s one thing I spent time on in set up that I’ll do differently in the future: I created blank template posts for every post students were going to do that year. For one class, I was having them write weekly reflections, so I created a directory and index.qmd for every week. e.g.

posts/01_week/index.qmd
posts/02_week/index.qmd
...
posts/15_week/index.qmd

For the the other course, I had them write a post for each chapter of the textbook, and the setup was similar.

I’d do that differently now for a few reasons. First, when looking at the source code and the rendered blog, it makes it harder to eyeball where the students have created new content. It might not seem like a lot, but it’s just a little extra bit of friction to click through to an index.qmd post to find that it’s still just the original template.

Second, it facilitated some poor metadata practices for the students. I really couldn’t get everyone to touch the yaml header to update the date of the post if there was already a date: there, so for some people all of their posts were dated January, when I created the template.

Thoughts: The feedback pull request isn’t worth it.

Github Classroom will give you the option of automatically creating a feedback branch and open a pull request to leave comments on the code. While this makes sense for some assignments, these quarto blogs with their rendered html are too unwieldy to bother.

I just opened feedback issues on the blogs referencing the specific lines I was commenting on.

Quarto Things

Some quarto things that I’d recommend:

Tip 2: Set up freeze: auto

To save yourself and your students’ time be sure to configure freezing in the _quarto.yml file.

execute: 
  freeze: auto

This means quarto will save the results of any executed R code, and won’t rerun the code when rendering the project unless the content of the file changes. This will save you and your students a lot of time when re-rendering blogs, especially later in the semester.

commit `_freeze/`

Be sure to add and commit the _freeze/ directory though!

Tip 3: Encourage (enforce!) actual rendering of the blog.

One of the positives of any code notebook system in general is that they look nice while you’re writing, and interleave prose, code, & results. A downside for a Quarto blog, though, is that students may not realize that the code results they see in the notebook don’t get saved and committed. You (the reader/grader) will have to re-run all of the code chunks, or re-render the html blog.

But, as long as students click the “Render Project” button, the generated html pages will be viewable in _site, with all of the prose, code and code results… if they click “Render Project”.

I didn’t pick up on the fact many students were just running the code in the notebook and never clicking “Render” until too late in the semester, and by that point we were very busy trying to get through the course content for me to turn that ship. That meant I had to re-render their blogs (takes time) and I had to deal with/fix any inconsistencies between our R environments (more time!)

Tip 4: Set error: true in the quarto project

I think you should set error: true in _quarto.yml. Usually, if there’s an error in your R code, the project will fail to render. With error: true, the project will render, with the R errors included in the output.

Maybe you’re thinking “But don’t you want to make sure that students fix the errors?” Well, yes I do, but if there’s errors in their code and they push it anyway, when you try to render the project, you’ll have to hunt down and fix the R errors before you can look at the rendered project!

R/RStudio Things

Tip 5: Teach them about {here} early

So, no matter how many times I left comments about “please use relative paths”, I would still get posts with code that looked like

data <- read_csv("~/usernamene/Documents/Courses/blog/data/data.csv")

When combined with the fact that many people weren’t clicking “Render” on their projects, this meant I had to go in and fix these global paths in order to read their posts.

The here package works within RStudio projects to help construct reproducible paths. here::here() returns the path to the main project directory, and will concatenate any further arguments to that path. So rewriting the example above would look like:

library(here)
data <- read_csv(here("data", "data.csv"))

On the one hand, using here in this way does bypass needing to come to grips with paths, which is a crucial component of scientific computing. But on the other, you need to make a decision about where your class time is spent.

If you go all in on *nix-style paths and their navigation, you will burn a lot of class time and your own creative energy on a topic that is increasingly conceptually difficult for students before you even get to course content. Moreover, students won’t neatly delimit course content like “paths are utility background information, stats are a collection of theories and methods, R code is an implementation of those theories and methods.” Rather, it’ll all get dumped into one big bucket of “stats is hard.”

Or, you could teach them to use here.

Tip 6: Figure out {renv}.

This is more of a “to-do”. I’m relatively new to using renv and am still trying to work out the kinks of making it work in distributed assignments like this.

I think step one would be to make sure they’ve installed renv globally, before opening any given project. Then, in your template, commit your renv.lock file, but not the .Rprofile. Then, once they’ve created the project in RStudio, run renv::init() once, restore from the lock file.

I think

Tip 7: Remind them to save!

Remind them that this is not like Google Docs or Word! The document is not auto-saving as you go along! Save save save!

Git/Grading Things

On the reading/grading side of things, I worked out a git workflow that worked pretty well.

Tip 8: Add the student blogs as git submodules

I originally had a grand idea of adding every student’s blog to one larger quarto project I would render, and look at all of their posts in one place, but that didn’t work out great. Instead, I created a bare bones RStudio project, and added each student’s blog repository as a submodule in a `blogs/` directory:

git submodule add git@github.com:...

After initial setup, this meant I could pull all student’s new posts with

git submodule update --remote

Tip 9: Make use of RStudio’s project navigation.

The way I’d read and grade the blog posts was by navigating to a student’s blog repository in RStudio’s file browser, then clicking on the blog.Rproj file. This will auto open the student’s blog as an RStudio project which you can render and browse in isolation from all other students’ projects (especially if you’ve initialized renv inside).

Tip 10: Always commit all changes, but don’t push, after grading

Commit Changes!

I’m saying the same thing twice because it’s important.

After re-rendering and reading the student’s blog, be sure to commit all changes, but don’t push them. This is because of a detail of how both quarto and git submodules work.

Every time you re-render a project, the “last modified” metadata in the rendered html files gets updated. Meaning even if you just changed one page, all of the html pages get modified.

Additionally, if there are uncommitted changes within the git submodule, when you run git submodule update --remote, git won’t pull down the new commits until you’ve committed those changes within then submodule.

Final Thoughts

Overall, I was pretty happy with the outcomes! The blog format worked well for incremental logging of course progress, and it started socializing students into the practices of collaborative coding projects.

I should note that both classes were relatively small, roughly seminar size, so I’m not sure how this would scale up to 25+ students.

Reuse

CC-BY-SA 4.0

Citation

BibTeX citation:
@online{fruehwald2023,
  author = {Fruehwald, Josef},
  title = {Using {Quarto} {Blogs} for {Teaching}},
  series = {Væl Space},
  date = {2023-05-03},
  url = {https://jofrhwld.github.io/blog/posts/2023/05/2023-05-03_teaching-quarto-blogs},
  langid = {en}
}
For attribution, please cite this work as:
Fruehwald, Josef. 2023. “Using Quarto Blogs for Teaching.” Væl Space. May 3, 2023. https://jofrhwld.github.io/blog/posts/2023/05/2023-05-03_teaching-quarto-blogs.