supreme
supreme is a modeling tool helping you better structure Shiny applications developed with modules.
Therefore, you are able to:
-
Visualize relationship of modules in existing applications
-
Design new applications from scratch
Installation
You can install the released version from CRAN:
install.packages("supreme")
Or get the development version from GitHub:
# install.packages("devtools")
devtools::install_github("strboul/supreme")
Usage
Existing applications
For your existing application, you can use src_file()
call that reads
your application from files.
supreme package comes with an example path containing a dummy Shiny
application created with modules for testing issues (in
example_app_path()
).
After the application has been read, create a supreme object from the model object:
library(supreme)
path <- example_app_path()
obj <- supreme(src_file(path))
obj
#> A supreme model object
#> 5 entities: server, customers_tab_module_server, items_tab_module_server, transactions_tab_module_server, ...
See the generated supreme object in tabular form a.k.a. data.frame
:
as.data.frame(obj)
#> name input
#> 1 server NA
#> 2 customers_tab_module_server customers_list
#> 3 items_tab_module_server items_list, is_fired
#> 4 transactions_tab_module_server table, button_clicked
#> 5 module_modal_dialog text
#> output return calling_modules
#> 1 NA <NA> list(ite....
#> 2 paid_customers_table, free_customers_table <NA> NA
#> 3 NA <NA> list(mod....
#> 4 transactions_table transactions_keys NA
#> 5 NA <NA> NA
#> src
#> 1 app.R
#> 2 module-customers.R
#> 3 module-items.R
#> 4 module-transactions.R
#> 5 module-utils.R
Finally, visualize the module structure:
graph(obj)
Creating YAML model objects
Model definition with YAML is a handy to design a new application from scratch or just design the specific parts of applications. Planning ahead with model tool can really be beneficial before going wild on implementation.
- name: server
calling_modules:
- items_tab_module_server: ItemsTab
- customers_tab_module_server: CustomersTab
- transactions_tab_module_server: TransactionsTab
src: app.R
- name: customers_tab_module_server
input: customers_list
output:
- paid_customers_table
- free_customers_table
src: module-customers.R
- name: items_tab_module_server
input:
- items_list
- is_fired
calling_modules:
- module_modal_dialog: ~
src: module-items.R
- name: transactions_tab_module_server
input:
- table
- button_clicked
output: transactions_table
return: transactions_keys
src: module-transactions.R
- name: module_modal_dialog
input:
- text
src: module-utils.R
There are some special rules when creating model objects with YAML:
-
Each entity in the model must have a name field.
-
The entities can have optional fields, which are input, output, return, calling_modules and src.
-
The fields input, output, return and calling_modules can have multiple elements means that these fields can contain an array in the YAML. The other fields can only have a single element.
-
Any other field, which is not known by the supreme modal object, is not allowed and it will throw an error.
After all, use src_yaml()
to read modeling from the YAML file:
model_yaml <- src_yaml(text = model)
obj <- supreme(model_yaml)
See the next section to understand how the model language works.
The model language
A supreme object is consisted by entities. An “entity” denotes
here that a Shiny server component is allowed to either be a server side
of a module or the main server
function of a Shiny application.
A graph entity consists of five main fields:
-
Module name
-
Module inputs (except the defaults input, output, session)
-
Module outputs
-
Module returns
-
Calling modules, which are modules called by the module
Known limitations
-
Although it’s possible to create a Shiny application by only providing
input
andoutput
arguments in the server side, supreme will not read any Shiny server side component missing asession
argument. That’s reasonable decision because modules cannot work withoutsession
argument and supreme is a package designed to work with Shiny modules. -
For the module returns, all return values in a module should explicitly be wrapped in
return()
call. -
supreme will not properly parse the source code of your application if server side component is created with
shinyServer()
, which is kind of soft-deprecated after a very early Shiny version0.10
. -
Some idiosyncratic Shiny application code may not be parsed as intended. For such cases, it would be great if you open an issue describing the situation with a reproducible example.
Acknowledgment
-
R Core Team: supreme package is brought to life thanks to R allowing abstract syntax trees (AST) that is used to practice static analysis on the code.
-
datamodelr: Inspiring work for creating modeling language
-
shinypod: Interesting thoughts regarding the implementation of Shiny modules
License
MIT © Metin Yazici