When can I use a prefix created with `shiny::addResourcePath()` to access shared resources?

Hi everyone

I am currently working on a package that contains multiple learnr tutorials. Here is a simplified version of the package layout (here called {tutorialpackage}):

├── R
│   └── hello.R
├── inst
│   ├── resources
│   │   ├── child_Rmds
│   │   │   └── formatting.Rmd
│   │   ├── css
│   │   │   └── style.css
│   │   ├── images
│   │   │   └── rstudio_logo.png
│   │   └── scripts
│   │       └── example_script.R
│   └── tutorials
│       └── first_tutorial
│           └── first_tutorial.Rmd
├── man
│   └── hello.Rd
└── tutorialpackage.Rproj

I would like to manage all resources used by the tutorials in a central directory inst/resources (corresponding to resources of the installed package), using shiny::addResourcePath(). For example, CSS files whould be in resources/css and accessed with /css.

title: "First tutorial"
    css: /css/style.css # works
runtime: shiny_prerendered

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
# Link to static resources to Shiny's web server
list.dirs(system.file("resources", package = "tutorialpackage"),
          recursive = FALSE) |>
  purrr::walk(\(x) shiny::addResourcePath(basename(x), x))
# Steps above equivalent to
# shiny::addResourcePath("css",
#                        system.file("resources", "css"
#                        package = "tutorialpackage"))
# repeated for all other directories in `resources`

## Topic 1

::: exercise <!-- works -->
Testing `div` definition from `style.css`.

Adding image:
![](/images/rstudio_logo.png){width=5%} <!-- works here -->

knitr::include_graphics("/images/rstudio_logo.png") # Does not work
test <- readr::read_file("/scripts/example_script.R") # Does not work
<!-- Loading child document below does not work -->
```{r child = "/child_Rmds/formatting.Rmd"}

I am unclear in what context the prefix path to a file works. For example, why does /images/rstudio_logo.png work with ![](/images/rstudio_logo.png) but not knitr::include_graphics("/images/rstudio_logo.png")? Why does css: /css/style.css in the YAML header work but not test <- readr::read_file("/scripts/example_script.R")? Is there a way to explicitly tell R that the path provided is a prefix path?



Edit: Added comment to explain purrr:walk(); fixed code example

A learnr tutorial involves two primary contexts:

  1. The pre-render step that generates static content and prepares the tutorial content.
  2. The Shiny app step that runs the tutorial interactively for the user.

Since shiny::addResourcePath() is a function that has an affect on files and folders served by Shiny apps, it only affects the second context. In other words, you can expect


to work because the image is found by the user's browser when they interact with the running tutorial, after you've configured Shiny to make those images available at /images/.

OTOH, the examples in this R chunk do not work

knitr::include_graphics("/images/rstudio_logo.png") # Does not work
test <- readr::read_file("/scripts/example_script.R") # Does not work

because, as standard R chunks, they are evaluated during the pre-render step just as if you were running those commands in your R console. In those cases ,you'll need to adjust the file paths to locate the image and script on your disk relative to the source Rmd file.

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.