Changing bookmark state directory when saving to disk

When saving bookmarks to disk, by default the state directory will be created within the app directory. I would rather specify my own state directory and tried to do this by assigning the desired path to state$dir within onBookmark but this does not seem to work - see the reproducible code below (should work on Windows and Mac).

library(shiny)

ui <- function(request) {
  
  fluidPage(
    textInput("txt", "Enter text"),
    checkboxInput("caps", "Capitalize"),
    verbatimTextOutput("out"),
    bookmarkButton()
  )
  
}

server <- function(input, output, session) {
  output$out <- renderText({
    if (input$caps)
      toupper(input$txt)
    else
      input$txt
  })
  
  # Define default path (to be changed later)
  switch(Sys.info()[['sysname']],
         Windows = {path <<- gsub("\\\\", "/", file.path(Sys.getenv("USERPROFILE"),"Desktop",fsep="/"))},
         Mac = {path <<- "~/Desktop"})
  
  onBookmark(function(state) {
    
    # Change working directory to target directory for bookmarks:
    id = gsub(sprintf("%s/shiny_bookmarks/",getwd()), "", state$dir) # get unique id
    state$dir = sprintf("%s/shiny_bookmarks/%s", path, id)
    
  })
  
}

enableBookmarking(store="server")
shinyApp(ui, server)

Is there any way to overwrite the default state directory or any reason why the option is not available?

Many thanks in advance,

Patrick

Is there any way to overwrite the default state directory or any reason why the option is not available?

There is are undocumented ways. The more 'official' way is through a shiny-server config setting, but it looks as though your only interested in running Shiny locally (shiny-server only runs on Linux). In that case, you can set the (undocumented) save.interface option. When Shiny runs locally, it defaults to this function, but you can override it:

my_save_interface <- function(id, callback) {
  path <- switch(
    Sys.info()[['sysname']],
    Windows = gsub("\\\\", "/", file.path(Sys.getenv("USERPROFILE"),"Desktop",fsep="/")),
    Darwin = "~/Desktop",
    getShinyOption("appDir", default = getwd())
  )
  stateDir <- file.path(path, "shiny_bookmarks", id)
  if (!shiny:::dirExists(stateDir))
    dir.create(stateDir, recursive = TRUE)
  callback(stateDir)
}

shinyOptions(save.interface = my_save_interface)

Keep in mind that this option is not documented because it's easy to shoot yourself in the foot. By using something other than the application directory for the bookmarking state, you're assuming a lot about the user's environment. Even if you have the setup and permissions, you could be overwriting files that shouldn't overwritten, and you lose the ability easily tell what state folder belongs to which app.

3 Likes

Thanks - much appreciated. This does what I wanted to achieve, although I'm running into issues upon restoring the session (but should be able to figure that out eventually). Anyway this is only a temporary workaround - we'll move to server eventually, but are still in the process of developing the app and working locally. Many thanks again!

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.