knitr::opts_chunk$set( collapse = TRUE, comment = "#>" )
As a reminder, the namespace is an important aspect of shiny module that prevents collision of input and output IDs in your application. The namespace identify each unique instance of the modules and need to be provided by the caller.
{tidymodules}
can be considered as an object-oriented organisational layer on top of shiny that does conventional module in the background.
It does use namespace but make it optional to the users. In other words, you don't need to remember it!
In the example below a {tm}
module MyMod
is defined and called with the new()
function and with no arguments supplied.
Printing the instance m
to the console shows the structure of the module.
library(tidymodules) MyMod <- R6::R6Class( "MyMod", inherit = TidyModule ) m <- MyMod$new() m
The namespace Id for module m
above is MyMod-1
. It is a unique Id generated by {tidymodules}
and composed of the class name and the initialisation order of the module.
The user can also provide a more informative name when initialising a module.
m <- MyMod$new("Tom") m
Tom
end up being the namespace Id of m
.
The provided name must begin with a letter [A-Za-z]
and may be followed by any number of letters, digits [0-9]
, hyphens -
, underscores _
.
You should not use the following characters as they have a special meaning on the UI ( CSS / jQuery ).
~ ! @ $ % ^ & * ( ) + = , . / ' ; : " ? > < [ ] \ { } | ` #
The code below illustrates a very simple example of nested module and the corresponding namespace Ids. Here are few things to note about this example:
ModA
and ModB
are both {tm}
classes as they both inherit from tidymodules::TidyModule
ModB
is used as a nested class of ModA
ModA
has a public field named nested_mod
ModB <- R6::R6Class( "ModB", inherit = TidyModule ) ModA <- R6::R6Class( "ModA", inherit = TidyModule, public = list( nested_mod = NULL, initialize = function(...) { super$initialize(...) self$nested_mod <- ModB$new() } ) ) m <- ModA$new() n <- m$nested_mod m n
This option allows the grouping of {tm}
modules together to facilitate their retrieval from the ModStore
and to better visualize them later in a network diagram.
ta <- MyMod$new("Tom", group = "A") tb <- MyMod$new("Tom", group = "B") ta tb
As you can see above the group argument is used to define the final namespace Id of the modules. Those modules share the same name but have different namespace IDs.
A {tm}
module namespace is a concatenation of many fields.
name
and group
{tidymodules}
: id
, parent_ns
and module_ns
the module's namespace is built like this
id = <group>_<name> module_ns = <parent_ns>_<id>
#' @field name Name of the module, either generated for or provided by the user. n$name ta$name #' @field group Group name of the module. n$group ta$group #' @field id ID of the module. n$id ta$id #' @field parent_ns Parent module namespace in case of nested modules. n$parent_ns ta$parent_ns #' @field module_ns Module namespace, unique identifier for the module. n$module_ns ta$module_ns
Like in conventional module, {tm}
module also requires wrapping UI elements with the namespace.
The function named ns()
available in all {tm}
modules should be used to namespace the inputs.
As you can see in the example below, you simply need to call the function using the self
R6 keyword.
There is no need to remember the modules's namespace anymore.
MyMod <- R6::R6Class( "MyMod", inherit = TidyModule, public = list( ui = function() { shiny::tagList( shiny::numericInput(self$ns("inputId"), NULL, 0) ) } ) ) m <- MyMod$new() as.character(m$ui())
ModStore
and module lookupThe ModStore
is an internal repository for all {tm}
modules and connections (see communication article for learning how to connect modules). It is a shared environment created by {tidymodules}
that orginizes the objects (modules and edges) by applications and sessions.
This allows to track and easily retrieve the modules anywhere in the application.
All the examples above show the creation of modules with the new()
R6 function and the assignment to variables (pointers to the R6 objects).
However {tidymodules}
also offers the choice to not save module references and instead use the getMod()
or mod()
utility functions to retrieve existing module. Note that mod()
is just an alias of getMod()
.
MyMod$new("SaveMeInStore") # look-up by namespace ID mod("SaveMeInStore") # look-up by index mod(2) # look-up by index within a group mod(1, group = "A")
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.