Philip
Philip

Reputation: 439

How to specify parameters in a .yml file for Quarto?

I am creating a quarto book project in RStudio to render an html document. I need to specify some parameters in the yml file but the qmd file returns "object 'params' not found". Using knitR.

I use the default yml file where I have added params under the book tag.

project:
  type: book

book:
  title: "Params_TEst"
  author: "Jane Doe"
  date: "15/07/2022"
  params:
    pcn: 0.1
  chapters:
    - index.qmd
    - intro.qmd
    - summary.qmd
    - references.qmd

bibliography: references.bib

format:
  html:
    theme: cosmo
  pdf:
    documentclass: scrreprt

editor: visual

and the .qmd file looks like this

# Preface {.unnumbered}

This is a Quarto book.

To learn more about Quarto books visit <https://quarto.org/docs/books>.

```{r}
1 + 1
params$pcn
```

When I render the book, or preview the book in Rstudio the error I receive is:

Quitting from lines 8-10 (index.qmd) Error in eval(expr, envir, enclos) : object 'params' not found Calls: .main ... withVisible -> eval_with_user_handlers -> eval -> eval

I have experimented placing the params line in the yml in different places but nothing works so far.

Could anybody help?

Upvotes: 10

Views: 6084

Answers (2)

Hirschey
Hirschey

Reputation: 95

For multi-page renders, e.g. quarto books, you need to add the YAML to each page, not in the _quarto.yml file

So in your case, each of the chapters that calls a parameter needs a YAML header, like index.qmd, intro.qmd, and summary.qmd, but perhaps not references.qmd.

The YAML header should look just like it does in a standard Rmd. So for example, your index.qmd would look like this:

---
  params:
    pcn: 0.1
---

# Preface {.unnumbered}

This is a Quarto book.

To learn more about Quarto books visit <https://quarto.org/docs/books>.

```{r}
1 + 1
params$pcn

But, what if you need to change the parameter and re-render? Then simply pass new parameters to the quarto_render function

quarto::quarto_render(input = here::here("quarto"), #expecting a dir to render
                      output_format = "html", #output dir is set in _quarto.yml
                      cache_refresh = TRUE, 
                      execute_params = list(pcn = 0.2))

Upvotes: 2

Lucas A. Meyer
Lucas A. Meyer

Reputation: 478

For now, this only seems to work if you add the parameters to each individual page front-matter YAML.

If you have a large number of pages and need to keep parameters centralized, a workaround is to run a preprocessing script that replaces the parameters in all pages. To add a preprocessing script, add the key pre-render to your _quarto.yml file. The Quarto website has detailed instructions.

For example, if you have N pages named index<N>.qmd, you could have a placeholder in the YML of each page:

---
title: This is chapter N
yourparamplaceholder
---

Your pre-render script could replace yourparamplaceholder with the desired parameters. Here's an example Python script:

for filename in os.listdir(dir):
  if filename.endswith(".qmd"):
    with open(filename, "r") as f:
      txt = f.read()
      f.replace('yourparamplaceholder', 'params:\n\tpcn: 0.1\n\tother:20\n')
    with open(filename, "w") as ff:
      ff.write(txt)

I agree with you that being able to set parameters centrally would be a good idea.

Upvotes: 3

Related Questions