2 App Structure

2.1 Read the required documentation

Before learning how the app is structured you need to have a basic comprehension of Shiny and the Golem framework. Please read the following:

  • Mastering Shiny: A comprehensive book on Shiny. It contains almost all the information you need to interact with the Shiny part of Teachvatory. I recommend starting with Chapters 1 to 4 if you have not had any experience with Shiny before. If you already know some Shiny, feel free to skip those chapters.
    • Chapters 1 to 8 (Required)
    • Chapter 10 (Required)
    • Chapters 12 (Required)
    • Chapter 13 and 14 (Recommended)
    • Chapters 19 and 20 (Required).
  • Engineering Production-Grade Shiny Apps: This is the book to understand our app’s structure. Teachvatory is built using the Golem Framework, which is explained in detail in this book. Do not continue reading the documentation before learning about Golem - it would make your learning process much harder. To understand Teachvatory you won’t need to read all the chapters - with the following list you will be ok:
    • Chapters 3 and 4: Introduce Golem. (Required)
    • Chapter 8: Explains how to create a Golem app from scratch. Although we will not be creating a new application, I think it is important that you understand what each configuration file does. (Required)
    • Chapter 10: Explains how to develop your app using Golem’s functions. (Required)

Once you have read the required chapters we are ready to go into our app’s structure.

2.2 Teachvatory code structure

Teachvatory follows the Golem Framework. This means that all the files are organized and named following the Golem conventions (which, at the same time, follows the .R package conventions). (If you have not read Chapter 4 of Engineering Production-Grade Shiny apps yet, this is a good time to do it).

├── LICENSE.md
├── R
│   ├── _disable_autoload.R
│   ├── app_config.R
│   ├── app_server.R
│   ├── app_ui.R
│   ├── fct_driveaccess.R
│   ├── fct_polishedauth.R
│   ├── globalvars.R
│   ├── mod_conventions.R
│   ├── mod_metrics.R
│   ├── mod_metrics_fct_logic.R
│   ├── mod_quiz.R
│   ├── mod_quiz_questionviz.R
│   ├── mod_quiz_questionviz_fct_graphs.R
│   ├── mod_quiz_questionviz_fct_uidynamic.R
│   ├── mod_quiz_fct_logic.R
│   ├── mod_roster.R
│   └── run_app.R
├── README.Rmd
├── README.md
├── app.R
├── config.yml
├── dev
│   ├── 01_start.R
│   ├── 02_dev.R
│   ├── 03_deploy.R
│   ├── googledrive_auth.R
│   └── run_dev.R
├── inst
│   ├── app
│   │   └── www
│   │       ├── favicon.ico
│   │       └── img
│   │           ├── logo_dark_background.png
│   │           ├── logo_white_background.png
│   │           ├── logosymbol_dark_background.png
│   │           └── logosymbol_white_background.png
│   └── golem-config.yml
├── man
│   ├── chart_multiplechoise_multiple.Rd
│   ├── (...)
├── rsconnect
│   └── shinyapps.io
│       └── gonzalojara
│           └── teachvatory.dcf
├── teachvatory.Rproj
└── tests
    ├── testthat
    │   ├── test-mod_quiz_questionviz.R
    │   └── (...)
    └── testthat.R

2.2.1 ./

  • DESCRIPTION contains the package information such as title, description, author, and app version. No need to change it.

  • LICENSE and the LICENSE.md files define the app licences. No need to change them.

  • NAMESPACE is an autogenerated file that contains the packages dependecies. You should never edit it by hand. The file is automatically updated when a new package is added with usethis::use_package("package-name") and referenced in the app using import or package-name::func().

  • README.mdand README.rmd are used to create a landing page at the GitHub page.

  • ./config.yml contains the private variables that are needed in the app. It also allows to use .R when preceding the expresion with !expr. In this example, the app is calling for the private variables POLISED_APP_NAME and POLISHED_API_KEY that are defined in our .Renviron file.

      polished_app_name: !expr Sys.getenv("POLISHED_APP_NAME")
      polished_api_key: !expr Sys.getenv("POLISHED_API_KEY")

2.2.2 .R/

All the .R files that defines the application logic are located in the R/ folder. Inside these files you will find the content of your modules (created with golem::add_modules()), and the utilitarian and business functions (created with golem::add_utils()and golem::add_fct()).

  • _disable_autoload.R is an autogerated file to disable the autoload of shinyapps.io. No need to change it.
  • app_config.R contains the mechanics for golem. You do not need to modify this file.
  • app_server.R is the main server configuration. In this file the app handles the user interaction with the navigation bars, load the MasterQuiz metadata, and the Roster file. It is also where the app call to the modules’ server function.
  • app_ui.R is the main UI configuration. In this file you can change the dashboard left, right, top, and bottom navigation bar. It also calls the modules’ UIs.
  • fct_driveraccess.R and fct_polishedauth contains functions to interact with Google Drive Files and the Polished authentication systems, respectively. (Note that because these are business-specific functions, the .R files start with fct_).
  • global_vars.R defines variables that are used in the app like the Dashboard URL, or the name used in the quizes to identify a student. You should never put private variables, like the API keys, here.
  • mod_conventions.R, mod_metrics.R, mod_quiz.R, and mod_roster.R are the main modules of the app. These modules contains the UI and server functions for each of the sections that you see in the left navigation bar.
  • mod_metrics_fct_logic.R and mod_quiz_fct_logic.R are two business-specific functions used in mod_metrics.R and mod_quiz.R, respectively.
  • mod_quiz_questinviz.R is a module that is called inside the mod_quiz.R module. You can think of this as a second-level module. This module takes care of the questions’ visualizations.
  • mod_quiz_questionviz_fct_graphs.R and mod_quiz_questionviz_fct_uidynamic.R are two business-specific files with functions that are used to create the graphs and UI for the mod_quiz_questionviz.R module. We could have put all the functions into one _fct file, or all of them inside mod_quiz_questionviz.R, and the functionality would have remained the same. Instead, we decide to break the code into different files so it would be easier to change and add functionalities.
  • run_app.R contains the run_app() function that is called when a new user connects to the app. You should not change this file unless you want to edit the authentication system or edit the login page.

2.2.3 dev/

The files in this folder are never called by the app. Instead, these files are meant to keep code that you will find yourself needing often when developing the app locally. You are not required to run any of these files; they serve only as a place to keep code and not forget them.

  • 01_start.R contains configuration code that you need to run when you first create a Golem app.
  • 02_dev.R contains code that you will need to run when developing the app, like the function to create new modules, or _fct and _utils.
  • 03_deploy.R contains code that you will need to run when deploying the app.
  • googledrive_auth.R is a configuration file that you will need to run whenever you want to change the .secrets of the app needed to connect to the Google Files API.
  • run_dev.R contains the block of code that you need to run to start the app locally.

2.2.4 inst/

In this folder you will find the golem_config.yml file and the public resources.

  • app/www/ is where you put resourcer that will need to be accesed on the web, like pictures.
  • golem_config.yml is a file to define variables for golem. We do not use this file for keeping variables as we use ./config.yml in the root folder instead.

2.2.5 man/

These files are automatically generated when building the app. These files contain the functions descriptions created using the roxygen2 convention.


#' Get sheetnames of file in course directory
#' @description Filter a `directory` (dribble) by `filter` and returns
#' the sheetnames of the file.
#' @param directory A dribble of files in a directory
#' @param filter A string of the file to open
#' @return A list of sheetnames or `c("")` if fail.
#' @import dplyr stringr googlesheets4 googledrive
get_sheetnames <- function(directory, filter) {
      filter_path <- directory %>%
        filter(name == filter)
      metadata <- googlesheets4::gs4_get(filter_path %>% head(1))
    error = function(e) {

By using this structure when defining a function, the app will autogenerate a file get_sheetnames.Rd with the description above of the function. This is useful for keeping a clean documentation.

2.2.6 rsconnect/

This folder contains the configurations to connect to shinyapps.io, which are needed to deploy the app.

2.2.7 tests/

This folder contains the .R scripts that run the tests for the app. We are not currently implementing tests in Teachvatory