-
Notifications
You must be signed in to change notification settings - Fork 142
RCloud Extensions
RCloud can be extended in three different ways:
- new user interface features on the client side
- new kinds of notebook content that integrate R and JavaScript functionality
- new cell languages on the server side
The basic mechanism for each of these kinds of extensions is the same: the R package. An RCloud extension, therefore, is just an R package which expects to be run in the RCloud environment, and the RCloud environment spans a process running on a server and a web browser running on a client.
Here is a basic introduction to the features of R packages which you will need for creating an RCloud extension. General (and comprehensive) information on creating R packages can be found on CRAN.
An R package is directory of files in a particular structure. They can include source files of any number of languages, which makes them great for RCloud packages.
Files at the root level:
-
DESCRIPTION
- contains metadata about the package. Details below -
NAMESPACE
- lists any names that to be available to the R session. (The NAMESPACE file has other name operations which don't concern us here - this document is one place to learn more.)
Optional directories:
-
R/
- contains R sources -
inst/javascript
- contains javascript sources to be loaded dynamically by the package. See the next section for details. -
inst/python
,inst/...
- contains python sources -
inst/www
- contains static resources to be served by HTTP, such as HTML, javascript, or images. If packagex
contains fileinst/www/y.html
, andrcloud.org
is an RCloud server (it's not), theny.html
will be available athttp://rcloud.org/shared.R/x/y.html
By convention, packages that install JavaScript to the RCloud client have a file R/zzz.R
with a function .onLoad
. (The reason for this filename is just to put it last so that it loads after any other R sources.)
Here is a typical zzz.R
, from the rcloud.enviewer package that displays the Workspace panel:
rcloud.enviewer.caps <- NULL
.onLoad <- function(libname, pkgname)
{
f <- function(module.name, module.path) {
path <- system.file("javascript", module.path, package="rcloud.enviewer")
caps <- rcloud.install.js.module(module.name,
paste(readLines(path), collapse='\n'))
caps
}
rcloud.enviewer.caps <<- f("rcloud.enviewer", "rcloud.enviewer.js")
if(!is.null(rcloud.enviewer.caps)) {
ocaps <- list(refresh = rcloud.support:::make.oc(rcloud.enviewer.refresh),
view_dataframe = rcloud.support:::make.oc(rcloud.enviewer.view.dataframe))
rcloud.enviewer.caps$init(ocaps)
}
}
The internal function f
finds a javascript source within the package and installs it on the client dynamically.
The next line calls this function in order to install rcloud.enviewer.js
, which contains GUI code for the extension.
Finally, if the function returns non-null, it means the package was loaded in an RCloud session and it is safe to call the JavaScript functions that were returned. So this function uses rcloud.support:::make.oc
to wrap a couple of R functions from the same package that the client code will need, rcloud.enviewer.refresh
and rcloud.enviewer.view.dataframe
, and passes them to the client initialization function which was returned.
See [R-JavaScript binding](R-JavaScript binding) for more details on how to call R functions from JavaScript, and JavaScript functions from R.
The DESCRIPTION
file in the root of an R package contains metadata about the package, as key-value pairs separated by :
. Where there is more than one value, the values are separated by commas.
The fields we need for an RCloud package are:
-
Package
- the name of the package -
Title
- longer title of the package -
Version
- the version of the package -
Author
- name and email of the original author(s) of the package -
Maintainer
- name and email of the package's maintainer -
Description
- a human-readable description of the package -
Imports
- packages this depends on, which will be loaded but not attached (this package uses names from these packages, but won't add them to the global environment) -
License
- if the package is open-source, names the open source license