From 04081ec2d3393cbcaa89e8cc68f9534a177bad1e Mon Sep 17 00:00:00 2001 From: Joe Cheng Date: Wed, 18 Jul 2012 15:26:13 -0700 Subject: [PATCH] Integrate UI builder into Shiny Replace example #1 HTML with builder --- NAMESPACE | 18 ++++ R/ui.R | 144 ++++++++++++++++++----------- examples/01_allcaps/app.R | 15 ++- examples/01_allcaps/www/index.html | 21 ----- man/startApp.Rd | 4 +- shiny.Rproj | 2 +- 6 files changed, 125 insertions(+), 79 deletions(-) delete mode 100644 examples/01_allcaps/www/index.html diff --git a/NAMESPACE b/NAMESPACE index a5943fa02..49bf4274d 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,10 +1,28 @@ +export(br) +export(defineUI) +export(div) +export(h1) +export(h2) +export(head) +export(header) +export(img) +export(input) +export(inputs) export(invalidateLater) +export(outputs) +export(p) +export(page) export(reactive) export(reactivePlot) export(reactiveTable) export(reactiveText) export(reactiveTimer) export(runApp) +export(script) +export(shinyPlot) +export(shinyText) +export(style) +export(tag) S3method(reactive,default) S3method(reactive,"function") S3method("$",reactvaluesreader) diff --git a/R/ui.R b/R/ui.R index fdaf45f79..d15d811d3 100644 --- a/R/ui.R +++ b/R/ui.R @@ -1,10 +1,10 @@ - -tag <- function(name, ...) { +#' @export +tag <- function(`_tag_name`, ...) { # create basic tag data structure tag <- list() class(tag) <- "shiny.tag" - tag$name <- name + tag$name <- `_tag_name` tag$attribs <- list() tag$children <- list() @@ -14,33 +14,35 @@ tag <- function(name, ...) { if (is.null(varArgsNames)) varArgsNames <- character(length=length(varArgs)) - for (i in 1:length(varArgsNames)) { - # save name and value - name <- varArgsNames[[i]] - value <- varArgs[[i]] - - # process attribs - if (nzchar(name)) - tag$attribs[[name]] <- value - - # process child tags - else if (inherits(value, "shiny.tag")) { - tag$children[[length(tag$children)+1]] <- value - } - - # process lists of children - else if (is.list(value)) { - for(child in value) { - if (inherits(child, "shiny.tag")) - tag$children[[length(tag$children)+1]] <- child - else - tag$children[[length(tag$children)+1]] <- as.character(child) + if (length(varArgsNames) > 0) { + for (i in 1:length(varArgsNames)) { + # save name and value + name <- varArgsNames[[i]] + value <- varArgs[[i]] + + # process attribs + if (nzchar(name)) + tag$attribs[[name]] <- value + + # process child tags + else if (inherits(value, "shiny.tag")) { + tag$children[[length(tag$children)+1]] <- value + } + + # process lists of children + else if (is.list(value)) { + for(child in value) { + if (inherits(child, "shiny.tag")) + tag$children[[length(tag$children)+1]] <- child + else + tag$children[[length(tag$children)+1]] <- as.character(child) + } + } + + # everything else treated as text + else { + tag$children[[length(tag$children)+1]] <- as.character(value) } - } - - # everything else treated as text - else { - tag$children[[length(tag$children)+1]] <- as.character(value) } } @@ -48,38 +50,56 @@ tag <- function(name, ...) { return (tag) } +#' @export h1 <- function(...) { tag("h1", ...) } +#' @export h2 <- function(...) { tag("h2", ...) } +#' @export p <- function(...) { tag("p", ...) } +#' @export div <- function(...) { tag("div", ...) } +#' @export img <- function(...) { tag("img", ...) } +#' @export head <- function(...) { tag("head", ...) } +#' @export script <- function(...) { tag("script", ...) } +#' @export style <- function(...) { tag("style", ...) } +#' @export +input <- function(...) { + tag("input", ...) +} + +#' @export +br <- function(...) { + tag("br", ...) +} + htmlEscape <- local({ .htmlSpecials <- list( `&` = '&', @@ -119,24 +139,34 @@ htmlEscape <- local({ } }) +#' @export shinyPlot <- function(outputId) { list(head(script(src="foobar.js"), style(src="foobar.css")), - img(id = outputId, class ="live-plot")) + div(id = outputId, class ="live-plot")) } +#' @export +shinyText <- function(outputId) { + div(id = outputId, class = "live-text") +} + +#' @export header <- function(...) { div(class="shiny-header", ...) } +#' @export inputs <- function(...) { div(class="shiny-inputs", ...) } +#' @export outputs <- function(...) { div(class="shiny-outputs", ...) } +#' @export defineUI <- function(...) { div(class="shiny-ui", ...) } @@ -243,32 +273,36 @@ renderPage <- function(ui, connection) { con = connection) } +#' @export +page <- function(ui, path='/') { + function(ws, header) { + if (header$RESOURCE != path) + return(NULL) + + textConn <- textConnection(NULL, "w") + on.exit(close(textConn)) + + renderPage(ui, textConn) + html <- paste(textConnectionValue(textConn), collapse='\n') + return(http_response(ws, 200, content=html)) + } +} -ui <- defineUI( - header( - h1("My first application"), - p("This is a really exciting application") - ), - inputs( - p("Here are the inputs") - ), - outputs( - p("Check out my shiny plot:"), - shinyPlot("plot1"), - p("Check out my other shiny plot:"), - shinyPlot("plot2") - ) -) +# ui <- defineUI( +# header( +# h1("My first application"), +# p("This is a really exciting application") +# ), +# inputs( +# p("Here are the inputs") +# ), +# outputs( +# p("Check out my shiny plot:"), +# shinyPlot("plot1"), +# p("Check out my other shiny plot:"), +# shinyPlot("plot2") +# ) +# ) #renderPage(ui, stdout()) - - - - - - - - - - diff --git a/examples/01_allcaps/app.R b/examples/01_allcaps/app.R index 4a0bf1523..bb4d5e912 100644 --- a/examples/01_allcaps/app.R +++ b/examples/01_allcaps/app.R @@ -1,9 +1,22 @@ library(shiny) + +ui <- defineUI( + h1("Example 1: All Caps"), + p( + "Input:", br(), + input(name='val', type='text', value='Hello World!') + ), + p( + "You said:", br(), + shinyText("valUpper") + ) +) + app <- function(input, output) { output$valUpper <- reactive(function() { toupper(input$val) }) } -runApp(client='./www', server=app) \ No newline at end of file +runApp(client=page(ui), server=app) diff --git a/examples/01_allcaps/www/index.html b/examples/01_allcaps/www/index.html deleted file mode 100644 index ecde6a04f..000000000 --- a/examples/01_allcaps/www/index.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - -

Example 1: All Caps

- -

- Input:
- -

- -

- You said:
-

-

- - - diff --git a/man/startApp.Rd b/man/startApp.Rd index 6e5faa219..f49c6a576 100644 --- a/man/startApp.Rd +++ b/man/startApp.Rd @@ -9,7 +9,9 @@ \arguments{ \item{client}{Path to the root of the application-specific www files (which should include - index.html).} + index.html); or, a function that knows how to serve up + www files (TODO: document); or, a list of one or more + paths and/or functions.} \item{server}{If a character string, a path to the R file that contains the server application logic. If a diff --git a/shiny.Rproj b/shiny.Rproj index 39bc2eff3..14e9a6a09 100644 --- a/shiny.Rproj +++ b/shiny.Rproj @@ -14,4 +14,4 @@ LaTeX: pdfLaTeX RootDocument: BuildType: Package -PackageRoxygenize: rd +PackageRoxygenize: rd,namespace