Skip to contents

Files: what is where

The root folder

  • DESCRIPTION, LICENCE, NAMESPACE, LICENSE.md are metadata files related to R packages

dev

Contains files related to the development of the app.

You should create:

  • a folder (e.g. dev/dev_events) for event files in the development phase. Change the call to run_app in run_dev.R to indicate the path to this folder
  • a user database (you can use create_user_db.R for this). This too should be indicated in run_dev.R

01_start.R, 02_dev.R and 03_deploy.R contain useful commands related to app development. These are files created by the Golem framework. 02_dev.R is the most useful of these, it can be used to indicate dependencies to other packages, create new modules etc.

run_dev.R is the script that golem::run_dev() runs (note, you should always use this command to run the app when developing it). It sets up the app for running it while developing the app. Here you can indicate whether you want the app to run in production or development mode.

inst

  • golem-config.yml is a configuration file related to Golem. Note, don’t change the version number by hand here; see dev/02_dev.R instead.
  • inst/app/www/script.js is a javascript file the app uses. It is added as a head tag to the app html. It is mostly related to the table and fileInput modules.
  • inst/user_doc/inst_frontpage is a file that the login page will use to generate the text paragraphs.

inst/extdata

This folder is home to three important files.

ui_structure.json

Contains the structure of each UI element. Each item in this file has at least the following fields:

  • code_name is the name used to refer to the widget in the app
  • type is the type of the widget. This is one of the following (listed under each type are the possible fields related to the type):
    • selectInput
      • choices: a list of choices, a category in display_names.csv or "IGNORE". See the documentation for the function get_selectInput_choices defined in fct_ui.R.
      • multiple: are multiple choices allowed? Defaults to false.
    • numericInput
      • min: The smallest acceptable value (inclusive)
      • max: The largest acceptable value (inclusive)
      • step: If set to 1, only integer values are allowed
      • sum_to, sum_of: related to the calculation of yield sums in harvest_crop_table
    • fileInput
      • filetype: The type of files that should be accepeted. See Shiny documentation for the fileInput widget. This is not necessarily enforced.
    • textInput
      • placeholder: Code name of placeholder
    • textAreaInput
      • placeholder: Code name of placeholder
      • maxlength: The maximum acceptable length (in characters) of the value
    • textOutput
      • dynamic: If defined, indicates how the text should be adjusted during the execution of app. See form_title for an illustrative (and only) example.
      • style: "label" if the text should look like a widget label.
    • actionButton
    • dateInput
    • dateRangeInput
    • dataTable
      • columns: The columns of the table in case it has a dynamic row group
      • rows: A list of row groups. There are two types of row groups: dynamic and static. There can be at most one dynamic row group and it comes first. There can be multiple static row groups. For dynamic row groups the row_variable field indicates the widget which determines the rows of the dynamic row group. For static rows the variable names of the desired widgets are listed under variables and hide_labels can be used to hide the labels of these widgets (labels of the widgets in the dynamic row group are automatically hidden). The name of a static row can be defined in name.

Other fields:

  • label: the code name of the label of the widget (this will be found from display_names.csv)
  • required: is it compulsory to fill the widget before the event can be saved? Defaults to false.
  • hide_in_event_list: should this variable be hidden in the event list (when viewing a specific activity type)? Defaults to false.
  • condition: this isn’t specified for single widgets but for groups of widgets. This is the condition (in javascript) which determines whether the widget group in question should be visible or not. This is given to a Shiny element called ConditionalPanel.
display_names.csv

A csv file with four columns: category, code_name, disp_name_eng and disp_name_fin. Each row is a translation of a code name into the different languages. The category can be used to e.g. point a set of these names as the choices of a selectInput widget.

FOsites.csv

A csv file which contains the sites and their blocks. Note, the user names in the user database should match the names of these sites exactly (including case).

man, vignettes

man contains the function documentation generated by Roxygen2, vignettes contains this vignette.

tests

All tests should be placed under tests/testthat. The testthat package is used. Currently automated test are made to check that changing language works as expected, and that downloading buttons return a valid file.

R

This is the folder which contains the actual bulk of the application. run_app.R defines the function which launches the app. app_server.R and app_ui.R define the server and UI functions of the main app. fct_ and utils_ files contain helper functions. Files starting with mod_ are either modules or files directly related to modules.

The structure of the app

The structure of the app can be summarised as follows:

  • the main app consists of app_server.R and app_ui.R. The UI includes (in order)
    • the language and site selectors
    • button to download the user instructions for the app
    • the title and introduction text
    • the event list module (mod_event_list.R)
      • the event list includes a table showing a list of events and selectors to filter which events are displayed
      • buttons to download the events as a zipped json files or as a flat csv
    • buttons to create a new event and to clone an event
    • the form module (mod_form.R)
      • this contains all the widgets for entering information about an event and the save, cancel and delete event buttons
      • the default widgets (block, activity, date and description) are hard-coded in the UI function of the module. The activity-specific widgets are created by calling the create_ui function (defined in fct_ui.R) in that same UI function.
      • the widgets include standard Shiny widgets as well as table modules (mod_table.R) and fileInput modules (mod_fileInput.R).

Modules are a tool to make Shiny apps more, well, modular. Each module includes a UI function, which creates user interface components, and a server function which defines how those components should behave.

A module (more specifically, its server function) can be given input values which are usually reactives (reactive is a Shiny term. Reactive expressions can be thought of as functions which store their value and only recalculate it when it is no longer valid.). For example, the language chosen in the main app is passed on to other modules as a reactive expression – when the language is changed by the user, that reactive can be used to access the latest language in the modules. Modules can also return values, and these values are usually reactive as well. For example, the form module returns the values of widgets to the main app server function, which goes on to edit or create a json file based on this information.

The startup process

A few words about the process of starting the app, as that became a bit more complex recently. The app is started by a call to the run_app function, defined in R/run_app.R. The app can be started in two modes, production mode or developer mode. This is controlled by the option golem.app.prod:

options(golem.app.prod = TRUE) # use production mode and hence user authentication
options(golem.app.prod = FALSE) # skip authentication
# run_app(...)

It is in this run_app.R file where the app is “wrapped in shinymanager” to display the authentication UI if the app is in production mode.

When the app starts, the app_server server function in R\app_server.R is initialised. It is here that the event list module server is initialised as well. However, calling the server function of the form module is delayed until a site is specified (either by logging in to a user account specific to a site or in admin mode where the site selector is visible). This is done to decrease the time it takes for the main app UI to be displayed. However, this causes a small delay in the loading of events in the event list.

The form server is initialised by calling the function initialise_form defined within the app_server function. Furthermore, when the form server function is initialised, it does not yet initialise the server function of table or fileInput modules on the form. Instead, they are initialised the first time the form is shown. Their initialisation happens by sending an initialisation signal to the form through a reactive (init_signal), which is being listened to by the form server function.

Useful resources