R/html-build.R

Defines functions html_script assert_valid_names html_mustache html_template html_tags

Documented in html_mustache html_script html_tags html_template

#' @title HTML Building Utilities
#'
#' @description
#' Set of functions for helping with building HTML content.
#'
#' @param ... tag or template components
#' @param env (env) calling environment
#'
#' @name html_build
NULL

#' @describeIn html_build Build HTML content using tags
#' @export
html_tags <- function(..., env = parent.frame()) {

  code <- enexprs(...)
  exec(tagList, !!!map(code, eval_tidy, data = tags, env = env))

}

#' @describeIn html_build Render an HTML template using
#' [`htmltools::htmlTemplate`]; better support for HTML dependencies and
#' also allows you to put `<!-- HEAD_CONTENT -->` to place the dependencies
#' @param file (pth) path to a file containing the template
#' @param text (str) as an alternative, supply a character vector
#' @param deps (lst) list of additional HTML dependencies
#' @export
html_template <- function(file,
                          ...,
                          text = NULL,
                          deps = NULL,
                          full = "auto") {

  assert_valid_names(...)
  assert_list(deps, "html_dependency", null.ok = TRUE)
  htmlTemplate(
    filename  = file,
    ...,
    text_     = text,
    document_ = full
  ) %>%
    attachDependencies(deps)

}

#' @describeIn html_build Render an HTML template using
#' [`whisker::whisker.render`]; has good support for partials and other
#' iterative elements because it is based on `{{mustache}}`.
#' @param part (lst) partial templates for the whisker renderer
#' @param full (flg) whether or not to render a full document
#' @export
html_mustache <- function(file,
                          ...,
                          part = NULL,
                          text = NULL,
                          deps = NULL) {
  data <- assert_valid_names(...)
  deps <- assert_list(deps, "html_dependency", null.ok = TRUE)
  tags <- renderTags(data)
  whisker.render(
    template = text %||% read_file(file),
    data     = data,
    partials = assert_list(part, null.ok = TRUE)
  ) %>%
    HTML() %>%
    tagList() %>%
    attachDependencies(c(deps, tags$dependencies))
}

assert_valid_names <- function(...) {
  if (any(as.character(enexprs(...)) %in% names(tags))) {
    stop("Don't use these symbols in templates: ",
         paste0(names(tags), collapse = ", "))
  }
  invisible(list(...))
}


#' @describeIn html_build Build a script using the whisker syntax
#' @param ...  (dta) data elements for the template
#' @param type (str) type attribute of the script tag
#' @param singleton (flg) should this script only appear once?
#' @param in_head   (flg) should this script be rendered in the head?
#' @export
html_script <- function(file, ...,
                        text = NULL,
                        type = NULL,
                        in_head = FALSE,
                        singleton = FALSE) {
  tags$script(
    type = type,
    HTML(whisker.render(
      template = text %||% read_file(file),
      data = list(...)
    ))
  ) %>%
    when(in_head, tags$head(.)) %>%
    when(singleton, singleton(.))

}

#' @describeIn html_build create a CSS/JS/other dependency
#' @param
#' name,version,src,meta,script,stylesheet,head,attachment,package,all_files
#' (args) passed to [`htmltools::htmlDependency`]
#' @export
html_dependency <- htmltools::htmlDependency
tjpalanca/webtools documentation built on Dec. 23, 2021, 11 a.m.