Untangling templates, formats and extensions in Quarto

An attempt to clarify the different ways to reuse templates and extend the features of Quarto, along with a cheatsheet of Quarto CLI commands to add, update and remove extensions, use starter templates, and create projects.

quarto
explainer
how-to
Author

Cynthia Huang

Published

March 11, 2024

Modified

November 9, 2024

Power and Confusion in Quarto

The powerful flexibility and extensibility of Quarto is one of the main reasons I love using it. There’s always something new to experiment with from different templates for blogs, websites and books to alternative formats, themes and, styling and, even custom rendering or document features.

However, there are often multiple ways to achieve the same outcome and even more ways to reuse modifications or customisation in a single document or multi-document projects. Unfortunately, this can lead to some confusion about things like the difference between document/project templates, custom formats, and extension features; or how to use the various quarto create/use/add commands.

This post attempts to untangle these differences, understand the different types of Quarto extensions and, provides some notes on using the associated quarto-cli commands and .qmd YAML options.

DISCLAIMER: Much of what follows comes from snooping around existing Quarto extensions, reading the official Quarto Creating Extensions documentation, and attempting to author my own templates and extensions. Please excuse any inaccuracies. Corrections are welcome.

TL;DR Cheatsheet for Using Extensions

NOTE: unless otherwise indicated, all code chunks in this post are Quarto CLI commands.

Tip

For a simple overview of the different types of Quarto extensions: https://quarto.org/docs/extensions/creating.html#overview

To add a format or feature extension to an existing directory:

quarto add <gh-org>/<gh-repo>

To list extension with details:

quarto list extensions

To update or remove an extension:

quarto update <gh-org>/<gh-repo>
quarto remove <gh-org>/<gh-repo>

To get starter template files from GitHub repo:

quarto use template <gh-org>/<gh-repo>

To use an existing GitHub repo as a starter template and create your own GitHub repo at the same time via GitHub CLI:

gh repo create <new-repo-name> --template <gh-org>/<gh-repo> --private --clone

To set up a new project using built-in project templates and types:

quarto create-project --help

To interactively set-up a new project or extension directory:

quarto create

If the installation or usage details are unclear in the extension repo, try referring to the official quarto docs for creating that type of extension (e.g. for Filters see this page)

Custom Formats and Template Documents

As with any other document creation software or system, templates in Quarto allow you to create documents that are “just like” another document. What exactly “just like” means can include aspects of structure, styling, and formatting, but generally does not include the “contents” of the document.

The most straightforward and transparent way of reusing .qmd documents as templates is probably to just copy and paste the YAML header from one file to another. This can of course get tedious, so Quarto offers a number of ways to reuse YAML options between files within the same folder or project, usually via “Includes”, which I discussed in a previous blog post on reusing and remixing content across revealjs slides.

However, you might want to use the same document template across multiple projects. This is where Custom Format extensions come in. A Custom Format extension is bundle of document configuration options and assets (e.g. custom css, logo images etc.)1. Instead of copy-pasting these elements, we store them together in a folder, and then direct Quarto to use the custom format when rendering. The contents of the custom format folder will vary depending on what “base format” it is extending or customising.

You can make a custom format available in existing .qmd documents using quarto add <gh-org>/<gh-repo>, which adds the custom format folder to your project like so:

quarto add schochastics/quarto-sketchy-html
├── _extensions
│   └── schochastics
│       └── quarto-sketchy-html
├── existing.qmd
...

You can then add all the bundled-up YAML options, features, and assets to your existing.qmd with the format: option in the YAML header:

existing.qmd
---
title: "My new file using the `sketchy-html` format"
format: sketchy-html
---

This tells Quarto to use all the options and assets in the custom format when rendering to existing.qmd. It’s as if you had copy-pasted everything from the bundle into the right places to make a document “just like” the custom format.

You can usually find the name of the custom format in the README of the GitHub repository. However, if it’s not there, it will be in Template Document that is usually available alongside the extension folder (e.g. schochastics/quarto-sketchy-html/template.qmd). Now, notice that this template document is different from the document that the custom format was based on, and instead uses the custom format (via the format: option).

If you want to get both the custom format and the template document, you can use:

quarto use template <gh-org>/<gh-repo>

This will download just the _extensions folder and the template document into a directory of your choice. You can then edit and render the template using the custom format.

Project Types and Starter Templates

In additional to authoring single documents, Quarto supports multi-document projects, which gives rise to project templates. A project template is a collection of template components such as template .qmd documents, directory structures, and default YAML options. Quarto also has “project types”, which also seem to be templates by another name. The available project types in Quarto v1.4 are book, default, website, and manuscript. If you use the quarto create-project command, you’ll notice that it allows you to select a project type (e.g --type website), with some default “sub-types” available via the template argument (e.g --template blog). However, regardless of whether you use the --template argument, the quarto create-project command sets up a new project for you (based on a template project type). Other project options can also be configured via additional arguments:


  Usage:   quarto create-project [dir]
  Version: 1.4.549                    

  Description:

    Create a project for rendering multiple documents

  Options:

    -h, --help                   - Show this help.                                    
    --title          <title>     - Project title                                      
    --type           <type>      - Project type (book, default, website, manuscript)  
    --template       <type>      - Use a specific project template                    
    --engine         <engine>    - Use execution engine (markdown, jupyter, knitr)    
    --editor         <editor>    - Default editor for project ('source' or 'visual')  
    --with-venv      [packages]  - Create a virtualenv for this project               
    --with-condaenv  [packages]  - Create a condaenv for this project                 
    --no-scaffold                - Don't create initial project file(s)               
    --log            <file>      - Path to log file                                   
    --log-level      <level>     - Log level (info, warning, error, critical)         
    --log-format     <format>    - Log format (plain, json-stream)                    
    --quiet                      - Suppress console output.                           
    --profile                    - Active project profile(s)                          

  Commands:

    help  [command]  - Show this help or the help of a sub-command.

  Examples:

    Create a project in the current directory:         quarto create-project                                                             
    Create a project in the 'myproject' directory:     quarto create-project myproject                                                   
    Create a website project:                          quarto create-project mysite --type website                                       
    Create a blog project:                             quarto create-project mysite --type website --template blog                       
    Create a book project:                             quarto create-project mybook --type book                                          
    Create a website project with jupyter:             quarto create-project mysite --type website --engine jupyter                      
    Create a website project with jupyter + kernel:    quarto create-project mysite --type website --engine jupyter:python3              
    Create a book project with knitr:                  quarto create-project mybook --type book --engine knitr                           
    Create jupyter project with virtualenv:            quarto create-project myproject --engine jupyter --with-venv                      
    Create jupyter project with virtualenv + packages: quarto create-project myproject --engine jupyter --with-venv pandas,matplotlib    
    Create jupyter project with condaenv :             quarto create-project myproject --engine jupyter --with-condaenv                  
    Create jupyter project with condaenv + packages:   quarto create-project myproject --engine jupyter --with-condaenv pandas,matplotlib

You can also interactively set-up a new project based on the included templates using quarto create. However, we might want to use an “external” set of files as the template for a new Quarto project. These are generally called Starter Templates. As with template documents for custom formats, you can use quarto use template <gh-org>/<gh-repo> to set up your new project using the specified repo as a starter template.

For example, I use a Quarto website as a personal wiki system for tracking my PhD progress. It contains all my meeting notes, research ideas, a brag/happy file2. I created a template wiki with some of the features I use and put it on GitHub so other PhD students could set-up a similar project in seconds using :

quarto use template cynthiahqy/quarto-wiki-template
Tip

For those of you familiar with the GitHub CLI, you can create a new GitHub repo at the same time as grabbing a starter template using:

gh repo create <new-repo-name> --template <gh-org>/<gh-repo> --clone

Note that this grabs everything in the template repo. This is different to quarto use template for custom formats, which just grabs the template document and extensions folder (leaving behind other files like the README).

Feature Extensions

Now that we’ve covered Custom Formats and Starter Templates, I’ll briefly touch on the remaining types of Quarto extensions, which I lump together in a catch-all category I call “Feature Extensions”. This includes Shortcodes, Filters and revealjs Plugins.

If custom formats allow me to render documents or projects that look or behave “just like” some base template, then feature extensions allow me to modify the rendering process and/or embed additional features into my .qmd files. They usually involve parts of the Quarto “machine” that I have little to no familiarity such as Pandoc filters or revealjs plugins.

Similar to custom formats, feature extensions are distributed as bundles of files in an _extension folder. However, the way you use the extension differs depending on the type of feature. Instead of adding the extension to the format: option, filters and revealjs plugins are added via the filters: and revealjs-plugin: YAML keys, while shortcodes go directly in the body of your document.

Managing Extensions

Depending on what mixture of formats and features you need in a project, you might add multiple extensions. To list all the extensions in a given project, run quarto list extensions from inside the main project directory. This will return something like:

Id                               Version    Contributes
quarto-ext/include-code-files    1.0.0      filters
quarto-ext/fontawesome           1.1.0      shortcodes
EmilHvitfeldt/letterbox          2.0.0      formats
numbats/monash                   0.0.1      formats

You can use this list to update or remove extensions as well, using:

quarto update <extension-id>
quarto remove <extension-id>

Find out more

Please add any other useful resources in the comments below!

Footnotes

  1. Journal Articles are slightly more complicated formats, but work just the same as “normal” custom formats.↩︎

  2. See this blog post by Julia Evans for why you should make yourself a brag file!↩︎

  3. Reminder: Only install extensions you trust. If in doubt, stick with the officially maintained extensions at (github.com/quarto-ext)↩︎

Citation

BibTeX citation:
@online{huang2024,
  author = {Huang, Cynthia},
  title = {Untangling Templates, Formats and Extensions in {Quarto}},
  date = {2024-03-11},
  url = {https://www.cynthiahqy.com/posts/quarto-extensions-explainer/},
  langid = {en}
}
For attribution, please cite this work as:
Huang, Cynthia. 2024. “Untangling Templates, Formats and Extensions in Quarto.” March 11, 2024. https://www.cynthiahqy.com/posts/quarto-extensions-explainer/.