Files
shiny/man/createRenderFunction.Rd
Carson Sievert 56ab530d87 v1.9.0 release candidate (#4105)
* Start v1.9.0 release candidate

* Check-in revdep results

* `yarn build` (GitHub Actions)

* Sync package version (GitHub Actions)

* `yarn build` (GitHub Actions)

* ran revdepcheck on cloud. 2 errors reported. Both seem like false positives

* Fix R CMD check note about Rd links targets missing package anchors

---------

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
Co-authored-by: Barret Schloerke <barret@posit.co>
Co-authored-by: schloerke <schloerke@users.noreply.github.com>
2024-07-29 17:10:38 -05:00

196 lines
7.1 KiB
R

% 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)
}