I am working on a multilingual shiny app using the shiny.i18n
package to translate different parts of the UI. It works really well until I tried to dynamically translate the text inside a specific selectInput
menu. Some reproducible code below:
# Translating text of a menu item from data
library(shiny)
library(shiny.i18n)
library(tidyverse)
# Create translation file and save in a directory called trans
system("mkdir trans")
translation_key <- data.frame(es = c("Cambiar de lenguaje", "Seleccione un proyecto", "Todos"),
en = c("Change language", "Select a project", "All")
)
write.csv(translation_key, "trans/translation_key.csv",
row.names = FALSE,
quote = FALSE)
# Create data object
data <- data.frame(project_name =c("Todos","proj1", "proj2"),
n = c(20,30,40)
)
# Setup translator
trans <- Translator$new(translation_csvs_path = "trans")
trans$set_translation_language("es")
# Define UI
ui <- fluidPage(
usei18n(trans),
# Application title
titlePanel("Reactivity test"),
mainPanel(
selectInput('selected_language',
trans$t("Cambiar de lenguaje"),
choices = trans$get_languages()
),
selectInput("project_name",
trans$t("Seleccione un proyecto"),
choices = NULL
),
textOutput("n")
)
)
# server part
server <- function(session, input, output) {
# update languae
observeEvent(input$selected_language, {
update_lang(session, input$selected_language)
print(paste("Language change!", input$selected_language))
})
# change the first element of data$project and translate it! It does not do it!
data_rv <- eventReactive(input$selected_language, {
data$project_name[1] <- trans$t("Todos")
data
})
# update the selection for project name depending on the language
observeEvent(data_rv(), {
updateSelectInput(session, inputId = "project_name",
choices = unique(data_rv()$project_name))
})
# print the n associated with project_name selected
output$n <- renderText({
req(input$project_name)
res <- data_rv() %>% filter(project_name == input$project_name)
res$n
})
}
# Run the application
shinyApp(ui = ui, server = server)
I attempt the translation of the first element of data$project_name
inside an eventReactive
call that returns the modified translated object. The problem is that the translation does not happen until after the menu for project_name is rendered (see screenshot below).
The application starts by default in Spanish (es) and when changed to English (en), everything is translated except the first item in the Select a project menu (it should say All instead of Todos).
I have found a solution using uiOutput
and renderUI
but the application I am working on has a very complex layout of panels and tabs and I rather not rework all the code if I can help it. Can someone recommend a workaround that works from the browser side. Thanks,
An alternative in this case could be making data_rv
a reactive expression with a req()
instead of an eventReactive
. It may also keep it simple for your purpose.
I tried it like this with your example:
# change the first element of data$project and translate it!
data_rv <- reactive({
req(input$selected_language)
data$project_name[1] <- trans$t(data$project_name[1])
data
})
Seems it checks out! reactivity question image here
Note: I translated reactivity test to prueba de reactividad for clarity but is not in the original reproducible example