Using the FGCZ Quarto report templates

What this package provides

fgczQuartoTemplate ships one shared set of Quarto report assets so that FGCZ analysis packages (ezRun, prolfqua, …) all produce reports with the same look and feel. A theme change becomes a single package bump instead of an edit in every downstream package.

See the layout live: https://fgcz.github.io/fgczQuartoTemplate/vignettes/example-report.html — a full report rendered with the extension (tabsets, figure + callout rows, nesting, lightbox). The documentation site is built with altdoc, which renders that report through Quarto, so the FGCZ layout and its panel-tabsets appear exactly as they do locally (pkgdown, by contrast, mangles Quarto tabsets). This article explains how to use the templates.

Author reports consistently: read the FGCZ Quarto reports authoring guide, which altdoc publishes directly from the skill source file. It defines the required Overview and Session Info structure, tab-depth rules, figure layout, caption guidance, and provenance conventions.

Two ways to use it

Way 1 — Quarto extension (plain quarto render, no R). Once per project:

quarto add fgcz/fgczQuartoTemplate

then in the report header:

---
title: "My report"
format: fgczQuartoTemplate-html
---

Way 2 — R helper (stage the files from R, no format: line needed) — the subject of the rest of this article. Both routes produce the same report and can coexist in one repo.

The assets live under inst/quarto/:

list.files(fgcz_quarto_dir())
#> [1] "_metadata.yml"            "fgcz_header_quarto.html" 
#> [3] "fgcz-buttons.lua"         "fgcz-plot-finder.html"   
#> [5] "fgcz-report-overview.svg" "fgcz.scss"               
#> [7] "template.qmd"
File Role
_metadata.yml Shared format defaults, applied automatically to every .qmd in the directory.
fgcz.scss Theme overrides — tabset/card styling, figure rows.
fgcz_header_quarto.html FGCZ header, injected via include-in-header.
fgcz-plot-finder.html Opt-in Find and Download toolbar.
fgcz-buttons.lua Validates and applies toolbar selections for the Quarto extension.
fgcz-report-overview.svg Visual abstract copied with the starter report.
template.qmd Generic starter report demonstrating the layout patterns.

Why the assets must sit next to the report

Quarto applies a file named _metadata.yml automatically to every .qmd in its directory (and subdirectories) — that is how the styling attaches without any front-matter reference. The file in turn names fgcz.scss and fgcz_header_quarto.html by bare filename:

writeLines(head(readLines(fgcz_quarto_dir("_metadata.yml")), 30))
#> ## ─────────────────────────────────────────────────────────────
#> ## FGCZ Shared Report Defaults
#> ## Quarto applies this file automatically to every .qmd in this
#> ## directory (and subdirectories) because it is named _metadata.yml.
#> ## Individual reports need NO reference to it in their front matter.
#> ## Keep fgcz.scss and fgcz_header_quarto.html next to it.
#> ## ─────────────────────────────────────────────────────────────
#> 
#> format:
#>   html:
#>     embed-resources: true
#>     self-contained: true
#>     smooth-scroll: true
#>     page-layout: full
#> 
#>     # Code
#>     code-fold: true
#>     code-tools: true
#> 
#>     # Theme — flatly base + FGCZ overrides (tabset card styling for now)
#>     theme: [spacelab, fgcz.scss]
#> 
#>     # Grid sizing
#>     grid:
#>       body-width: 1800px
#>       sidebar-width: 250px
#>       margin-width: 100px
#> 
#>     # FGCZ header
#>     include-in-header: fgcz_header_quarto.html

Quarto resolves those names relative to the directory of the input .qmd, not relative to the YAML that mentions them. So all three files must physically sit next to the report at render time. That is exactly what fgcz_copy_assets() and fgcz_render() take care of.

The portable report header

Because _metadata.yml attaches by directory, a report carries no FGCZ-specific front matter at all — just its own params and title:

---
params:
  reportTitle: "CountQC"
title: "`r params$reportTitle`"
---

Rendered with a bare quarto render CountQC.qmd, it still picks up the full styling — the package need not even be installed, as long as the three assets are in the directory.

Staging the assets

fgcz_copy_assets() copies the three styling files into a directory. Here we stage them into a temporary directory and confirm they landed:

dir <- file.path(tempdir(), "demo-report")
dir.create(dir, showWarnings = FALSE)

staged <- fgcz_copy_assets(dir)
basename(staged)
#> [1] "_metadata.yml"           "fgcz.scss"              
#> [3] "fgcz_header_quarto.html" "fgcz-plot-finder.html"
file.exists(staged)
#> [1] TRUE TRUE TRUE TRUE

Bootstrapping a new report

fgcz_use_template() copies the starter template.qmd into a directory together with the styling assets it needs, so you have a runnable report in one call:

qmd <- fgcz_use_template(file.path(tempdir(), "new-report"),
                         to = "my_report.qmd",
                         overwrite = TRUE)
list.files(dirname(qmd))
#> [1] "_metadata.yml"            "fgcz_header_quarto.html" 
#> [3] "fgcz-plot-finder.html"    "fgcz-report-overview.svg"
#> [5] "fgcz.scss"                "my_report.qmd"

Rendering

fgcz_render() stages the assets and then calls quarto::quarto_render(). It needs the Quarto CLI, so the call below is shown but not run in this vignette:

fgcz_render(qmd, execute_params = list(reportTitle = "My analysis"))
fgcz_render(qmd, buttons = TRUE) # all three toolbar buttons; FALSE remains the default
fgcz_render(qmd, buttons = "search") # Find only; "download"/"source" select the others
fgcz_render(qmd, colour = TRUE, number = TRUE) # per-level tab colours + numbers
fgcz_render(qmd, fig_dpi = 150, fig_retina = 1) # smaller self-contained HTML

That is the single call downstream packages use in place of a bare quarto::quarto_render().

fig_dpi and fig_retina override the shared _metadata.yml figure resolution (format.html.fig-dpi, default 300, and knitr.opts_chunk.fig.retina, default 2) for a single render, without editing the .qmd. Reach for these on figure-heavy reports — many samples, each with a repeated per-sample plot — where the default balloons the self-contained HTML into the hundreds of MB.

With the Quarto extension route, opt into the toolbar with include-after-body and select controls using a top-level fgcz-buttons: key:

format:
  fgczQuartoTemplate-html:
    include-after-body: _extensions/fgczQuartoTemplate/fgcz-plot-finder.html
fgcz-buttons: [search, download, source]

Use a single name for one button, or any subset. Omitting fgcz-buttons shows all three controls; an unknown name stops the render with a validation error.

Independent of the toolbar selection, any figure or table chunk with #| label: fig-xxx / #| label: tbl-xxx and a matching fig-cap:/tbl-cap: gets a small “Show code” </> badge — on the figure/table itself and on its card in the Find panel — that jumps to and highlights that chunk in View Source. It needs only code-tools: true, which is already a _metadata.yml default, so an unlabelled chunk (the default) simply shows nothing extra.

Two further opt-in tab features, both off by default and independent of each other, are set as top-level YAML keys (or via fgcz_render(colour =, number =) from R):

fgcz-colour: true   # per-nesting-level tab palette (deep blue → indigo)
fgcz-number: true   # hierarchical tab numbers: 1, 1.1, 1.1.1 …

fgcz-colour replaces the uniform grey folder tabs with one hue per nesting level, so depth reads as colour; fgcz-number prefixes every tab label with its hierarchical position, counting across sibling tabsets at the same depth.

Using it from a downstream package

  1. Add fgczQuartoTemplate to Imports (and, since it is distributed on GitHub, Remotes: fgcz/fgczQuartoTemplate).
  2. Replace quarto::quarto_render() calls with fgczQuartoTemplate::fgcz_render().
  3. Leave report front matter free of any styling reference — the staged _metadata.yml attaches automatically.
  4. Git-ignore the staged copies (_metadata.yml, fgcz.scss, fgcz_header_quarto.html, and fgcz-plot-finder.html) in the render directory so the packaged assets remain the single source of truth.