Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

htmltools rendering #90

Open
JohnCoene opened this issue Jan 15, 2025 · 3 comments
Open

htmltools rendering #90

JohnCoene opened this issue Jan 15, 2025 · 3 comments
Assignees
Labels
feature New feature

Comments

@JohnCoene
Copy link
Collaborator

Maybe we can generalise the code below to make it easier to render in ambiorix?

library(ambiorix)
library(htmltools)
library(calcite)

# core app
app <- Ambiorix$new()

app$get("/", \(req, res){
  shell <- calcite_shell(
    calcite_navigation(
      slot = "header",
      calcite_navigation_logo(
        slot = "logo",
        heading = "Snow Plow Map",
        description = "City of AcmeCo"
      ),
      calcite_menu(
        slot = "content-end",
        calcite_menu_item(text = "Drivers", `icon-start` = "license", `text-enabled` = TRUE),
        calcite_menu_item(text = "Routes", `icon-start` = "road-sign", `text-enabled` = TRUE),
        calcite_menu_item(text = "Forecast", `icon-start` = "snow", `text-enabled` = TRUE)
      ),
      calcite_navigation(
        slot = "navigation-secondary",
        calcite_menu(
          slot = "content-start",
          calcite_menu_item(breadcrumb = TRUE, text = "All Routes", `icon-start` = "book", `text-enabled` = TRUE),
          calcite_menu_item(breadcrumb = TRUE, text = "South Hills", `icon-start` = "apps", `text-enabled` = TRUE, active = TRUE)
        )
      ),
      calcite_navigation_user(slot = "user", `full-name` = "Wendell Berry", username = "w_berry")
    )
  )

  tgs <- htmltools::renderTags(shell)
  dps <- htmltools::renderDependencies(tgs$dependencies)

  page <- tags$html(
    tags$head(dps),
    tags$body(tgs)
  )

  res$send(page)
})

app$start()
@kennedymwavu
Copy link
Contributor

i would argue that one can easily use {calcite} components in ambiorix by simply including calcite assets in the head of the html document explicitly. this would be my recommended way:

library(ambiorix)
library(htmltools)
library(calcite)

#' Generic html page
#'
#' @param head [htmltools::tagList()] Items
#' included in the head of the html document.
#' @param body [htmltools::tagList()] Items
#' included in the body of the html document.
#' @return [htmltools::tags]
#' @export
page <- \(head = NULL, body = NULL) {
  tags$html(
    tags$head(
      tags$script(
        type = "module",
        src = "https://js.arcgis.com/calcite-components/2.13.2/calcite.esm.js"
      ),
      tags$link(
        type = "text/css",
        rel = "stylesheet",
        href = "https://js.arcgis.com/calcite-components/2.13.2/calcite.css"
      ),
      head
    ),
    tags$body(body)
  )
}

#' Home page
#'
#' @return [htmltools::tags]
#' @export
home_page <- \() {
  shell <- calcite_shell(
    calcite_navigation(
      slot = "header",
      calcite_navigation_logo(
        slot = "logo",
        heading = "Snow Plow Map",
        description = "City of AcmeCo"
      ),
      calcite_menu(
        slot = "content-end",
        calcite_menu_item(text = "Drivers", `icon-start` = "license", `text-enabled` = TRUE),
        calcite_menu_item(text = "Routes", `icon-start` = "road-sign", `text-enabled` = TRUE),
        calcite_menu_item(text = "Forecast", `icon-start` = "snow", `text-enabled` = TRUE)
      ),
      calcite_navigation(
        slot = "navigation-secondary",
        calcite_menu(
          slot = "content-start",
          calcite_menu_item(breadcrumb = TRUE, text = "All Routes", `icon-start` = "book", `text-enabled` = TRUE),
          calcite_menu_item(breadcrumb = TRUE, text = "South Hills", `icon-start` = "apps", `text-enabled` = TRUE, active = TRUE)
        )
      ),
      calcite_navigation_user(slot = "user", `full-name` = "Wendell Berry", username = "w_berry")
    )
  )

  page(body = shell)
}

# core app
app <- Ambiorix$new()

app$get("/", \(req, res){
  res$send(home_page())
})

app$start()

but i also totally understand that most R users learnt shiny first, and are accustomed to its way of doing things, but wouldn't imposing such come at a significant cost for ambiorix considering it takes a fundamentally different path?

this is similar to the issue we were discussing a while ago about whether to ship ambiorix with a css framework (bootstrap, tailwind, bulma, etc.), and we agreed that it's much better to allow the user to pick whichever css/js framework they feel is right for them (a.k.a unopinionated😅)

it’s both a blessing and a burden: the freedom to build exactly what they want, but also the responsibility to build and customize their components from scratch.

i'm, of course, not against adding support for htmlwidgets or features that make ambiorix easier to use... my main concern is whether those changes will actually make things easier, better or more effiicent— or if they might complicate the framework unnecessarily.

@JohnCoene
Copy link
Collaborator Author

I disagree here.

I agree that {ambiorix} should not be opinionated.

But this is not about opinion it's just about support. If we say the package supports {htmltools} it should do so as much as possible.
We should be able to use {calcite} in {ambiorix}, {calcite} doesn't do anything strange or remotely esoteric, the components include the dependency so send should render the tags correctly with the dependencies.

How about we do something like this

render_htmltools <- function(x) {

This would allow using {calcite} (an any other such library) as intended.

library(ambiorix)
library(htmltools)
library(calcite)

page <- function(...) {
  tags$html(
    tags$head(
      tags$title("The page title!")
    ),
    tags$body(...)
  )
}

# core app
app <- Ambiorix$new()

app$get("/", \(req, res){
  shell <- calcite_shell(
    calcite_navigation(
      slot = "header",
      calcite_navigation_logo(
        slot = "logo",
        heading = "Snow Plow Map",
        description = "City of AcmeCo"
      ),
      calcite_menu(
        slot = "content-end",
        calcite_menu_item(text = "Drivers", `icon-start` = "license", `text-enabled` = TRUE),
        calcite_menu_item(text = "Routes", `icon-start` = "road-sign", `text-enabled` = TRUE),
        calcite_menu_item(text = "Forecast", `icon-start` = "snow", `text-enabled` = TRUE)
      ),
      calcite_navigation(
        slot = "navigation-secondary",
        calcite_menu(
          slot = "content-start",
          calcite_menu_item(breadcrumb = TRUE, text = "All Routes", `icon-start` = "book", `text-enabled` = TRUE),
          calcite_menu_item(breadcrumb = TRUE, text = "South Hills", `icon-start` = "apps", `text-enabled` = TRUE, active = TRUE)
        )
      ),
      calcite_navigation_user(slot = "user", `full-name` = "Wendell Berry", username = "w_berry")
    )
  )

  res$send(page(shell))
})

The one thing that still would not work are the "inputs" which are designed around Shiny's API.

What do you think?

@kennedymwavu
Copy link
Contributor

okay, okay, i agree now. this is the point i was missing:

But this is not about opinion it's just about support. If we say the package supports {htmltools} it should do so as much as possible.

yes, if we say {ambiorix} supports {htmltools} then it should indeed do almost all the heavy-lifting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature
Projects
None yet
Development

No branches or pull requests

2 participants