1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
|
% 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)
}
|