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.