Another take on building a multi-lingual shiny app
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
I was reading this interesting post about how to build a multi-lingual Shiny app. I’m also building a multi-lingual Shiny app and came up with slightly different take on it.
First, I don’t use a function for finding the translation, but a 2D list. This way I can directly get to the translation with a simple access to the list.
1 2 3 4 5 6 7 | translation <- list( "youhaveselected" = list("en" = "You have selected:", "fr"="Vous avez sélectionné:"), "greetings" = list("en" = "Hello", "fr"="Bonjour") ) # then: translation[['greetings']][['en']] # Hello translation[['greetings']][['fr']] # Bonjour |
Second, I don’t use observe, as I didn’t find it necessary. I simply have a radio button for switching between languages, and a function tr() to translate a phrase or a list of phrases. Like in the original post, the UI is built from server.R using renderUI().
1 2 3 | tr <- function(text){ # translates text into current language sapply(text,function(s) translation[[s]][[input$language]], USE.NAMES=FALSE) } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | # UI output$uiObs <- renderUI({ sliderInput("obs", tr("numberOfObservations"), min = 1, max = 100, value = 50) }) output$uiWeekdays <- renderUI({ # Using a named list in order to pass the same value regardless of the label (which changes with the language) daysValue <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday") days <- structure(daysValue, .Names = tr(daysValue)) selectInput(inputId = "weekdays", label = tr("Selection:"), choices = days, multiple = TRUE) }) |
To make things easier for the translators, the dictionary is stored as a csv file, which is easy to edit. A small R script turns the csv into the expected 2D list, and saves it in a binary file, to avoid re-processing the file every time the user decides to switch language.
1 2 3 4 5 6 7 8 9 | # update the processed translation file translation.bin # run this every time dictionary.csv is updated # it reads the look-up table in dictionary.csv and turns it into a 2D list library(plyr) translationContent <- read.delim("dictionary.csv", header = TRUE, sep = "t", as.is = TRUE) translation <- dlply(translationContent ,.(key), function(s) key = as.list(s)) save(translation, file = "translation.bin") |
You can consult the whole code on the github repository and run it directly from R using:
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.