[Bug]: Problem in the uiOutput and renderUI in modules
Closed this issue · 9 comments
Guidelines
- I agree to follow this project's Contributing Guidelines.
Project Version
0.2.1
Platform and OS Version
Windows 10 x64
Existing Issues
What happened?
Dear creators,
first of all thank you for developing this package which I have started to use and appreciate its potentialities.
The package works properly for every section except when we pass inside a module and inside uiOutput and renderUI function.
In fact when I go to edit the languages it translates everything except the part that are inside those two functions.
Below you will find code to reproduce the problem, but if you need more information I am available.
Could you help me to solve this?
Steps to reproduce
app_ui.R
#' The application User-Interface
#'
#' @param request Internal parameter for `{shiny}`.
#' DO NOT REMOVE.
#' @import shiny
#' @noRd
i18n <- shiny.i18n::Translator$new(translation_json_path='translations/translation.json')
i18n$set_translation_language('Italiano')
app_ui <- function(request) {
tagList(
# Leave this function for adding external resources
golem_add_external_resources(),
# Your application UI logic
fluidPage(
h1(i18n$t("Titolo")),
selectInput(inputId='selected_language',
label=i18n$t('Lingua'),
multiple = FALSE,
choices = i18n$get_languages(),
selected = i18n$get_key_translation()),
mod_name_of_module1_ui("name_of_module1_1"),
hr(),
hr(),
mod_name_of_module2_ui("name_of_module2_1")
)
)
}
#' Add external Resources to the Application
#'
#' This function is internally used to add external
#' resources inside the Shiny application.
#'
#' @import shiny
#' @importFrom golem add_resource_path activate_js favicon bundle_resources
#' @noRd
golem_add_external_resources <- function() {
add_resource_path(
"www",
app_sys("app/www")
)
tags$head(
favicon(),
bundle_resources(
path = app_sys("app/www"),
app_title = "translationtest"
),
shiny.i18n::usei18n(i18n)
# Add here other external resources
# for example, you can add shinyalert::useShinyalert()
)
}
app_server.R
#' The application server-side
#'
#' @param input,output,session Internal parameters for {shiny}.
#' DO NOT REMOVE.
#' @import shiny
#' @noRd
app_server <- function(input, output, session) {
# Your application server logic
library(shiny)
library(shiny.i18n)
i18n <- shiny.i18n::Translator$new(translation_json_path='translations/translation.json')
i18n$set_translation_language('Italiano')
observeEvent(input$selected_language, {
update_lang(session, input$selected_language)
})
mod_name_of_module1_server("name_of_module1_1")
mod_name_of_module2_server("name_of_module2_1")
}
mod_name_of_module1.R
#' name_of_module1 UI Function
#'
#' @description A shiny Module.
#'
#' @param id,input,output,session Internal parameters for {shiny}.
#'
#' @noRd
#'
#' @importFrom shiny NS tagList
mod_name_of_module1_ui <- function(id){
ns <- NS(id)
tagList(
h4("We are in the module 1"),
h4(i18n$t("Titolo")),
uiOutput(ns("module_1_ui")),
uiOutput(ns("module_2_ui"))
)
}
#' name_of_module1 Server Functions
#'
#' @noRd
mod_name_of_module1_server <- function(id){
moduleServer( id, function(input, output, session){
ns <- session$ns
output$module_1_ui<-renderUI({
h4("We are in the module 1 - renderui section")
})
output$module_2_ui<-renderUI({
h4(i18n$t("Titolo"))
})
})
}
## To be copied in the UI
# mod_name_of_module1_ui("name_of_module1_1")
## To be copied in the server
# mod_name_of_module1_server("name_of_module1_1")
mod_name_of_module2.R
#' name_of_module2 UI Function
#'
#' @description A shiny Module.
#'
#' @param id,input,output,session Internal parameters for {shiny}.
#'
#' @noRd
#'
#' @importFrom shiny NS tagList
mod_name_of_module2_ui <- function(id){
ns <- NS(id)
tagList(
h4("We are in the module 2"),
h4(i18n$t("Titolo")),
uiOutput(ns("module_1_ui")),
uiOutput(ns("module_2_ui"))
)
}
#' name_of_module2 Server Functions
#'
#' @noRd
mod_name_of_module2_server <- function(id){
moduleServer( id, function(input, output, session){
ns <- session$ns
output$module_1_ui<-renderUI({
h4("We are in the module 2 - renderui section")
})
output$module_2_ui<-renderUI({
h4(i18n$t("Titolo"))
})
})
}
## To be copied in the UI
# mod_name_of_module2_ui("name_of_module2_1")
## To be copied in the server
# mod_name_of_module2_server("name_of_module2_1")
translation.json
{
"languages": ["Italiano","English","Brasileiro","Español","Français","Deutsch","**", "やまと"],
"translation": [
{
"Italiano": "Titolo",
"English": "Title",
"Brasileiro": "Título",
"Español": "Título",
"Français": "Titre",
"Deutsch" : "Titel",
"**": "标题",
"やまと": "タイトル"
}
]
}
Expected behavior
When I change the selectinput I expect everything to be translated instead the elements within the forms in the uiouput and renderui section do not change
Any news or update about this issue?
@agronomofiorentini, did you find a solution to this?
I have the same issue and not sure if it's a bug or something wrong on my end.
I'm sorry but I haven't found any solution for this yet.
In fact I was looking for help from the appsilon team to figure out.
Here is my reproducible example of the problem, based on the solution posted here:
library(shiny)
library(shiny.i18n)
i18n <- Translator$new(translation_json_path = "../data/translation.json")
i18n$set_translation_language("pl")
languageButton_UI <- function(id, i18n) {
ns <- NS(id)
tagList( usei18n(i18n), actionButton(ns("go"), "English"), h2(i18n$t("Hello Shiny!"))
)
}
languageButton_Server <- function(id, global_session) {
moduleServer(
id,
function(input, output, session) {
ns <- NS(id)
observeEvent(input$go,{
print(input$go[1])
if((input$go[1] %% 2) != 0){
updateActionButton(session, "go",
label = "Polish")
update_lang(global_session, "en")
} else {
updateActionButton(session, "go",
label = "English")
update_lang(global_session, "pl")
}
})
}
)
}
another_UI <- function(id, i18n) {
ns <- NS(id)
uiOutput(ns("test"))
}
another_Server <- function(id, global_session) {
moduleServer(
id,
function(input, output, session) {
ns <- NS(id)
output$test <- renderUI(tagList(
usei18n(i18n),
p(i18n$t("Hello Shiny!"))
))
}
)
}
ui <- fluidPage(
languageButton_UI("language_button", i18n = i18n),
another_UI("test", i18n = i18n)
)
server <- function(input, output, session) {
languageButton_Server("language_button", global_session = session)
another_Server("test", global_session = session)
}
shinyApp(ui, server)
Dear @AdrianHordyk
I have seen the #48
I tried to implement the suggested code, but i have still problem in the renderui section.
The follow is the code
library(shiny)
library(shiny.i18n)
mod_name_of_module1_ui <- function(id, i18n){
ns <- NS(id)
tagList(
h4("We are in the module 1"),
h4(i18n$t("Titolo")),
uiOutput(ns("module_1_ui")),
uiOutput(ns("module_2_ui")))
}
mod_name_of_module1_server <- function(id, global_session){
moduleServer(id, function(input, output, session){
ns <- session$ns
output$module_1_ui<-renderUI({
h4("We are in the module 1 - renderui section")
})
output$module_2_ui<-renderUI(
tagList(
shiny.i18n::usei18n(i18n),
h4(i18n$t("Titolo"))
)
)
})
}
mod_name_of_module2_ui <- function(id, i18n){
ns <- NS(id)
tagList(
h4("We are in the module 2"),
h4(i18n$t("Titolo")),
uiOutput(ns("module_1_ui")),
uiOutput(ns("module_2_ui"))
)
}
mod_name_of_module2_server <- function(id, global_session){
moduleServer( id, function(input, output, session){
ns <- session$ns
output$module_1_ui<-renderUI({
h4("We are in the module 2 - renderui section")
})
output$module_2_ui<-renderUI(
tagList(
shiny.i18n::usei18n(i18n),
h4(i18n$t("Titolo")))
)
})
}
i18n <- shiny.i18n::Translator$new(translation_json_path='translations/translation.json')
i18n$set_translation_language('Italiano')
app_ui <- function(request) {
tagList(
# Your application UI logic
fluidPage(
shiny.i18n::usei18n(i18n),
h1(i18n$t("Titolo")),
selectInput(inputId='selected_language',
label=i18n$t('Lingua'),
multiple = FALSE,
choices = i18n$get_languages(),
selected = i18n$get_key_translation()),
mod_name_of_module1_ui("name_of_module1_1", i18n = i18n),
hr(),
hr(),
mod_name_of_module2_ui("name_of_module2_1", i18n = i18n)
)
)
}
app_server <- function(input, output, session) {
# Your application server logic
library(shiny)
library(shiny.i18n)
observeEvent(input$selected_language, {
update_lang(session, input$selected_language)
})
mod_name_of_module1_server("name_of_module1_1", global_session = session)
mod_name_of_module2_server("name_of_module2_1", global_session = session)
}
shinyApp(app_ui, app_server)
The traslation.json is the follow
{
"languages": ["Italiano","English","Brasileiro","Español","Français","Deutsch","**", "やまと"],
"translation": [
{
"Italiano": "Titolo",
"English": "Title",
"Brasileiro": "Título",
"Español": "Título",
"Français": "Titre",
"Deutsch" : "Titel",
"**": "标题",
"やまと": "タイトル"
}
]
}
@agronomofiorentini I am having the same problem.
At first I thought #48 solved it but it doesn't.
I posted my code as a minimum reproducible example of the problem based on #48.
Ok, setting i18n
as a reactive object seems to do the trick:
library(shiny)
library(shiny.i18n)
translator <- Translator$new(translation_json_path = "../data/translation.json")
translator$set_translation_language('en')
another_UI <- function(id) {
ns <- NS(id)
uiOutput(ns("test"))
}
another_Server <- function(id, i18n) {
moduleServer(
id,
function(input, output, session) {
ns <- NS(id)
output$test <- renderUI(tagList(
usei18n(i18n()),
h1('renderUI in module'),
p(i18n()$t("Hello Shiny!"))
))
}
)
}
server <- function(input, output, session) {
i18n <- reactive({
req(input$selected_language)
selected <- input$selected_language
if (length(selected) > 0 && selected %in% translator$get_languages()) {
translator$set_translation_language(selected)
}
translator
})
output$ui <- renderUI({
tagList(
selectInput('selected_language',
"Select language",
choices = translator$get_languages(),
selected = translator$get_key_translation()
)
)
})
output$text <- renderUI({
tagList(
h1('renderUI in server'),
h2(i18n()$t("Hello Shiny!"))
)
})
lang <- reactive({
req(input$selected_language)
input$selected_language
})
observeEvent(lang(), {
shiny.i18n::update_lang(session, input$selected_language)
print(i18n()$t('Hello Shiny!'))
}, ignoreInit = FALSE)
another_Server("test", i18n=i18n)
}
ui <- fluidPage(
uiOutput("ui"),
uiOutput("text"),
another_UI("test")
)
shinyApp(ui, server)
Now to see if I can replicate this in my more complex use case
I will try your suggestion and i will tell you if is working also from my side.
Thanks @AdrianHordyk
Hey @AdrianHordyk
It's working.
This is my code
library(shiny)
library(shiny.i18n)
translator <- shiny.i18n::Translator$new(translation_json_path='translation.json')
translator$set_translation_language('Italiano')
mod_name_of_module1_ui <- function(id){
ns <- NS(id)
tagList(
h4("We are in the module 1"),
h4(translator$t("Titolo")),
uiOutput(ns("module_1_ui")),
uiOutput(ns("module_2_ui")))
}
mod_name_of_module1_server <- function(id, i18n){
moduleServer(id, function(input, output, session){
ns <- session$ns
output$module_1_ui<-renderUI({
h4("We are in the module 1 - renderui section")
})
output$module_2_ui<-renderUI(
tagList(
shiny.i18n::usei18n(i18n()),
h4(i18n()$t("Titolo"))
)
)
})
}
mod_name_of_module2_ui <- function(id){
ns <- NS(id)
tagList(
h4("We are in the module 2"),
h4(translator$t("Titolo")),
uiOutput(ns("module_1_ui")),
uiOutput(ns("module_2_ui"))
)
}
mod_name_of_module2_server <- function(id, i18n){
moduleServer( id, function(input, output, session){
ns <- session$ns
output$module_1_ui<-renderUI({
h4("We are in the module 2 - renderui section")
})
output$module_2_ui<-renderUI(
tagList(
shiny.i18n::usei18n(i18n()),
h4(i18n()$t("Titolo")))
)
})
}
app_ui <- function(request) {
tagList(
fluidPage(
shiny.i18n::usei18n(translator),
h1(translator$t("Titolo")),
selectInput(inputId='selected_language',
label=translator$t('Lingua'),
multiple = FALSE,
choices = translator$get_languages(),
selected = translator$get_key_translation()),
mod_name_of_module1_ui("name_of_module1_1"),
hr(),
hr(),
mod_name_of_module2_ui("name_of_module2_1")
)
)
}
app_server <- function(input, output, session) {
observeEvent(input$selected_language, {
update_lang(session, input$selected_language)
})
i18n <- reactive({
req(input$selected_language)
selected <- input$selected_language
if (length(selected) > 0 && selected %in% translator$get_languages()) {
translator$set_translation_language(selected)
}
translator
})
mod_name_of_module1_server("name_of_module1_1", i18n = i18n)
mod_name_of_module2_server("name_of_module2_1", i18n = i18n)
}
shinyApp(app_ui, app_server)
Thanks again