#' Deploy a website
#'
#' Deploy an R Markdown or quarto website to a server.
#'
#' @inheritParams deployApp
#' @param siteDir Directory containing website. Defaults to current directory.
#' @param siteName Name for the site (names must be unique within
#' an account). Defaults to the base name of the specified `siteDir`
#' or to the name provided by a custom site generation function.
#' @param siteTitle Title for the site. For quarto sites only, if not
#' supplied uses the title recorded in `_quarto.yml`.
#' @param render Rendering behavior for site:
#'
#' * `"none"` uploads a static version of the current contents of
#' the site directory.
#' * `"local"` renders the site locally then uploads it.
#' * `"server"` uploads the source of the site to render on the server.
#'
#' Note that for `"none"` and `"local"` source files (e.g. `.R`, `.Rmd` and
#' `.md`) will not be uploaded to the server.
#' @param recordDir The default, `NULL`, uses `siteDir`.
#' @param ... Additional arguments to [deployApp()]. Do not supply `appDir`
#' or `appFiles`; these parameters are automatically generated by
#' `deploySite()`.
#' @family Deployment functions
#' @export
deploySite <- function(siteDir = getwd(),
siteName = NULL,
siteTitle = NULL,
account = NULL,
server = NULL,
render = c("none", "local", "server"),
launch.browser = getOption("rsconnect.launch.browser", interactive()),
logLevel = c("normal", "quiet", "verbose"),
lint = FALSE,
metadata = list(),
python = NULL,
recordDir = NULL,
...) {
check_directory(siteDir)
isQuarto <- file.exists(file.path(siteDir, "_quarto.yml")) ||
file.exists(file.path(siteDir, "_quarto.yaml"))
quiet <- identical(match.arg(logLevel), "quiet")
if (isQuarto) {
site <- quartoSite(siteDir, quiet = quiet)
} else {
site <- rmarkdownSite(siteDir, quiet = quiet)
}
# render locally if requested
render <- arg_match(render)
if (render == "local") {
site$render()
}
# determine appDir based on whether we are rendering on the server
if (render == "server") {
appDir <- siteDir
} else {
appDir <- site$output_dir
}
# Need to override recordDir to always record in the source directory
if (is.null(recordDir)) {
# We're deploying an entire directory, so we don't really need to set
# a path here, but we don't want to break existing deployments so
# we leave the existing behaviour for RMarkdown
if (!isQuarto) {
name <- if (file.exists("index.Rmd")) "index.Rmd" else "index.md"
recordDir <- file.path(siteDir, name)
} else {
recordDir <- siteDir
}
}
deployApp(
appName = siteName %||% site$name,
appTitle = siteTitle %||% site$title,
appDir = appDir,
recordDir = recordDir,
contentCategory = "site",
account = account,
server = server,
launch.browser = launch.browser,
logLevel = logLevel,
lint = lint,
metadata = metadata,
python = python,
...
)
}
quartoSite <- function(path, quiet = FALSE, error_call = caller_env()) {
check_installed(
"quarto",
reason = "to deploy quarto sites",
call = error_call
)
config <- quarto::quarto_inspect(path)$config
list(
render = function() quarto::quarto_render(path, quiet = quiet, as_job = FALSE),
name = basename(normalizePath(path)),
title = config$website$title %||% config$book$title %||% config$title,
# non-site projects build in current directory
output_dir = outputDir(path, config$project$`output-dir` %||% ".")
)
}
rmarkdownSite <- function(siteDir, quiet = FALSE, error_call = caller_env()) {
check_installed(
"rmarkdown",
version = "0.9.5.3",
reason = "to deploy RMarkdown sites",
call = error_call
)
# discover the site generator
siteGenerator <- rmarkdown::site_generator(siteDir)
if (is.null(siteGenerator)) {
cli::cli_abort(
"No `_site.yml` found in {.path {siteDir}.}",
call = error_call
)
}
list(
render = function() {
siteGenerator$render(
input_file = NULL,
output_format = NULL,
envir = new.env(),
quiet = quiet,
encoding = getOption("encoding")
)
},
name = siteGenerator$name,
title = NULL,
output_dir = outputDir(siteDir, siteGenerator$output_dir)
)
}
outputDir <- function(wd, path) {
old <- setwd(wd)
defer(setwd(old))
normalizePath(dirCreate(path), mustWork = FALSE)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.