2

I am translating all texts in my Shiny-app with Shiny.i18n, using the live approach. I am having a realtive long Text in my app, which I want to be able to translate but also at the same time make individual words in that text bold.

I know that I could theoretically write and translate each word individually and then make it bold. But I would like to find a more elegant option that lets me make words within a larger context bold.

Here is a repex of my problem.

The Shiny-App

library(shiny)
library(shiny.i18n)
library(ggplot2)

i18n <- Translator$new(translation_json_path='translation.json')
i18n$set_translation_language('de')



ui <- fluidPage(
  shiny.i18n::usei18n(i18n),
  h1(i18n$t("Welt")),
  tags$div(
    style='float: right;',
    selectInput(
      inputId='selected_language',
      label=i18n$t('Change language'),
      choices = i18n$get_languages(),
      selected = i18n$get_key_translation()
    )
  ),
  h1(i18n$t("<strong>Hallo</strong> Welt"), windowTitle=NULL),
  
  )


server <- function(input, output, session) {
  observeEvent(input$selected_language, {
    update_lang(session, input$selected_language)
  })
  
}

# Run the application 
shinyApp(ui = ui, server = server)

I have my translations saved in a json e.g.

   "languages":[
      "de",
      "en"
   ],
   "translation":[
      {
         "de":"<strong>Hallo</strong> Welt",
         "en":"<strong>Hello</strong> World"
      },
      {
         "de":"Sprache Aendern:",
         "en":"Change language:"
      },
      {
        "de":"Welt",
        "en":"World"
      }
   ]
}

If i now try to change the language only "World" is translated. "< strong >Hallo< /strong > Welt" does not get translated at all. I dont understand why.

If I add h1(i18n$t(HTML("<strong>Hallo</strong> Welt")). "Hallo" does get bold, but the sentence is still not translated.

I have also tried h1(HTML(i18n$t("<strong>Hallo</strong> Welt")), but this throws the following error message:

Error in FUN(X[[i]], ...) : argument is not a character vector

Thank you very much for any advice or any ideas

LauraFeh
  • 46
  • 6
  • The problem is that with the use of `usei18n` the content of the original json is stored here and there in the DOM using `htmltools` functions like `span`. BUT: the text ist **escaped** and suddenly you have a mismatch, which prevents the auto translation. You can get the code running by using `h1(i18n$t(HTML("Hallo Welt")))` but the translation won't work b/c of the aforementioned reasons. Bottom line: do not use the auto translation with `use18n` or fall back to single words and keep markup out of the json. – thothal Jun 14 '22 at 11:42

1 Answers1

-1

First things first, a Full Reproducible Example will halp in the future to get proper answers, as you do not require the people who are dedicated some of their time to your problem to first create a running example.

Regarding your problem. You need to tell shiny to render the text as HTML. See the use of HTML in the example below.

translation.json

{
   "languages":[
      "de",
      "en"
   ],
   "translation":[
      {
         "de":"<strong>Hallo</strong> Welt",
         "en":"<strong>Hello</strong> World"
      },
      {
         "de":"Sprache ändern:",
         "en":"Change language:"
      }
   ]
}

app.R

library(shiny)
library(shiny.i18n)
translator <- Translator$new(translation_json_path = "translation.json")

ui <- fluidPage(
   titlePanel('Use HTML in Translation'),
   uiOutput('page_content')
)

server <- function(input, output, session) {
   i18n <- reactive({
      selected <- input$selected_language
      if (length(selected) > 0 && selected %in% translator$get_languages()) {
         translator$set_translation_language(selected)
      }
      translator
   })
   
   output$page_content <- renderUI({
      tagList(
         sidebarLayout(
            sidebarPanel(
               selectInput('selected_language',
                           i18n()$t("Sprache ändern:"),
                           choices = translator$get_languages(),
                           selected = input$selected_language)
            ),
            mainPanel(
               ## note the use of `HTML` here
               p(HTML(i18n()$t("<strong>Hallo</strong> Welt"))) 
            )
         )
      )
   })
}

shinyApp(ui = ui, server = server)

Screenshot

Screenshot showing the bold word in the translation

thothal
  • 16,690
  • 3
  • 36
  • 71
  • Thank you very much for your help! I have now added a repex. Unfortunately your solution does not work for me. I think it is because I translate my app a little bit different, but I am not sure. Do you have any other advice/idea? – LauraFeh Jun 11 '22 at 15:36