Project Types

Overview

Custom project types provide the ability to tailor projects for a particular purpose. This could be used to create a project type that implements an organization-level standard for creating documentation or conducting analyses.

For example, if you created a project type extension called lexdocs, it could be used with:

_quarto.yml
project:
  type: lexdocs

This single line of configuration could provide:

  • Navigational elements
  • Headers and footers
  • Document filters
  • Graphical elements
  • HTML options and styles

If you additionally include some basic scaffolding as a Starter Template for using the project type, and host it within a GitHub repository, then users could get a new project up and running as simply as:

Terminal
quarto use template lexcorp/lexdocs

Note that it is possible to bundle and distribute project type extensions as simple gzip archives (as opposed to using a GitHub repository as described above). See the article on Distributing Extensions for additional details.

Development Tools

If you are using custom project types within VS Code or RStudio, only the very latest versions of these tools handle custom project types correctly:

Please be sure to update your version(s) of these tools before proceeding.

Complete Example

In this section we’ll describe exactly what a project type extension should include by providing a complete example of the lexdocs project type alluded to above. Here are the files contained in our lexdocs project type:

_quarto.yml
index.qmd
team.qmd
_extensions
  lexdocs/
    _extension.yml
    lexcorp.png
    theme.scss
    filter.lua

Note that this repository provides both:

  1. The project type extension (contained in the _extensions directory).

  2. A starter template for using the project type (the _quarto.yml, index.qmd, and team.qmd files in the root of the repository).

Project Type Extension

Let’s explore the code for the extension first. Here is the main _extension.yml file:

_extensions/lexdocs/_extension.yml
title: Lexdocs Project
author: Lexcorp, Inc.
version: 1.0.0
quarto-required: ">=1.2.0"
contributes:
  project:
    project:
      type: website
    website:
      sidebar: 
        contents: auto
        search: true
        style: docked
        background: light
        logo: lexcorp.png
      page-footer: |
        "Copyright 2022, Lexcorp, Inc." 
    format: lexdocs-html
  formats:
    html:
      theme: [default, theme.scss]
      code-overflow: wrap
      code-line-numbers: true
      filters:
        - filter.lua

The contributes key includes a project entry, which in turn defines the default values for the _quarto.yml configuration file when this project type is used.

Note that custom project types always need to inherit from one of the base project types built into Quarto (default, website, or book). Here we specify project: type: website.

You’ll also note that we additionally define a lexdocs-html Custom Format within the extension (and then make that the default format for the project). This enables us to reference that format explicitly within documents (e.g. if you want to include a document that renders both pdf and lexdocs-html variations).

There are three additional files referenced in the custom project definition in _extension.yml. We won’t show their source code, but here’s a rundown on the role they play:

  • lexcorp.png is a logo added to the sidebar.
  • theme.scss provides a custom theme for HTML output.
  • filter.lua provides some additional transformations required by the format.

Starter Template

This repository also provides a starter template by including these files at the root of the repository:

  • _quarto.yml is the project configuration file
  • index.qmd is an empty default home page
  • team.qmd is a page where users of the project type are encouraged to list the team members who contributed.

Here’s what _quarto.yml might look like:

_quarto.yml
project:
  title: "Docs Site"
  type: lexdocs
  
format:
  lexdocs-html:
    toc: true

Users of the template will natually change the default title, and can add whatever other project, website, or format level options they require (these options will be merged with the defaults provided by the extension).

Markdown Publishing

If you are using Quarto to produce markdown for another publishing system, you can use a project type extension to tailor the markdown output created by Quarto, as well as integrate with the native preview capabilities of the other system.

Quarto includes a couple of built-in project-types for integrating with the Hugo and Docusaurus publishing systems. You can see the source code for these project types here:

Hugo Example

Here is the the _extension.yml file for the Hugo project type (this demonstrates a few of the additional options you’d typically specify when creating a project type for markdown publishing, we’ll describe these options below):

_extension.yml
title: Hugo
author: RStudio, PBC
organization: quarto
contributes:
  project:
    project:
      type: default
      detect:
        - ["config.toml", "content"]
        - ["config/_default/config.toml", "content"]
      render:
        - "**/*.qmd"
        - "**/*.ipynb"
      preview:
        serve:
          cmd: "hugo serve --port {port} --bind {host} --navigateToChanged"
          env: 
            HUGO_RELATIVEURLS: "true"
          ready: "Web Server is available at"
    format: hugo-md
  formats:
    md:
      variant: gfm+yaml_metadata_block+definition_lists
      prefer-html: true
      fig-format: retina
      fig-width: 8
      fig-height: 5
      wrap: preserve

Let’s look specifically at some project options provided for Hugo that you may not have seen before:

project:
  type: default
  detect:
    - ["config.toml", "content"]
    - ["config/_default/config.toml", "content"]
  render:
    - "**/*.qmd"
    - "**/*.ipynb"
  preview:
    serve:
      cmd: "hugo serve --port {port} --bind {host} --navigateToChanged"
      env: 
        HUGO_RELATIVEURLS: "true"
      ready: "Web Server is available at"

The detect option enables Quarto to automatically detect when to activate this project type based on the presence of one or more files.

The render option indicates which files Quarto should render (note that by default Quarto will render .md files, but this would interfere with Hugo’s native rendering of .md files so we exclude them here).

The preview option enables quarto preview to launch the native preview server for Hugo. The cmd indicates the shell command to use (with spots to interpolate the {port} and {host}); the env option specifies values for environment variables; and the ready option is a sequence of characters to look for to indicate that the preview server has started and is ready to handle requests.

Markdown Formats

When creating a project type for a markdown publishing system you’ll always need to define a custom format along with it which defines what flavor of markdown to produce. In the case of Hugo we define the markdown flavor using the variant option:

formats:
  md:
    variant: gfm+yaml_metadata_block+definition_lists+smart

This results in GitHub Flavored Markdown w/ YAML metadata blocks (which Hugo requires for tags/categories/etc) in addition to support for definition lists and smart typography.

Note that for some systems you’ll need to do more than just declare a variant. For example, in the case of Docusaurus we declare the variant as well as a Lua filter that deals with Docusaurus-specific constructs like MDX, Callouts, and Tabsets:

formats:
  md:
    variant: +yaml_metadata_block+pipe_tables+tex_math_dollars+header_attributes-all_symbols_escapable
    filters:
      - docusaurus.lua

A project type for any given markdown publishing system will have its own variant, and will often also require a filters to deal with non-standard constructs and other vagaries of the target system.