GithubHelp home page GithubHelp logo

brochure's Introduction

Hi there ๐Ÿ‘‹

Welcome to my GitHub account!

I'm Colin, and (probably like a lot of people here), I love writing code.

My languages of choice are R, JavaScript and Docker. I love building infrastructures and backends.

Here are some of the things I've been working on lately:

I also have a bunch of Docker image I maintain on my Docker hub.

I love to speak around the world, and most of my talks are available on my speakerdeck, and if you're looking for the video I try to keep the list on my website up to date.

You can learn more about me on my website colinfay.me where I blog on a random basis and on Twitter at @_ColinFay where I tweet quite frequently.

I probably forgot a lot of things here, so feel free to explore my profiles and website, and to contact me if you need my help!

brochure's People

Contributors

abelborges avatar colinfay avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

brochure's Issues

Natively set cookies

To work seamlessly, we should be able to set cookies natively through {brochure}.

Deployment Help for Brochure application

I have built up a multi-page application using Brochure.
I tried to deploy it using Docker & ShinyProxy deployment model.
The app gets deployed and the first page alone loads.
All other pages are missing when deployed with ShinyProxy (404).

In shiny Proxy application.yml file,
container-cmd: ["R", "-e", "shiny::runApp('/root/euler')"]

When I tried to deploy the application without Brochure (i.e Single paged shiny app) then the deployment works.

Any help is greatly invited.

Creating a brochure app through golem does not import `{brochure}`

Following the Readme:

golem::create_golem("testbrochure", project_hook = brochure::golem_hook)

Creates a blank brochure app. But,

> devtools::load_all(".")
โ„น Loading testbrochure
> run_app()
Error in brochureApp(golem_add_external_resources(), home(), onStart = onStart,  : 
  could not find function "brochureApp"

And the DESCRIPTION does not import {brochure}:

Package: testbrochure
Title: An Amazing Shiny App
Version: 0.0.0.9000
Authors@R: 
    person(given = "firstname",
           family = "lastname",
           role = c("aut", "cre"),
           email = "[email protected]")
Description: What the package does (one paragraph).
License: What license is it under?
Imports: 
    config (>= 0.3.1),
    golem (>= 0.3.1),
    shiny (>= 1.7.1)
Encoding: UTF-8
LazyData: true
RoxygenNote: 7.1.1

The workaround is of course trivial,

usethis::use_package("brochure", min_version = TRUE)

but ideally this import would be declared by the function (like {golem} and {shiny})

@ColinFay Not sure if this is best filed under a {brochure} or {golem}?

Allow redirect

Allow to build a way to redirect a page to another, which the correct http code

reactLog error

reactLog does not work within the {brochure} framework, when CTRL + F3 are pressed, a browser comes up with the message 'Not Found' despite having the setup the same with just {golem} framework.
reactLog has been enabled.

Is there a need to use inner-session async in `brochure` pages?

Please see this link for detailed overview.

I cannot find in the docs, how multiple users interact w/ individual endpoints in brochure. i see that with "each new page opens a new session" under design patter, but does that refer to client side or server side? ie a new session the server is hosting for multiple users or, every new user a new session in the server?

Auto scale

We can build a proxy with NodeJS by scraping the brochure() object

shinyashboard doesn't refresh page, it opens a new one

Hi
I stumbled across a question in stackoverflow about creating a flow of a multipage app using tabsets inside a shinydashboard app .
I am able to recreate it, but when clicking on the tabname, instead of refreshing the page, it creates a new one.
Does this have something to do with the fact that shinydashboard adds a lot of js?

Minimal reproducible example:

library(shiny)
library(shinydashboard)
library(brochure)

header <- dashboardHeader(title = "Basic dashboard")
sidebar <- dashboardSidebar(
  sidebarMenu(
    menuItem("Dashboard", href = "/", icon = icon("dashboard")),
    menuItem("Widgets", href = "/widgets", icon = icon("th"))
  )
)

brochureApp(
  page(
    href="/",
    ui=dashboardPage(
      header,
      sidebar,
      dashboardBody(
        h2("Dashboard tab content")
      )
    ),
    server = function(input, output, session){}
  ),
  page(
    href="/widgets",
    ui=dashboardPage(
      header,
      sidebar,
      dashboardBody(
        h2("Widgets tab content")
      )
    ),
    server = function(input, output, session){}
  )
)

Just to be clear, I want to know if this issue is completely related to shinydasboard or you could see if there is any problem with brochure

Thanks!

Css not recognized when adapting traditional golem app to brochure [solved]

You have my utmost gratitude for this package and for everything you have done and continue to do in the shiny community.

I followed the great and detailed tutorial on how to adapt an existing traditional golem app to get it to work with brochure. I must say that everything worked perfectly until I tried to add a css file to the project - it was not recognized. Even after trying everything I could think of, it still did not work. Then, I tried to create a new project from scratch with the brochure project hook and found out that my css file worked with no problem at all. So I started to study the differences between the two projects, which led to the solution.

The tutorial mentions that the top part of app_ui.R should be deleted and only the bottom part (i.e. the function for adding external resources) should be kept. I am not sure about the details, but the solution for me was to entirely delete my app_ui.R and to copy and paste the function from a project created with brochure's project hook to my run_app.R. I also noted that the "correct" function has additional arguments such as basename for example.

In any case, I thought I would document what happened to me here. Hopefully it helps a few so that they will not have to start their project from scratch just because they would like to use brochure.

bug: sub-path not working

Reprex :

library(shiny)
library(brochure)
brochureApp(
  # First page
  page(
    href = "/",
    ui = fluidPage(
      h1("This is my first page"),
      plotOutput("plot")
    ),
    server = function(input, output, session) {
      output$plot <- renderPlot({
        plot(iris)
      })
    }
  ),
  # Second page, without any server-side function
  page(
    href = "/page2/this",
    ui = fluidPage(
      h1("This is my second page"),
      plotOutput("plot")
    ),
    server = function(input, output, session) {
      output$plot <- renderPlot({
        plot(iris)
      })
    }
  )
)

Diagnostics :

onPage

A form of observeEvent() to allow to run code only on given page.

onPage("yeah", {
	print("coucou")
})

Brochure hex logo

Hello Colin Fay / Brochure !

I see that this app has no logo. I was wondering if you would be interested in this design?

Hope you like it, I can make changes if you like.

Bootswatch-themes per page don't get applied

Hello,

I created a brochure app that consists of several pages. In each page I set another bootswatch-theme and experience strange behaviour: I never know which theme I will see. In most cases I get any of the themes and all pages look the same (though they should look different).

This doesn't occur when brochureApp contains only one page.

Maybe related: It seems that not all sessions that these pages spawn are closed in RStudio when closing the window/interrupt R (red stop sign). I removed pages from the brochureApp function and they were still available next time I started the brochureApp.

Here is my code:

library(bslib)
library(shiny)
library(stringi) 

page_names <- list("Home", "App 1", "App 2")
lorem_ipsum_dolor_sit_amet <- HTML(paste0(stri_rand_lipsum(10), 
                                          collapse = '<br><br>'))


home <- function() {
  brochure::page(
    href = "/",
    ui <- 
      bslib::page_navbar(
      theme = bs_theme(version = 5, bootswatch = "quartz"),
      window_title = page_names[1],      
      selected = page_names[1], 
      bslib::nav(
        value = page_names[1],
        tags$a(img(src = "https://www.r-project.org/logo/Rlogo.svg", 
                   height = "50", width = "50"), href = "/"),
        fluidPage(  
          tags$h2("Choose..."),
          tags$ul(
            tags$li(
              tags$a(icon("star"), page_names[2], href = "/1")
            ),
            tags$li(
              tags$a(icon("heart"), page_names[3], href = "/2")
            )
          ) 
        )
      ),
      bslib::nav(
        value = page_names[2],
        tags$a(icon("star"), page_names[2], href = "/1")
      ),
      bslib::nav(
        value = page_names[3],
        tags$a(icon("heart"), page_names[3], href = "/2")
      )
    ),
    server <- function(input, output, session) {
    }
  )
}

page_1 <- function() {
  brochure::page(
    href = "/1",
    ui <- bslib::page_navbar( 
      theme = bs_theme(version = 5, bootswatch = "darkly"),
      window_title = page_names[2],
      selected = page_names[2],
      bslib::nav(
        value = page_names[1],
        tags$a(img(src = "https://www.r-project.org/logo/Rlogo.svg", 
                   height = "50", width = "50"), "", href = "/")
      ),
      bslib::nav(
        value = page_names[2],
        tags$a(icon("star"), page_names[2], href = "/1"),
        fluidPage( 
          tags$h2("About App 1"),
          lorem_ipsum_dolor_sit_amet 
        )
      ),
      bslib::nav(
        value = page_names[3],
        tags$a(icon("heart"), page_names[3], href = "/2")
      )
    ),
    server <- function(input, output, session) {
    }
  )
}

page_2 <- function() {
  brochure::page(
    href = "/2",
    ui <- bslib::page_navbar(
      theme = bs_theme(version = 5, bootswatch = "cyborg"),
      window_title = page_names[3],
      selected = page_names[3], 
      bslib::nav(
        value = page_names[1],
        tags$a(img(src = "https://www.r-project.org/logo/Rlogo.svg", 
                        height = "50", width = "50"), "", href = "/")
      ),
      bslib::nav(
        value = page_names[2],
        tags$a(icon("star"), page_names[2], href = "/1")
      ),
      bslib::nav(
        value = page_names[3],
        tags$a(icon("heart"), page_names[3], href = "/2"),
        fluidPage( 
          tags$h2("About App 2"),
          lorem_ipsum_dolor_sit_amet 
        )
      )
    ),
    server <- function(input, output, session) {
    }
  )
}

brochure::brochureApp(  
  home(),
  page_1(),
  page_2()
)

golem hook

Add a golem hook to create a golem based brochure

Start from within RStudio

Hello,

Great to see your attempt to give shiny multiple web pages :)

I created a shiny app in RStudio and put in the code from your "Minimal {brochure} App".
Then I was able to click on the "run App"-Button and the brochure minimal app opened in a new window.

But if I close RStudio and reopen the file, RStudio doesn't recognise it as a shiny app anymore. The button "run App" changed to "Source". Clicking on it doesn't open a browser window.

I can only start the brochure app from within RStudio console via shiny::runApp(). Is this the only way to start a brochure app?

When I place shiny::runApp() at the end of my brochure app, I get an error (error message: Error: C stack usage 7976484 is too close to the limit)

Redirect to login page

Hey @ColinFay!

I was wondering if I could use {brochure} for a redirect to a login page? I am looking for a way to integrate AWS Cognito in a {golem} app, and I still haven't found a good package or resource to do that. I was wondering if I could use {brochure} to make my own redirect to the login page?

Thanks in advance!
Felipe

Refactor how brochures are built

For better code organisation and handling of server functions,

ui <- function(request){
  tagList()
}

server <- function(
  input, 
  output, 
  session
){

}

ui_2 <- function(request){
  tagList()
}

server_2 <- function(
  input, 
  output, 
  session
){

}

then

brochure(
  page(
    href = "/",
    ui = ui,
    server = server, 
    req_handlers = list()
  ), 
  page(
    href = "/page2",
    ui = ui_2, 
    server = server_2, 
    res_handlers = list()
  )
)

Allow a form of /page/:id: ร  la express

Something that would allow to write :

ui <- function(request){
  brochure(
    page(
      href = "/profile/:id:",
      ui = tagList(
        h1("This is my first page"),
        h2(paste("Hello", {:id:}) 
      )
    )
  )
}

Brochure adds unnecessary container-fluid

When using an HTML template to create the html layout of a Shiny app, the brochure application seems to add an unnecessary <div class="container-fluid"> to the application, potentially causing issues with the site rendering. Thanks for the cool package!

Reproducible example

template.html

<!doctype html>
<html lang="en">
<head>
{{ headContent() }}
</head>
<body>
<p>Hello</p>
</body>
</html>

app.R without brochure that renders correctly:

library(shiny)
ui <- htmlTemplate("template.html", document_=TRUE)
server <- function(input, output, session) {}
shinyApp(ui = ui, server = server)

app.R with brochure that renders incorrectly:

library(shiny)
ui <- htmlTemplate("template.html", document_=TRUE)
server <- function(input, output, session) {}
brochureApp(page("/",ui=ui, server = server))

Add middleware

We could have a mechanism to add middleware as functions to the page()

page(
	middleware = list(fun1, fun2, ...)
)

Strange EOF issue when POSTing JSON

Hi! I was working on an example of using brochure to handle post requests, and I noticed a weird error when sending JSON. The following simple app:

library(shiny)
library(jsonlite)
library(brochure)

number_vector <- numeric(0)

main_page <- page(
  href = "/",
  req_handlers = list(
    function(req){
      if (identical(req$REQUEST_METHOD, "POST")) {
        return(httpResponse(200, "text/plain", "OK\n"))
        data <- req$rook.input$read(-1)
        data <- jsonlite::fromJSON(rawToChar(data))
        message(paste0("Received post request with number: ", data$number))
        number_vector <<- c(number_vector, data$number)
        return(httpResponse(200, "text/plain", "OK\n"))
      } else {
        return(req)
      }
    }
  ),
  ui = h2("Numbers received:", textOutput("number_vector", inline = TRUE, container = span)),
  server = function(input, output, session) {
    recheck <- reactiveTimer(500)
    output$number_vector <- renderText({
      recheck() #this causes the number_total to get polled again
      paste0(number_vector, collapse = ", ")
    })
  }
)

brochureApp(
  main_page
)

Gives an error when POSTing JSON. Interestingly, the app works as intended but for some reason the POST returns a 500 error still. I think somehow an EOF is occurring in the data <- req$rook.input$read(-1) line, and that gets returned instead of the success:

> httr::POST('http://127.0.0.1', body = '{"number": 3}\n\n', encode = 'json')

Yields

Response [http://127.0.0.1]
  Date: 2022-07-28 03:06
  Status: 500
  Content-Type: text/plain; charset=UTF-8
  Size: 116 B
ERROR: parse error: premature EOF

Thanks!

Page redirection fails for rstudio server

Thanks for a great package, it really has potential I think.

Here is my problem:
If you start a brochure app in "Rstudio server" not "Rstudio"! , you first get a pop up window, I think this window will never work with redirections, but what should work is if you click "open in browser" in this window

Then you get paths, but your app is not running in relative href directory "/" as in normal Rstudio, but something like:
http://localhost:20002/p/adfae814/

So if you redirect to homepage "/", that will make you go to Rstudio server IDE and not the home page of the app.
Because http://localhost:20002/ is the URL for your ssh Rstudio server connection

I guess this is only a bug during development?

To recreate the bug, run Rstudio server on a ssh server and run your example code under redirect section:

brochureApp(
  # Pages
  page_1(),
  page_2(),
  page_contact(),
  # Redirections
  redirect(
    from = "/page3",
    to = "/page2"
  ),
  redirect(
    from = "/page4",
    to = "/"
  )
)

This will not work.

To fix this I believe there is a way,
Lets say we have a page called "/heatmap", you can manually in the browser update URL to:
http://localhost:20002/p/adfae814/heatmap instead of the failed redirect: http://localhost:20002/heatmap

But then redirection by click will still not work, and if you set the href of each page brochure will fail since it requires a page at location
"/" (This you set as a requirement to make sure there is a home startup page).

To initially fix this you can make a dummy front page that has "/", and have another for redirection later, that will actually work.
What I then need to do is to extract unique client URL, with

observe({
      print(reactiveValuesToList(session$clientData))
    })

But I have not figured out a way to retrieve this client value and store it to the href of the pages before I actually call the app pages.

Will update here if I figure it out,
Let me know if I am doing something too complicated here :)

adding a "www" folder to my app caused it to unexpectedly break

I had a POST request in my brochure app, as this blog post suggested, and it was working extremely well up until I added a "www" folder with a "site.css" file to my app. At that point the req_handlers of the post function stopped being fired off. When I deleted the folder the POST requests worked again. I'm not sure how these two parts of the code would be related but it did seem to be the case.

setInputvalue to capture the current page

Something like this in the page function:

$(function() {
  // set by default on first page
  Shiny.setInputValue('current_page', window.location.href);
  // set whenever location changes
  window.addEventListener('popstate', function() {
    Shiny.setInputValue('current_page', window.location.href);
   });
});
page <- function(
  href,
  ui
){
  list(
    href = href,
    ui = tagList(
      tags$head(
        tags$script(
          "$(function() {
            // set by default on first page
            Shiny.setInputValue('current_page', window.location.href);
            // set whenever location changes
            window.addEventListener('popstate', function() {
              Shiny.setInputValue('current_page', window.location.href);
            });
          });
          "
        )
      ),
      ui
    )
  )
}

Example:

library(brochure)
library(shiny)

brochure_button <- function(href, ...) {
  tags$button(onclick = sprintf("window.location.href='%s'", href), ..., class = "brochure-btn")
}

ui <- function(request){
  brochure(
    page(
      href = "/",
      ui = tagList(
        h1("This is my first page"),
        brochure_button(href = "page2", "Next"),
        plotOutput("plota")
      )
    ),
    page(
      href = "/page2",
      ui =  tagList(
        h1("This is my second page"),
        fluidRow(
          brochure_button(href = "/", "Previous"),
          brochure_button(href = "contact", "Next")
        ),
        plotOutput("plotb")
      )
    ),
    page(
      href = "/contact",
      ui =  tagList(
        h1("Contact us"),
        brochure_button(href = "page2", "Previous"),
        tags$ul(
          tags$li("Here"),
          tags$li("There")
        )
      )
    )
  )
}

server <- function(
  input, 
  output, 
  session
){
  
  brochure_enable()
  
  observeEvent(input$current_page, {
    showNotification(
      ui = sprintf("Welcome on page %s", input$current_page),
      duration = 5
    )
  })
  
  output$plota <- renderPlot({
    plot(mtcars)
  })
  
  output$plotb <- renderPlot({
    plot(airquality)
  })
  
}

brochureApp(ui, server)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.