mirror of
https://github.com/rstudio/shiny.git
synced 2026-01-10 23:48:01 -05:00
Compare commits
12 Commits
py-shiny
...
jeff-skele
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
337f4c9c40 | ||
|
|
e86c0c4be4 | ||
|
|
44a485b07a | ||
|
|
9138adf8a1 | ||
|
|
e588fc5a4a | ||
|
|
19965c9eb7 | ||
|
|
98e390bc1b | ||
|
|
3994055056 | ||
|
|
374f7c2aa2 | ||
|
|
27ad5d6110 | ||
|
|
d374f1dc88 | ||
|
|
38349f354d |
@@ -102,6 +102,7 @@ URL: http://shiny.rstudio.com
|
||||
BugReports: https://github.com/rstudio/shiny/issues
|
||||
Collate:
|
||||
'app.R'
|
||||
'app_template.R'
|
||||
'bookmark-state-local.R'
|
||||
'stack.R'
|
||||
'bookmark-state.R'
|
||||
|
||||
@@ -230,6 +230,7 @@ export(setSerializer)
|
||||
export(shinyApp)
|
||||
export(shinyAppDir)
|
||||
export(shinyAppFile)
|
||||
export(shinyAppTemplate)
|
||||
export(shinyOptions)
|
||||
export(shinyServer)
|
||||
export(shinyUI)
|
||||
|
||||
230
R/app_template.R
Normal file
230
R/app_template.R
Normal file
@@ -0,0 +1,230 @@
|
||||
#' Generate a Shiny application from a template
|
||||
#'
|
||||
#' This function populates a directory with files for a Shiny application.
|
||||
#'
|
||||
#' In an interactive R session, this function will, by default, prompt the user
|
||||
#' which components to add to the application.
|
||||
#'
|
||||
#' The full example application includes the following files and directories:
|
||||
#'
|
||||
#' ```
|
||||
#' appdir/
|
||||
#' |- app.R
|
||||
#' |- R
|
||||
#' | |- my-module.R
|
||||
#' | |-- sort.R
|
||||
#' `-- tests
|
||||
#' |- server.R
|
||||
#' |- server
|
||||
#' | |- test-mymodule.R
|
||||
#' | `- test-server.R
|
||||
#' |- shinytest.R
|
||||
#' |- shinytest
|
||||
#' | `- mytest.R
|
||||
#' |- testthat.R
|
||||
#' `-- testthat
|
||||
#' |- helper-load.R
|
||||
#' `- test-sort.R
|
||||
#' ```
|
||||
#'
|
||||
#' Some notes about these files:
|
||||
#' * `app.R` is the main application file.
|
||||
#' * All files in the `R/` subdirectory are automatically sourced when the
|
||||
#' application is run.
|
||||
#' * `R/sort.R` and `R/my-module.R` are automatically sourced when
|
||||
#' the application is run. The first contains a function `lexical_sort()`,
|
||||
#' and the second contains code for a [Shiny module](moduleServer()) which
|
||||
#' is used in the application.
|
||||
#' * `tests/` contains various tests for the application. You may
|
||||
#' choose to use or remove any of them. They can be executed by the
|
||||
#' [runTests()] function.
|
||||
#' * `tests/server.R` is a test runner for test files in
|
||||
#' `tests/server/`.
|
||||
#' * `tests/server/test-mymodule.R` is a test for the module.
|
||||
#' * `tests/shinytest.R` is a test runner for test files in the
|
||||
#' `tests/shinytest/` directory.
|
||||
#' * `tests/shinytest/mytest.R` is a test that uses the
|
||||
#' [shinytest](https://rstudio.github.io/shinytest/) package to do
|
||||
#' snapshot-based testing.
|
||||
#' * `tests/testthat.R` is a test runner for test files in the
|
||||
#' `tests/testthat/` directory.
|
||||
#' * `tests/testthat/helper-load.R` is a helper script that is automatically
|
||||
#' loaded before running `test-mymodule.`R. (This is performed by the testthat
|
||||
#' package.)
|
||||
#' * `tests/testthat/test-sort.R` is a set of tests that use the
|
||||
#' [testthat](https://testthat.r-lib.org/) package for testing.
|
||||
#'
|
||||
#' @param path Path to create new shiny application template.
|
||||
#' @param examples Either one of "default", "ask", "all", or any combination of
|
||||
#' "app", "rdir", "module", "shinytest", "testthat", and "server". In an
|
||||
#' interactive session, "default" falls back to "ask"; in a non-interactive
|
||||
#' session, "default" falls back to "all". With "ask", this function will
|
||||
#' prompt the user to select which template items will be added to the new app
|
||||
#' directory. With "all", all template items will be added to the app
|
||||
#' directory.
|
||||
#'
|
||||
#' @export
|
||||
shinyAppTemplate <- function(path = NULL, examples = "default")
|
||||
{
|
||||
if (is.null(path)) {
|
||||
stop("Please provide a `path`.")
|
||||
}
|
||||
|
||||
choices <- c(
|
||||
app = "app.R : Main application file",
|
||||
rdir = "R/sort.R : Helper file with R code",
|
||||
module = "R/my-module.R : Example module",
|
||||
shinytest = "tests/shinytest/ : Tests using shinytest package",
|
||||
testthat = "tests/testthat/ : Tests using testthat",
|
||||
server = "tests/server/ : Tests of server and module code"
|
||||
)
|
||||
|
||||
if (identical(examples, "default")) {
|
||||
if (interactive()) {
|
||||
examples <- "ask"
|
||||
} else {
|
||||
examples <- "all"
|
||||
}
|
||||
}
|
||||
|
||||
if (!identical(examples, "ask") &&
|
||||
!identical(examples, "all") &&
|
||||
any(! examples %in% names(choices)))
|
||||
{
|
||||
stop('`examples` must be one of "default", "ask", "all", or any combination of "',
|
||||
paste(names(choices), collapse = '", "'), '".')
|
||||
}
|
||||
|
||||
if (identical(examples, "ask")) {
|
||||
response <- select_menu(
|
||||
c(all = "All", choices),
|
||||
title = paste0(
|
||||
"Select which of the following to add at ", path, "/ :"
|
||||
),
|
||||
msg = "Enter one or more numbers (with spaces), or an empty line to exit: \n"
|
||||
)
|
||||
|
||||
examples <- names(response)
|
||||
}
|
||||
|
||||
examples <- unique(examples)
|
||||
|
||||
if ("all" %in% examples) {
|
||||
examples <- names(choices)
|
||||
}
|
||||
|
||||
if (length(examples) == 0) {
|
||||
return(invisible())
|
||||
}
|
||||
|
||||
# Check if a directory is empty, ignoring certain files
|
||||
dir_is_empty <- function(path) {
|
||||
files <- list.files(path, all.files = TRUE, no.. = TRUE)
|
||||
# Ignore .DS_Store files, which are sometimes automatically created on macOS
|
||||
files <- setdiff(files, ".DS_Store")
|
||||
return(length(files) != 0)
|
||||
}
|
||||
|
||||
# Helper to resolve paths relative to our example
|
||||
example_path <- function(path) {
|
||||
system.file("app_template", path, package = "shiny")
|
||||
}
|
||||
|
||||
# Copy the files for a tests/ subdirectory
|
||||
copy_test_dir <- function(name, with_rdir, with_module) {
|
||||
tests_dir <- file.path(path, "tests")
|
||||
dir.create(tests_dir, showWarnings = FALSE, recursive = TRUE)
|
||||
|
||||
files <- dir(example_path("tests"), recursive = TRUE)
|
||||
# Note: This is not the same as using dir(pattern = "^shinytest"), since
|
||||
# that will not match files inside of shinytest/.
|
||||
files <- files[grepl(paste0("^", name), files)]
|
||||
|
||||
# Filter out files related to R/sort.R, if applicable.
|
||||
if (!with_rdir) {
|
||||
files <- files[!grepl("utils", files)]
|
||||
}
|
||||
|
||||
# Filter out module files, if applicable.
|
||||
if (!with_module) {
|
||||
files <- files[!grepl("module", files)]
|
||||
}
|
||||
|
||||
# Create any subdirectories if needed
|
||||
dirs <- setdiff(unique(dirname(files)), ".")
|
||||
for (dir in dirs) {
|
||||
dir.create(file.path(tests_dir, dir), showWarnings = FALSE, recursive = TRUE)
|
||||
}
|
||||
|
||||
file.copy(
|
||||
file.path(example_path("tests"), files),
|
||||
file.path(path, "tests", files)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
if (is.null(path)) {
|
||||
stop("`path` is missing.")
|
||||
}
|
||||
if (file.exists(path) && !dir.exists(path)) {
|
||||
stop(path, " exists but is not a directory.")
|
||||
}
|
||||
|
||||
if (dir.exists(path) && dir_is_empty(path)) {
|
||||
if (interactive()) {
|
||||
response <- readline(paste0(
|
||||
ensure_trailing_slash(path),
|
||||
" is not empty. Do you want to create a Shiny app in this directory anyway? [y/n] "
|
||||
))
|
||||
if (tolower(response) != "y") {
|
||||
return(invisible())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
dir.create(path)
|
||||
}
|
||||
|
||||
# app.R - If "app", populate with example; otherwise use empty file.
|
||||
app_file <- file.path(path, "app.R")
|
||||
if ("app" %in% examples) {
|
||||
if (file.exists(app_file)) {
|
||||
message("Not writing ", app_file, "because file already exists.")
|
||||
|
||||
} else {
|
||||
writeChar(
|
||||
as.character(htmlTemplate(
|
||||
example_path("app.R"),
|
||||
rdir = "rdir" %in% examples,
|
||||
module = "module" %in% examples
|
||||
)),
|
||||
con = app_file,
|
||||
eos = NULL
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
# R/ dir with utils and/or module
|
||||
r_dir <- file.path(path, "R")
|
||||
if ("rdir" %in% examples) {
|
||||
dir.create(r_dir, showWarnings = FALSE, recursive = TRUE)
|
||||
file.copy(example_path("R/sort.R"), r_dir, recursive = TRUE)
|
||||
}
|
||||
if ("module" %in% examples) {
|
||||
dir.create(r_dir, showWarnings = FALSE, recursive = TRUE)
|
||||
file.copy(example_path("R/my-module.R"), r_dir, recursive = TRUE)
|
||||
}
|
||||
|
||||
# tests/ dir
|
||||
if ("shinytest" %in% examples) {
|
||||
copy_test_dir("shinytest", "rdir" %in% examples, "module" %in% examples)
|
||||
}
|
||||
if ("testthat" %in% examples) {
|
||||
copy_test_dir("testthat", "rdir" %in% examples, "module" %in% examples)
|
||||
}
|
||||
if ("server" %in% examples) {
|
||||
copy_test_dir("server", "rdir" %in% examples, "module" %in% examples)
|
||||
}
|
||||
if ("app" %in% examples) {
|
||||
message("Shiny application created at ", ensure_trailing_slash(path))
|
||||
}
|
||||
}
|
||||
26
R/utils.R
26
R/utils.R
@@ -316,6 +316,15 @@ resolve <- function(dir, relpath) {
|
||||
return(abs.path)
|
||||
}
|
||||
|
||||
# Given a string, make sure it has a trailing slash.
|
||||
ensure_trailing_slash <- function(path) {
|
||||
if (!grepl("/$", path)) {
|
||||
path <- paste0(path, "/")
|
||||
}
|
||||
path
|
||||
}
|
||||
|
||||
|
||||
isWindows <- function() .Platform$OS.type == 'windows'
|
||||
|
||||
# This is a wrapper for download.file and has the same interface.
|
||||
@@ -1812,3 +1821,20 @@ cat_line <- function(...) {
|
||||
cat(paste(..., "\n", collapse = ""))
|
||||
}
|
||||
|
||||
select_menu <- function(choices, title = NULL, msg = "Enter one or more numbers (with spaces), or an empty line to exit: \n")
|
||||
{
|
||||
if (!is.null(title)) {
|
||||
cat(title, "\n", sep = "")
|
||||
}
|
||||
nc <- length(choices)
|
||||
op <- paste0(format(seq_len(nc)), ": ", choices)
|
||||
fop <- format(op)
|
||||
cat("", fop, "", sep = "\n")
|
||||
repeat {
|
||||
answer <- readline(msg)
|
||||
answer <- strsplit(answer, "[ ,]+")[[1]]
|
||||
if (all(answer %in% seq_along(choices))) {
|
||||
return(choices[as.integer(answer)])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
27
inst/app_template/R/my-module.R
Normal file
27
inst/app_template/R/my-module.R
Normal file
@@ -0,0 +1,27 @@
|
||||
mymoduleUI <- function(id, label = "Counter") {
|
||||
# Al uses of Shiny input/output IDs in the UI must be namespaced,
|
||||
# as in ns("x").
|
||||
ns <- NS(id)
|
||||
tagList(
|
||||
actionButton(ns("button"), label = label),
|
||||
verbatimTextOutput(ns("out"))
|
||||
)
|
||||
}
|
||||
|
||||
mymoduleServer <- function(id) {
|
||||
# moduleServer() wraps a function to create the server component of a
|
||||
# module.
|
||||
moduleServer(
|
||||
id,
|
||||
function(input, output, session) {
|
||||
count <- reactiveVal(0)
|
||||
observeEvent(input$button, {
|
||||
count(count() + 1)
|
||||
})
|
||||
output$out <- renderText({
|
||||
count()
|
||||
})
|
||||
count
|
||||
}
|
||||
)
|
||||
}
|
||||
5
inst/app_template/R/sort.R
Normal file
5
inst/app_template/R/sort.R
Normal file
@@ -0,0 +1,5 @@
|
||||
# Given a numeric vector, convert to strings, sort, and convert back to
|
||||
# numeric.
|
||||
lexical_sort <- function(x) {
|
||||
as.numeric(sort(as.character(x)))
|
||||
}
|
||||
52
inst/app_template/app.R
Normal file
52
inst/app_template/app.R
Normal file
@@ -0,0 +1,52 @@
|
||||
ui <- fluidPage(
|
||||
{{
|
||||
# These blocks of code are processed with htmlTemplate()
|
||||
if (isTRUE(module)) {
|
||||
' # ======== Modules ========
|
||||
# mymoduleUI is defined in R/my-module.R
|
||||
mymoduleUI("mymodule1", "Click counter #1"),
|
||||
mymoduleUI("mymodule2", "Click counter #2"),
|
||||
# =========================
|
||||
'
|
||||
}
|
||||
}}
|
||||
wellPanel(
|
||||
sliderInput("size", "Data size", min = 5, max = 20, value = 10),
|
||||
{{
|
||||
if (isTRUE(rdir)) {
|
||||
' div("Lexically sorted sequence:"),'
|
||||
} else {
|
||||
' div("Sorted sequence:"),'
|
||||
}
|
||||
}}
|
||||
verbatimTextOutput("sequence")
|
||||
)
|
||||
)
|
||||
|
||||
server <- function(input, output, session) {
|
||||
{{
|
||||
if (isTRUE(module)) {
|
||||
' # ======== Modules ========
|
||||
# mymoduleServer is defined in R/my-module.R
|
||||
mymoduleServer("mymodule1")
|
||||
mymoduleServer("mymodule2")
|
||||
# =========================
|
||||
'
|
||||
}
|
||||
}}
|
||||
data <- reactive({
|
||||
{{
|
||||
if (isTRUE(rdir)) {
|
||||
' # lexical_sort from R/sort.R
|
||||
lexical_sort(seq_len(input$size))'
|
||||
} else {
|
||||
' sort(seq_len(input$size))'
|
||||
}
|
||||
}}
|
||||
})
|
||||
output$sequence <- renderText({
|
||||
paste(data(), collapse = " ")
|
||||
})
|
||||
}
|
||||
|
||||
shinyApp(ui, server)
|
||||
6
inst/app_template/tests/server.R
Normal file
6
inst/app_template/tests/server.R
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
files <- list.files("./server", full.names = FALSE)
|
||||
origwd <- getwd()
|
||||
setwd("./server")
|
||||
on.exit(setwd(origwd), add=TRUE)
|
||||
lapply(files, source, local=environment())
|
||||
19
inst/app_template/tests/server/test-mymodule.R
Normal file
19
inst/app_template/tests/server/test-mymodule.R
Normal file
@@ -0,0 +1,19 @@
|
||||
# Use testthat just for expectations
|
||||
library(testthat)
|
||||
|
||||
# See ?testServer for more information
|
||||
testServer(mymoduleServer, {
|
||||
# Set initial value of a button
|
||||
session$setInputs(button = 0)
|
||||
|
||||
# Check the value of the reactiveVal `count()`
|
||||
expect_equal(count(), 1)
|
||||
# Check the value of the renderText()
|
||||
expect_equal(output$out, "1")
|
||||
|
||||
# Simulate a click
|
||||
session$setInputs(button = 1)
|
||||
|
||||
expect_equal(count(), 2)
|
||||
expect_equal(output$out, "2")
|
||||
})
|
||||
11
inst/app_template/tests/server/test-server.R
Normal file
11
inst/app_template/tests/server/test-server.R
Normal file
@@ -0,0 +1,11 @@
|
||||
# Use testthat just for expectations
|
||||
library(testthat)
|
||||
|
||||
testServer('../..', {
|
||||
# Set the `size` slider and check the output
|
||||
session$setInputs(size = 6)
|
||||
expect_equal(output$sequence, "1 2 3 4 5 6")
|
||||
|
||||
session$setInputs(size = 12)
|
||||
expect_equal(output$sequence, "1 2 3 4 5 6 7 8 9 10 11 12")
|
||||
})
|
||||
3
inst/app_template/tests/shinytest.R
Normal file
3
inst/app_template/tests/shinytest.R
Normal file
@@ -0,0 +1,3 @@
|
||||
library(shinytest)
|
||||
shinytest::testApp("../")
|
||||
|
||||
7
inst/app_template/tests/shinytest/mytest.R
Normal file
7
inst/app_template/tests/shinytest/mytest.R
Normal file
@@ -0,0 +1,7 @@
|
||||
app <- ShinyDriver$new("../../")
|
||||
app$snapshotInit("mytest")
|
||||
|
||||
app$snapshot()
|
||||
app$setInputs(`mymodule1-button` = "click")
|
||||
app$setInputs(`mymodule1-button` = "click")
|
||||
app$snapshot()
|
||||
6
inst/app_template/tests/testthat.R
Normal file
6
inst/app_template/tests/testthat.R
Normal file
@@ -0,0 +1,6 @@
|
||||
library(testthat)
|
||||
|
||||
# Run in the "current" environment, because shiny::runTests() is going to
|
||||
# provision a new environment that's just for our test. And we'll want access to
|
||||
# the supporting files that were already loaded into that env.
|
||||
testthat::test_dir("./testthat", env = environment())
|
||||
11
inst/app_template/tests/testthat/helper-load.R
Normal file
11
inst/app_template/tests/testthat/helper-load.R
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
# The RStudio IDE offers a "Run Tests" button when it sees testthat tests but it runs
|
||||
# in its own environment/process. Which means that any helpers we've loaded into our
|
||||
# environment won't be visible. So we add this helper not because it's actually needed
|
||||
# in the typical `shiny::runTests` workflow, but to make that IDE button work.
|
||||
# Once the IDE adds proper support for this style, we'll be able to drop these files.
|
||||
#
|
||||
# Note that this may redundantly source the files in your R/ dir depending on your
|
||||
# workflow.
|
||||
library(shiny)
|
||||
shiny::loadSupport("../../", renv = globalenv())
|
||||
5
inst/app_template/tests/testthat/test-sort.R
Normal file
5
inst/app_template/tests/testthat/test-sort.R
Normal file
@@ -0,0 +1,5 @@
|
||||
# Test the lexical_sort function from R/utils.R
|
||||
test_that("Lexical sorting works", {
|
||||
expect_equal(lexical_sort(c(1, 2, 3)), c(1, 2, 3))
|
||||
expect_equal(lexical_sort(c(1, 2, 3, 13, 11, 21)), c(1, 11, 13, 2, 21, 3))
|
||||
})
|
||||
@@ -4,29 +4,34 @@
|
||||
\alias{markdown}
|
||||
\title{Insert inline Markdown}
|
||||
\usage{
|
||||
markdown(mds, extensions = TRUE, ...)
|
||||
markdown(mds, extensions = TRUE, .noWS = NULL, ...)
|
||||
}
|
||||
\arguments{
|
||||
\item{mds}{A character vector of Markdown source to convert to HTML. If the
|
||||
vector has more than one element, resulting HTML is concatenated.}
|
||||
vector has more than one element, a single-element character vector of
|
||||
concatenated HTML is returned.}
|
||||
|
||||
\item{extensions}{Enable Github syntax extensions, defaults to \code{TRUE}.}
|
||||
\item{extensions}{Enable Github syntax extensions; defaults to \code{TRUE}.}
|
||||
|
||||
\item{.noWS}{Character vector used to omit some of the whitespace that would
|
||||
normally be written around generated HTML. Valid options include \code{before},
|
||||
\code{after}, and \code{outside} (equivalent to \code{before} and \code{end}).}
|
||||
|
||||
\item{...}{Additional arguments to pass to \code{\link[commonmark:markdown_html]{commonmark::markdown_html()}}.
|
||||
These arguments are \emph{\link[rlang:dyn-dots]{dynamic}}.}
|
||||
}
|
||||
\value{
|
||||
an \code{html}-classed character vector of rendered HTML
|
||||
a character vector marked as HTML.
|
||||
}
|
||||
\description{
|
||||
This function accepts a character vector of
|
||||
\href{https://en.wikipedia.org/wiki/Markdown}{Markdown}-syntax text and renders
|
||||
it to HTML that may be included in a UI.
|
||||
This function accepts
|
||||
\href{https://en.wikipedia.org/wiki/Markdown}{Markdown}-syntax text and returns
|
||||
HTML that may be included in Shiny UIs.
|
||||
}
|
||||
\details{
|
||||
Prior to interpretation as Markdown, leading whitespace is trimmed from text
|
||||
with \code{\link[glue:trim]{glue::trim()}}. This makes it possible to insert Markdown and for it to
|
||||
be processed correctly even when the call to \code{markdown()} is indented.
|
||||
Leading whitespace is trimmed from Markdown text with \code{\link[glue:trim]{glue::trim()}}.
|
||||
Whitespace trimming ensures Markdown is processed correctly even when the
|
||||
call to \code{markdown()} is indented within surrounding R code.
|
||||
|
||||
By default, \link[commonmark:extensions]{Github extensions} are enabled, but this
|
||||
can be disabled by passing \code{extensions = FALSE}.
|
||||
|
||||
@@ -52,6 +52,6 @@ below to see their documentation.
|
||||
\describe{
|
||||
\item{fastmap}{\code{\link[fastmap]{is.key_missing}}, \code{\link[fastmap]{key_missing}}}
|
||||
|
||||
\item{htmltools}{\code{\link[htmltools]{a}}, \code{\link[htmltools]{br}}, \code{\link[htmltools]{code}}, \code{\link[htmltools]{div}}, \code{\link[htmltools]{em}}, \code{\link[htmltools]{h1}}, \code{\link[htmltools]{h2}}, \code{\link[htmltools]{h3}}, \code{\link[htmltools]{h4}}, \code{\link[htmltools]{h5}}, \code{\link[htmltools]{h6}}, \code{\link[htmltools]{hr}}, \code{\link[htmltools]{HTML}}, \code{\link[htmltools]{htmlTemplate}}, \code{\link[htmltools]{img}}, \code{\link[htmltools]{includeCSS}}, \code{\link[htmltools]{includeHTML}}, \code{\link[htmltools]{includeMarkdown}}, \code{\link[htmltools]{includeScript}}, \code{\link[htmltools]{includeText}}, \code{\link[htmltools]{is.singleton}}, \code{\link[htmltools]{p}}, \code{\link[htmltools]{pre}}, \code{\link[htmltools]{singleton}}, \code{\link[htmltools]{span}}, \code{\link[htmltools]{strong}}, \code{\link[htmltools]{suppressDependencies}}, \code{\link[htmltools]{tag}}, \code{\link[htmltools]{tagAppendAttributes}}, \code{\link[htmltools]{tagAppendChild}}, \code{\link[htmltools]{tagAppendChildren}}, \code{\link[htmltools]{tagGetAttribute}}, \code{\link[htmltools]{tagHasAttribute}}, \code{\link[htmltools]{tagList}}, \code{\link[htmltools]{tags}}, \code{\link[htmltools]{tagSetChildren}}, \code{\link[htmltools]{validateCssUnit}}, \code{\link[htmltools]{withTags}}}
|
||||
\item{htmltools}{\code{\link[htmltools]{HTML}}, \code{\link[htmltools]{a}}, \code{\link[htmltools]{br}}, \code{\link[htmltools]{code}}, \code{\link[htmltools]{div}}, \code{\link[htmltools]{em}}, \code{\link[htmltools]{h1}}, \code{\link[htmltools]{h2}}, \code{\link[htmltools]{h3}}, \code{\link[htmltools]{h4}}, \code{\link[htmltools]{h5}}, \code{\link[htmltools]{h6}}, \code{\link[htmltools]{hr}}, \code{\link[htmltools]{htmlTemplate}}, \code{\link[htmltools]{img}}, \code{\link[htmltools]{includeCSS}}, \code{\link[htmltools]{includeHTML}}, \code{\link[htmltools]{includeMarkdown}}, \code{\link[htmltools]{includeScript}}, \code{\link[htmltools]{includeText}}, \code{\link[htmltools]{is.singleton}}, \code{\link[htmltools]{p}}, \code{\link[htmltools]{pre}}, \code{\link[htmltools]{singleton}}, \code{\link[htmltools]{span}}, \code{\link[htmltools]{strong}}, \code{\link[htmltools]{suppressDependencies}}, \code{\link[htmltools]{tag}}, \code{\link[htmltools]{tagAppendAttributes}}, \code{\link[htmltools]{tagAppendChild}}, \code{\link[htmltools]{tagAppendChildren}}, \code{\link[htmltools]{tagGetAttribute}}, \code{\link[htmltools]{tagHasAttribute}}, \code{\link[htmltools]{tagList}}, \code{\link[htmltools]{tagSetChildren}}, \code{\link[htmltools]{tags}}, \code{\link[htmltools]{validateCssUnit}}, \code{\link[htmltools]{withTags}}}
|
||||
}}
|
||||
|
||||
|
||||
74
man/shinyAppTemplate.Rd
Normal file
74
man/shinyAppTemplate.Rd
Normal file
@@ -0,0 +1,74 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/app_template.R
|
||||
\name{shinyAppTemplate}
|
||||
\alias{shinyAppTemplate}
|
||||
\title{Generate a Shiny application from a template}
|
||||
\usage{
|
||||
shinyAppTemplate(path = NULL, examples = "default")
|
||||
}
|
||||
\arguments{
|
||||
\item{path}{Path to create new shiny application template.}
|
||||
|
||||
\item{examples}{Either one of "default", "ask", "all", or any combination of
|
||||
"app", "rdir", "module", "shinytest", "testthat", and "server". In an
|
||||
interactive session, "default" falls back to "ask"; in a non-interactive
|
||||
session, "default" falls back to "all". With "ask", this function will
|
||||
prompt the user to select which template items will be added to the new app
|
||||
directory. With "all", all template items will be added to the app
|
||||
directory.}
|
||||
}
|
||||
\description{
|
||||
This function populates a directory with files for a Shiny application.
|
||||
}
|
||||
\details{
|
||||
In an interactive R session, this function will, by default, prompt the user
|
||||
which components to add to the application.
|
||||
|
||||
The full example application includes the following files and directories:\preformatted{appdir/
|
||||
|- app.R
|
||||
|- R
|
||||
| |- my-module.R
|
||||
| |-- sort.R
|
||||
`-- tests
|
||||
|- server.R
|
||||
|- server
|
||||
| |- test-mymodule.R
|
||||
| `- test-server.R
|
||||
|- shinytest.R
|
||||
|- shinytest
|
||||
| `- mytest.R
|
||||
|- testthat.R
|
||||
`-- testthat
|
||||
|- helper-load.R
|
||||
`- test-sort.R
|
||||
}
|
||||
|
||||
Some notes about these files:
|
||||
\itemize{
|
||||
\item \code{app.R} is the main application file.
|
||||
\item All files in the \verb{R/} subdirectory are automatically sourced when the
|
||||
application is run.
|
||||
\item \code{R/sort.R} and \code{R/my-module.R} are automatically sourced when
|
||||
the application is run. The first contains a function \code{lexical_sort()},
|
||||
and the second contains code for a \href{moduleServer()}{Shiny module} which
|
||||
is used in the application.
|
||||
\item \verb{tests/} contains various tests for the application. You may
|
||||
choose to use or remove any of them. They can be executed by the
|
||||
\code{\link[=runTests]{runTests()}} function.
|
||||
\item \code{tests/server.R} is a test runner for test files in
|
||||
\verb{tests/server/}.
|
||||
\item \code{tests/server/test-mymodule.R} is a test for the module.
|
||||
\item \code{tests/shinytest.R} is a test runner for test files in the
|
||||
\verb{tests/shinytest/} directory.
|
||||
\item \code{tests/shinytest/mytest.R} is a test that uses the
|
||||
\href{https://rstudio.github.io/shinytest/}{shinytest} package to do
|
||||
snapshot-based testing.
|
||||
\item \code{tests/testthat.R} is a test runner for test files in the
|
||||
\verb{tests/testthat/} directory.
|
||||
\item \code{tests/testthat/helper-load.R} is a helper script that is automatically
|
||||
loaded before running \code{test-mymodule.}R. (This is performed by the testthat
|
||||
package.)
|
||||
\item \code{tests/testthat/test-sort.R} is a set of tests that use the
|
||||
\href{https://testthat.r-lib.org/}{testthat} package for testing.
|
||||
}
|
||||
}
|
||||
@@ -168,6 +168,7 @@ reference:
|
||||
- title: Utility functions
|
||||
desc: Miscellaneous utilities that may be useful to advanced users or when extending Shiny.
|
||||
contents:
|
||||
- shinyAppTemplate
|
||||
- req
|
||||
- validate
|
||||
- session
|
||||
|
||||
Reference in New Issue
Block a user