diff --git a/R/ambhtmx.R b/R/ambhtmx.R index 25b71f0..dda7bf2 100644 --- a/R/ambhtmx.R +++ b/R/ambhtmx.R @@ -546,32 +546,6 @@ process_loggedin_middleware <- \( } -#' Process error post requests -#' -#' @param req request object -#' @param res response object -#' @param errors the error message character vector -#' @param cookie_errors if you need to customize the name of the errors cookie -#' @param error_url if you need to customize the url of the error to redirect to. -#' @returns the error process response -#' @export -process_error_post <- \( - req, - res, - errors = NULL, - cookie_errors = "errors", - error_url = NULL - ) { - if (is_debug_enabled()) print("process_error_post") - error_message <- paste0(errors, ". ", collapse = "") - res$cookie( - name = cookie_errors, - value = error_message - ) - res$header("HX-Redirect", error_url) - return(res$redirect(error_url, status = 302L)) -} - #' Process error get requests #' #' @param req request object diff --git a/R/extra-tags.R b/R/extra-tags.R index f9c8d63..0d488da 100644 --- a/R/extra-tags.R +++ b/R/extra-tags.R @@ -41,4 +41,24 @@ input <- htmltools::tags$input #' @rdname builder #' @export -label <- htmltools::tags$label \ No newline at end of file +label <- htmltools::tags$label + +#' @rdname builder +#' @export +nav <- htmltools::tags$nav + +#' @rdname builder +#' @export +li <- htmltools::tags$li + +#' @rdname builder +#' @export +ul <- htmltools::tags$ul + +#' @rdname builder +#' @export +ol <- htmltools::tags$ol + +#' @rdname builder +#' @export +form <- htmltools::tags$form \ No newline at end of file diff --git a/inst/examples/01-counter.R b/inst/examples/01-counter.R index 5925bc0..324cd0e 100644 --- a/inst/examples/01-counter.R +++ b/inst/examples/01-counter.R @@ -1,5 +1,5 @@ library(ambhtmx) -# devtools::load_all() +# devtools::load_all(); remotes::install_github("jrosell/ambhtmx", force = TRUE) #' Starting the app counter <- 0 diff --git a/inst/examples/02-ggplot2.R b/inst/examples/02-ggplot2.R index 138c94b..836929a 100644 --- a/inst/examples/02-ggplot2.R +++ b/inst/examples/02-ggplot2.R @@ -1,10 +1,5 @@ -tryCatch({ - library(ambhtmx) - }, - error = \(e) print(e) -) - -# devtools::load_all() +library(ambhtmx) +library(ggplot2) #' Starting the app counter <- 0 @@ -35,12 +30,16 @@ app$get("/", \(req, res){ #' Post call to return the plot app$post("/increment", \(req, res){ - counter <<- counter + 1 - rexp_data <<- c(rexp_data, rexp(1)) - rexp_df <- tibble(x = 1:length(rexp_data), y = rexp_data) - p <- ggplot(rexp_df, aes(x, y)) + geom_line() - png(p_file <- tempfile(fileext = ".png")); print(p); dev.off() - p_txt <- b64::encode_file(p_file) + tryCatch({ + counter <<- counter + 1 + rexp_data <<- c(rexp_data, rexp(1)) + rexp_df <- tibble(x = 1:length(rexp_data), y = rexp_data) + p <- ggplot(rexp_df, aes(x, y)) + geom_line() + png(p_file <- tempfile(fileext = ".png")); print(p); dev.off() + p_txt <- b64::encode_file(p_file) + }, + error = \(e) print(e) + ) res$send(render_tags( tags$p(glue("Counter is set to {counter}")), tags$img(src = glue("data:image/png;base64,{p_txt}")) diff --git a/inst/examples/03-slider.R b/inst/examples/03-slider.R index 1f8f221..5461149 100644 --- a/inst/examples/03-slider.R +++ b/inst/examples/03-slider.R @@ -1,10 +1,5 @@ library(ambhtmx) -# devtools::load_all() -library(ambiorix) -library(tidyverse) -library(zeallot) -library(glue) -library(htmltools) +library(ggplot2) #' Starting the app counter <- 1 diff --git a/inst/examples/04-todo.R b/inst/examples/04-todo.R index 6e6bd4b..0f977be 100644 --- a/inst/examples/04-todo.R +++ b/inst/examples/04-todo.R @@ -1,11 +1,5 @@ library(ambhtmx) # devtools::load_all() -library(ambiorix) -library(scilis) -library(tidyverse) -library(zeallot) -library(glue) -library(htmltools) #' Starting the app counter <- 0 diff --git a/inst/examples/05-live.R b/inst/examples/05-live.R index ece4905..dbfe4b9 100644 --- a/inst/examples/05-live.R +++ b/inst/examples/05-live.R @@ -1,20 +1,21 @@ +# TODO: Use websockets to refresh the HTML page when R server is restarted. +# TODO: Detect if the script is run from nodemon or not. + library(ambhtmx) # devtools::load_all() -library(ambiorix) -library(tidyverse) -library(zeallot) -library(glue) -library(htmltools) + live_path <- tryCatch( {this.path::this.path()}, error = function(e) return("") ) + #' Starting the app counter <- 0 c(app, context, operations) %<-% ambhtmx_app(live = live_path) + #' Main page of the app app$get("/", \(req, res){ html <- render_page( @@ -32,11 +33,13 @@ app$get("/", \(req, res){ res$send(html) }) + #' Post call to return the value of the global counter variable app$post("/increment", \(req, res){ counter <<- counter + 1 res$send(glue("Counter is set to {counter}")) }) + #' Start the app with all the previous defined routes app$start(open = FALSE) diff --git a/inst/examples/06-basic-auth.R b/inst/examples/06-basic-auth.R index 6bf2b54..9ba6524 100644 --- a/inst/examples/06-basic-auth.R +++ b/inst/examples/06-basic-auth.R @@ -1,10 +1,6 @@ library(ambhtmx) # devtools::load_all() -library(ambiorix) -library(tidyverse) -library(zeallot) -library(glue) -library(htmltools) +library(ggplot2) page_title <- "ambhtmx basic authentication example" @@ -14,9 +10,7 @@ live_path <- tryCatch( ) #' Starting the app -c(app, context, operations) %<-% ambhtmx_app( - live = live_path -) +c(app, context, operations) %<-% ambhtmx_app() #' Authentication feature with secret cookies and .Renviron variables app$get("/login", \(req, res) { @@ -85,5 +79,5 @@ app$post("/increment", \(req, res){ }) #' Start the app with all the previous defined routes -app$start(open = FALSE) +app$start() diff --git a/inst/examples/07-crud.R b/inst/examples/07-crud.R index 1c0c3f0..2f6d47f 100644 --- a/inst/examples/07-crud.R +++ b/inst/examples/07-crud.R @@ -1,20 +1,8 @@ library(ambhtmx) # devtools::load_all() -library(ambiorix) -library(tidyverse) -library(zeallot) -library(glue) -library(htmltools) -library(signaculum) page_title <- "Password protected CRUD (Create, Read, Update, and Delete) example with ambhtmx" -live_path <- tryCatch( - {this.path::this.path()}, - error = function(e) return("") -) -print(live_path) - render_index <- \() { main <- NULL tryCatch({ @@ -57,6 +45,33 @@ render_index <- \() { return(main) } +render_new <- \(req, res) { + errors <- process_error_get(req, res) + render_tags(tagList( + h2("New item"), + div(label("Name", p(input(name = "name")))), + div(label("Content", p(textarea(name = "content")))), + a( + "Go back", + href = "/", + style = "margin-right:20px", + `hx-confirm` = "Are you sure you want to go back?", + `hx-get` = "/items", + `hx-target` = "#page", + `hx-swap` = "outerHTML", + `hx-encoding` = "multipart/form-data" + ), + button( + "Create", + style = "margin-top:20px", + `hx-post` = "/items", + `hx-target` = "#page", + `hx-swap` = "outerHTML", + `hx-include` = "[name='name'], [name='content']", + ), + errors + )) +} render_row <- \(item) { tags$div( @@ -76,7 +91,6 @@ c(app, context, items) %<-% name = character(1), content = character(1) ), - live = live_path, render_index = render_index, render_row = render_row ) @@ -86,22 +100,13 @@ app$get("/login", \(req, res) { process_login_get(req, res) }) app$post("/login", \(req, res) { - process_login_post( - req, - res, - user = Sys.getenv("AMBHTMX_USER"), - password = Sys.getenv("AMBHTMX_PASSWORD") - ) + process_login_post(req, res) }) app$get("/logout", \(req, res) { process_logout_get(req, res) }) app$use(\(req, res){ - process_loggedin_middleware( - req, - res, - user = Sys.getenv("AMBHTMX_USER") - ) + process_loggedin_middleware(req, res) }) #' Some CRUD operations examples @@ -169,31 +174,11 @@ app$get("/items/new", \(req, res){ if (!req$loggedin) { return(res$redirect("/login", status = 302L)) } - errors <- process_error_get(req, res) - html <- render_tags(tagList( - h2("New item"), - div(label("Name", p(input(name = "name")))), - div(label("Content", p(textarea(name = "content")))), - a( - "Go back", - href = "/", - style = "margin-right:20px", - `hx-confirm` = "Are you sure you want to go back?", - `hx-get` = "/items", - `hx-target` = "#page", - `hx-swap` = "outerHTML", - `hx-encoding` = "multipart/form-data" - ), - button( - "Create", - style = "margin-top:20px", - `hx-post` = "/items", - `hx-target` = "#page", - `hx-swap` = "outerHTML", - `hx-include` = "[name='name'], [name='content']", - ), - errors - )) + tryCatch({ + html <- render_new(req, res) + }, + error = \(e) print(e) + ) res$send(html) }) @@ -271,6 +256,7 @@ app$get("/items/:id/edit", \(req, res){ res$send(html) }) + #' Create a new item app$post("/items", \(req, res){ if (!req$loggedin) { @@ -278,12 +264,15 @@ app$post("/items", \(req, res){ } params <- parse_multipart(req) if (is.null(params[["name"]])) { - return(process_error_post( - req, - res, - errors = "Name is required", - error_url = "/items/new" - )) + error_message <- "Name is required." + res$cookie( + name = "errors", + value = error_message + ) + res$header("HX-Retarget", "#main") + res$header("HX-Reswap", "innerHTML") + print("Retarget amb error") + return(res$send(render_new(req, res))) } if (is.null(params[["content"]])) { params[["content"]] = ""