% Generated by roxygen2: do not edit by hand % Please edit documentation in R/shinywrappers.R, R/utils-lang.R \name{createRenderFunction} \alias{createRenderFunction} \alias{quoToFunction} \alias{installExprFunction} \title{Implement custom render functions} \usage{ createRenderFunction( func, transform = function(value, session, name, ...) value, outputFunc = NULL, outputArgs = NULL, cacheHint = "auto", cacheWriteHook = NULL, cacheReadHook = NULL ) quoToFunction(q, label = sys.call(-1)[[1]], ..stacktraceon = FALSE) installExprFunction( expr, name, eval.env = parent.frame(2), quoted = FALSE, assign.env = parent.frame(1), label = sys.call(-1)[[1]], wrappedWithLabel = TRUE, ..stacktraceon = FALSE ) } \arguments{ \item{func}{A function without parameters, that returns user data. If the returned value is a promise, then the render function will proceed in async mode.} \item{transform}{A function that takes four arguments: \code{value}, \code{session}, \code{name}, and \code{...} (for future-proofing). This function will be invoked each time a value is returned from \code{func}, and is responsible for changing the value into a JSON-ready value to be JSON-encoded and sent to the browser.} \item{outputFunc}{The UI function that is used (or most commonly used) with this render function. This can be used in R Markdown documents to create complete output widgets out of just the render function.} \item{outputArgs}{A list of arguments to pass to the \code{uiFunc}. Render functions should include \code{outputArgs = list()} in their own parameter list, and pass through the value to \code{markRenderFunction}, to allow app authors to customize outputs. (Currently, this is only supported for dynamically generated UIs, such as those created by Shiny code snippets embedded in R Markdown documents).} \item{cacheHint}{One of \code{"auto"}, \code{FALSE}, or some other information to identify this instance for caching using \code{\link[=bindCache]{bindCache()}}. If \code{"auto"}, it will try to automatically infer caching information. If \code{FALSE}, do not allow caching for the object. Some render functions (such as \link{renderPlot}) contain internal state that makes them unsuitable for caching.} \item{cacheWriteHook}{Used if the render function is passed to \code{bindCache()}. This is an optional callback function to invoke before saving the value from the render function to the cache. This function must accept one argument, the value returned from \code{renderFunc}, and should return the value to store in the cache.} \item{cacheReadHook}{Used if the render function is passed to \code{bindCache()}. This is an optional callback function to invoke after reading a value from the cache (if there is a cache hit). The function will be passed one argument, the value retrieved from the cache. This can be useful when some side effect needs to occur for a render function to behave correctly. For example, some render functions call \code{\link[=createWebDependency]{createWebDependency()}} so that Shiny is able to serve JS and CSS resources.} \item{q}{Quosure of the expression \code{x}. When capturing expressions to create your quosure, it is recommended to use \code{\link[rlang:defusing-advanced]{rlang::enquo0()}} to not unquote the object too early. See \code{\link[rlang:defusing-advanced]{rlang::enquo0()}} for more details.} \item{label}{A label for the object to be shown in the debugger. Defaults to the name of the calling function.} \item{expr}{A quoted or unquoted expression, or a quosure.} \item{name}{The name the function should be given} \item{eval.env}{The desired environment for the function. Defaults to the calling environment two steps back.} \item{quoted}{Is the expression quoted?} \item{assign.env}{The environment in which the function should be assigned.} \item{wrappedWithLabel, ..stacktraceon}{Advanced use only. For stack manipulation purposes; see \code{\link[=stacktrace]{stacktrace()}}.} } \value{ An annotated render function, ready to be assigned to an \code{output} slot. } \description{ Developer-facing utilities for implementing a custom \code{renderXXX()} function. Before using these utilities directly, consider using the \href{http://www.htmlwidgets.org/develop_intro.html}{\code{htmlwidgets} package} to implement custom outputs (i.e., custom \code{renderXXX()}/\code{xxxOutput()} functions). That said, these utilities can be used more directly if a full-blown htmlwidget isn't needed and/or the user-supplied reactive expression needs to be wrapped in additional call(s). } \details{ To implement a custom \code{renderXXX()} function, essentially 2 things are needed: \enumerate{ \item Capture the user's reactive expression as a function. \itemize{ \item New \code{renderXXX()} functions can use \code{quoToFunction()} for this, but already existing \code{renderXXX()} functions that contain \code{env} and \code{quoted} parameters may want to continue using \code{installExprFunction()} for better legacy support (see examples). } \item Flag the resulting function (from 1) as a Shiny rendering function and also provide a UI container for displaying the result of the rendering function. \itemize{ \item \code{createRenderFunction()} is currently recommended (instead of \code{\link[=markRenderFunction]{markRenderFunction()}}) for this step (see examples). } } } \section{Functions}{ \itemize{ \item \code{quoToFunction()}: convert a quosure to a function. \item \code{installExprFunction()}: converts a user's reactive \code{expr} into a function that's assigned to a \code{name} in the \code{assign.env}. }} \examples{ # A custom render function that repeats the supplied value 3 times renderTriple <- function(expr) { # Wrap user-supplied reactive expression into a function func <- quoToFunction(rlang::enquo0(expr)) createRenderFunction( func, transform = function(value, session, name, ...) { paste(rep(value, 3), collapse=", ") }, outputFunc = textOutput ) } # For better legacy support, consider using installExprFunction() over quoToFunction() renderTripleLegacy <- function(expr, env = parent.frame(), quoted = FALSE) { func <- installExprFunction(expr, "func", env, quoted) createRenderFunction( func, transform = function(value, session, name, ...) { paste(rep(value, 3), collapse=", ") }, outputFunc = textOutput ) } # Test render function from the console reactiveConsole(TRUE) v <- reactiveVal("basic") r <- renderTriple({ v() }) r() #> [1] "basic, basic, basic" # User can supply quoted code via rlang::quo(). Note that evaluation of the # expression happens when r2() is invoked, not when r2 is created. q <- rlang::quo({ v() }) r2 <- rlang::inject(renderTriple(!!q)) v("rlang") r2() #> [1] "rlang, rlang, rlang" # Supplying quoted code without rlang::quo() requires installExprFunction() expr <- quote({ v() }) r3 <- renderTripleLegacy(expr, quoted = TRUE) v("legacy") r3() #> [1] "legacy, legacy, legacy" # The legacy approach also supports with quosures (env is ignored in this case) q <- rlang::quo({ v() }) r4 <- renderTripleLegacy(q, quoted = TRUE) v("legacy-rlang") r4() #> [1] "legacy-rlang, legacy-rlang, legacy-rlang" # Turn off reactivity in the console reactiveConsole(FALSE) }