Coder Social home page Coder Social logo

appsilon / shiny.i18n Goto Github PK

View Code? Open in Web Editor NEW
166.0 31.0 37.0 3.84 MB

Shiny applications internationalization made easy

Home Page: https://appsilon.github.io/shiny.i18n/

License: Other

R 94.42% JavaScript 2.77% CSS 2.81%
shiny translation r internationalization language cran rhinoverse

shiny.i18n's Introduction

shiny.i18n shiny.i18n logo

Shiny applications internationalization made easy!

CRAN status codecov cranlogs total R-CMD-check

Using it is very simple: just prepare your translation files in one of the supported formats, read them into your app using user-friendly shiny.i18n interface and surround your expressions to translate by a translator tag. Thanks to that your app will remain neat and readable.

Actually, you can use shiny.i18n as a standalone R package - shiny app is just a perfect use-case example.

Change languages and formats easy with shiny.i18n.

How to install?

Stable version:

install.packages("shiny.i18n")

Development version:

remotes::install_github("Appsilon/shiny.i18n")

Examples

You can find some basic examples in examples folder:

  1. Using i18n object with CSV translation files or JSON translation files.

  2. Live language change on the browser side or with the server function renderUI.

  3. RMarkdown translations.

  4. Example of translation data format.

  5. shiny.i18n works seamlessly with Quarto.

  6. shiny.i18n also works when used in interactive Quarto + Shiny instances. Alternatively, you can also experience a deployed version.

Translation file format

Currently shiny.i18n supports two translation formats:

  • csv - where each translation is in separate file translation_<LANGUAGE-CODE>.csv containing two columns: key translation, language to which it needs to be translated. Example of translation_pl.csv for Polish language you may find here: inst/examples/data/translation_pl.csv. You load the data by passing the path to folder containing all the csv files:
Translator$new(translation_csvs_path = "...")
  • json - single json file translation.json with mandatory fields: "languages" with list of all language codes and "translation" with list of dictionaries assigning each translation to a language code. Example of such a json file for Polish language you may find here: inst/examples/data/translation.json. You load the data by passing the path to json file.
Translator$new(translation_json_path = "...")

shiny.i18n and rhino

shiny.i18n can be used to add live language change feature to Shiny applications built using Rhino framework. For more details, check this tutorial.

How to contribute?

If you want to contribute to this project please submit a regular PR, once you're done with a new feature or bug fix.

Reporting a bug is also helpful - please use GitHub issues and describe your problem as detailed as possible.

Appsilon

Appsilon is a Posit (formerly RStudio) Full Service Certified Partner.
Learn more at appsilon.com.

Get in touch [email protected]

Explore the Rhinoverse - a family of R packages built around Rhino!

We are hiring!

shiny.i18n's People

Contributors

berkorbay avatar can-taslicukur avatar deepanshkhurana avatar dokato avatar eduardodudu avatar fractalpolarity avatar jakubnowicki avatar jey1401 avatar krystian8207 avatar krzyslom avatar marekrogala avatar mend-bolt-for-github[bot] avatar przytu1 avatar sankhadeepdutta avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

shiny.i18n's Issues

Semicolon-separated CSVs

I just moved to a new country, where they use commas for decimals, so Excel saves CSVs with semicolons as separators. Giving them to the translator doesn't work.

Could there be an argument in to switch between read.csv and read.csv2 (which uses semicolons) in multmerge()? I think that would solve the issue and make the package more internationally friendly. :)

CVE-2020-11022 (Medium) detected in jquery-3.4.1.min.js - autoclosed

CVE-2020-11022 - Medium Severity Vulnerability

Vulnerable Library - jquery-3.4.1.min.js

JavaScript library for DOM operations

Library home page: https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js

Path to dependency file: /docs/reference/save_to_csv.html

Path to vulnerable library: /docs/reference/save_to_csv.html

Dependency Hierarchy:

  • jquery-3.4.1.min.js (Vulnerable Library)

Found in HEAD commit: 6b2e254700f0cad98b0de1c6391a4e02012fc98e

Found in base branch: master

Vulnerability Details

In jQuery versions greater than or equal to 1.2 and before 3.5.0, passing HTML from untrusted sources - even after sanitizing it - to one of jQuery's DOM manipulation methods (i.e. .html(), .append(), and others) may execute untrusted code. This problem is patched in jQuery 3.5.0.

Publish Date: 2020-04-29

URL: CVE-2020-11022

CVSS 3 Score Details (6.1)

Base Score Metrics:

  • Exploitability Metrics:
    • Attack Vector: Network
    • Attack Complexity: Low
    • Privileges Required: None
    • User Interaction: Required
    • Scope: Changed
  • Impact Metrics:
    • Confidentiality Impact: Low
    • Integrity Impact: Low
    • Availability Impact: None

For more information on CVSS3 Scores, click here.

Suggested Fix

Type: Upgrade version

Origin: https://blog.jquery.com/2020/04/10/jquery-3-5-0-released/

Release Date: 2020-04-29

Fix Resolution: jQuery - 3.5.0


Step up your Open Source Security Game with Mend here

Translation for radioButton() choices and selectInput()

Hi shiny.i18n team,

I know I have seen questions about this before but I can't find a solution -- I need to find a way to translate the choices in my selectInput() and radioButtons() inputs. If I try to wrap choice labels with i18n$t(), the app does not run. I don't know if this is a feature in the package yet, but if it isn't, would you mind offering some best practices for how people should get by in the meantime?

I am doing live translation and using uiOutput(page_content) in my UI to do automatic translation when the user selects a radio button with the language on it. I don't need to update the language selection radio buttons themselves, but I need it for other radioButton inputs and a dropdown SelectInput() with common names of species.

Thank you in advance for your help.

[Bug]: Trouble translating HTML tags

Guidelines

  • I agree to follow this project's Contributing Guidelines.

Project Version

0.2.0

Platform and OS Version

No response

Existing Issues

No response

What happened?

I have a text which is like

HTML("This is a long text <br> with a line break")

This basically returns "with a line break" on next line since <br> is a line break. I want to translate the same using shiny.i18n however, that doesn't seem to work with HTML tags.

HTML(i18n$t("This is a long text <br> with a line break"))

It displays the same text in English even when I change the language.

This is how my translation csv looks

en, fr
This is a long text <br> with a line break, Ceci est un long texte <br> avec un saut de ligne

The rest of the translation works fine as expected.

Steps to reproduce

Run the translation code with HTML tags.

Expected behavior

Corresponding translation should be available for HTML tags just like the other ones.

Attachments

No response

Screenshots or Videos

No response

Additional Information

No response

Problem with translating the options for Shiny Widgets

Hello,
I was trying to create an instance of the Live language change on the browser side by following the examples.
It works very well with the "label" elements of the widgets, but the option texts are not getting translated.

I'm attaching an example where I was trying to create a Likert scale widget using the "shinyWidgets" package, and the options are not playing well.

Code snippet below:

# Not Working
shiny.i18n::usei18n(i18n)
likert.choices = c(i18n$t("Strongly disagree"), i18n$t("Disagree"), i18n$t("Neither agree nor disagree"), i18n$t("Agree"), i18n$t("Strongly agree"))
...
#Input: Slider  ----
            sliderTextInput( 
                inputId = "Id102",
                label = i18n$t("Your choice:"),  # This works
                grid = TRUE,
                force_edges = TRUE,
                choices = likert.choices # this doesn't work
            )

The complete code and translation files are pasted below for reference.
Archive.zip

If you could suggest some way of fixing this problem, that would be great!

Cyrillic comes out as unicode

This might be an issue with Shiny/R, rather than this package, sorry if so. I haven't dealt with encoding stuff before so this is all new to me.

I'm trying to translate from English to Russian. I've got the translator working fine when I tested it using the Latin alphabet. However, now that I've loaded in an actual Russian translation CSV, I've got trouble. These six unicode characters should say Привет (hello).

cyrillic text shown as asshole unicode

Is it this package that's showing the unicode, or do you guys know how to show it as Cyrillic?

How using Shiny.i18n for translation of modal dialogue of module 2 which rendered within the server of module 1

I want to translate modal dialogues in my modularized shiny app. As I presented in my reproducible example here, in the first module (register) I have no problem as registerUI() rendered the first modal dialogue and translation works well. But my problem is with the UI of module 2 (M2UI) which this function itself has been called within the server of module 1 (register) to return the second modal dialogue. But i18n probably not detected and translation not works on the displayed new modal. Any suggestions why this happens? thanks in advance.

Translate value in vector

Thank you for development of this package. I am able to successfully use the package, but wonder if I can use the package to translate the values within a vector.

For instance, in the iris dataset, can I add to my JSON file to feed the translations for the values in the Species column?
{
"en": "setosa",
"pl": "setosa_pl",
"hr": "setosa_hr"
},
{
"en": "versicolor",
"pl": "versicolor_pl",
"hr": "versicolor_hr"
},
{
"en": "virginica",
"pl": "virginica_pl",
"hr": "virginica_hr"
}

This would allow the app user to view the name of the Species in their preferred language, if Species were to be plotted as an axis variable.
image

I can't find documentation of this using the i18n package.

Do you suggest using another package for this? Thanks again!

Example of Update_lang for Automatic Translation

Hi there,

I was trying to get the automatic translation to work with the update_lang live example.
Although it is possible to initate the translation, it wont display in labels. working with "i18n$t()" works perfectly fine.

Isit maybe not supported (yet)?

[Bug]: Issue calling update_lang() - order of function arguments

Guidelines

  • I agree to follow this project's Contributing Guidelines.

Project Version

0.3.0

Platform and OS Version

macOS 12.6, Windows10 Pro

Existing Issues

No response

What happened?

My shiny apps broke as result of upgrade in shiny.i18n package from v0.2.0 to 0.3.0. The problem occurs in my server.R
includes an observeEvent for language change which includes a call to this package's update_lang() method. At appears the order of arguments to the function changed between versions 0.2.0 and 0.3.0
the call: update_lang(session, input$lang_pick) # works in v 0.2.0 but breaks in 0.3.0
the call: update_lang(input$lang_pick, session) # works in v 0.3.0 but breaks in 0.2.0

The problem also occurs in your minimal tutorial at:
https://appsilon.github.io/shiny.i18n/articles/basics.html

Steps to reproduce

  1. at your tutorials https://appsilon.github.io/shiny.i18n/articles/basics.html
  2. with shiny.i18n v0.3.0 package installed
  3. select code from section "Live Language Change" "Option b" and paste in an App.R file
  4. create a json translator file. I used the one from the tutorial. In same foldeer as App.R
  5. ** from your tutorial you must change tag "Hello Shiny!" to "Hello" to be same as in the call i18n$t call in App.R
  6. note the call to run the App - it crashes when hit the "Go" button
  7. reverse the arguments in the server function's "update_lang()" call from: update_lang(session, "pl") to update_lang("pl",session)
  8. rerun the application. It should now work properly.
    ...

Expected behavior

Updating the package should not break functionality. Order of arguments or the tutorials and the README notes should be corrected or state the naturre of the breaking change.

Attachments

library(shiny)
library(shiny.i18n)

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

i18n$set_translation_language("en")

ui <- fluidPage(usei18n(i18n),
p(i18n$t("Hello")),
actionButton("go", "GO!")
)

server <- function(input, output, session) {
observeEvent(input$go,{
#update_lang(session, "pl") # tutorial and 0.2.0 code, breaks with 0.3.0
update_lang("pl",session) # works with v 0.3.0, breaks on 0.2.0
})
}

shinyApp(ui, server)

Screenshots or Videos

No response

Additional Information

No response

[Bug]: The website in the README does not work

Guidelines

  • I agree to follow this project's Contributing Guidelines.

Project Version

0.2.1

Platform and OS Version

No response

Existing Issues

No response

What happened?

The demo link in the readme file does not work. The URL is https://demo.appsilon.ai/apps/i18n/

It gets redirected to https://legacy.appsilon.com/apps/i18n/ and I get -

image

Steps to reproduce

  1. Click on the See shiny.i18n in action live

Expected behavior

Site should be working and reachable.

Attachments

No response

Screenshots or Videos

No response

Additional Information

No response

UTF encoding and special characters during golem deployment

Hi Appsilon developers!
I built an app using golem because I hope to publish it as an R package.

I am using live translation in the app via radioButtons. The .json file with my translations contains special characters. When I deploy the app from the R package to shinyapps.io , the version that publishes to the server does not display these special characters at all (notice how the í is missing from "vaya aquí"):
Screen Shot 2021-08-25 at 6 18 15 PM

Special characters included in the app_ui.R file render as UTF on the server:
Screen Shot 2021-08-25 at 6 17 26 PM

I am not sure if this is a golem issue or a shiny.i18n issue, but I am posting here because I am guessing other shiny.i18n users have similar issues. I have to keep both types (the .json contents and the in-app special characters) in order to allow translation for the radioButton options and the plots.

Here is the repo for the R package (everything works perfectly when the app is deployed from the package): https://github.com/mcsiple/mmrefpoints
Here is the server version that deploys automatically when I use golem::add_shinyappsio_file(); rsconnect::deployApp():
https://msiple.shinyapps.io/mmrefpoints/

If I should post this on the golem github page instead, just let me know. And thank you in advance for your help.

[Bug]: Translator cannot deal with sentences starting with the same string.

Guidelines

  • I agree to follow this project's Contributing Guidelines.

Project Version

No response

Platform and OS Version

Windows 10

Existing Issues

No response

What happened?

I have a translation file in which many sentences start with the same words. This causes an error in which duplicate rownames are generated (unclear where) and the translation stops (see below). Presumably this is because the first word is stored as rowname of the DF.
Most likely culprit:

column_to_row <- function(data, colname) {
  stopifnot(colname %in% colnames(data))
  key_index <- which(colname == colnames( (data) ))
  ndata <- data[-key_index]
  rownames(ndata) <- data[, key_index]
  ndata
}

Steps to reproduce

  1. Make translation CSV file with different rows starting with the exact same character.
  2. Run serverside translation workflow:
    translator <- Translator$new(translation_csvs_path = "./inst/extdata/")
  3. Following error is generated:
Error in `.rowNamesDF<-`(x, value = value) : 
  duplicate 'row.names' are not allowed
  1. When you remove the sentences starting with the same strings, the error is resolved.

Expected behavior

Text should be translated without triggering the error.

Attachments

No response

Screenshots or Videos

No response

Additional Information

No response

Allow translating vectors

It would improve the usage a lot if we could pass vectors of keys to the translator.
An example:

i18n$t(c("key1", "key2"))

could return:

[1] "Key one" "Key two"

[Bug]: Unable to install dev version from github

Guidelines

  • I agree to follow this project's Contributing Guidelines.

Project Version

No response

Platform and OS Version

Ubuntu 22.04

Existing Issues

No response

What happened?

When trying to install the developer version from github via

devtools::install_github("Appsilon/shiny.i18n")

the installation process stops with an error that it cannot open a shared object file libicui18n.so.66 (see attachment for full error message).

Might be a library mismatch of libicu?

Steps to reproduce

  1. devtools::install_github("Appsilon/shiny.i18n")

Expected behavior

successful installation

Attachments

Error in dyn.load(file, DLLpath = DLLpath, ...) :
unable to load shared object '/home/USER/R/x86_64-pc-linux-gnu-library/4.2/stringi/libs/stringi.so':
libicui18n.so.66: cannot open shared object file: No such file or directory
Calls: ... namespaceImport -> loadNamespace -> library.dynam -> dyn.load
Execution halted

Screenshots or Videos

No response

Additional Information

OS: Ubuntu 22.04
R Version: 4.2.1

$ apt list --installed | grep libicu

libicu-dev/jammy,now 70.1-2 amd64 [installed,automatic]
libicu70/jammy,now 70.1-2 amd64 [installed,automatic]

How to translate selectInput ? Getting error names vector error

Hello! I wanna translate selectInput in my shiny app,but guess i18n$t('my text for translate') is returning list with 3 elements theregore i am getting error in 'choices' pls help. Tried setNames no result.
Code example is below
tabsetPanel(id = "tabs", type = "tabs",
tabPanel(i18n$t("Population density and ethnic composition of the population"),value = 1,
selectInput(
inputId = "variant1",
label = "",
width = "500px",
choices =setNames(c('pdregion'),i18n$t("Population density of the region"))
)),

[Feature]: Add support for translations of shinyBS collapse panels

Guidelines

  • I agree to follow this project's Contributing Guidelines.

Description

Elements such as the bsCollapsePanel from the shinyBS library are frequency used to organize UI controls. As such, for international applications, being able to translate all elements in a UI is critical.

Problem

As currently implemented, translation cannot be directly enabled for the bsCollapsePanel since it doesn't appear to expose the appropriate data context for the shiny.i18n library to access. A work around is possible as demonstrated in the Proposed Solution, which suggests that it is is likely possible to add a cleaner (e.g., shiny.i18n::translate_panels(i18n) function call or the like) version to the library.

Proposed Solution

The following snippet enables translation of bsCollapsePanel elements:

# Add the i18n class and translation key to the bsCollapsePanel
HTML('
<script>
$(document).on("shiny:sessioninitialized", function(event) {
  $("a[id^=\'ui-collapse\']").each(function() {
    $(this).addClass("i18n");
    $(this).attr("data-key", $(this).text());
  }); 
});
</script>'),

Alternatives Considered

I've actually added the above code snippet to our own application, so the support is already present. Formalizing it as part of the shiny.i18n library would just make this more accessible to others for use.

Compatibility with selectInput

Does shiny.i18n have compatibility with selectInput? Here I have an example where the label choices and values are different:

selectInput(ns('label_id'), label=i18n$t('My label'), choices=c(i18n$t('Transformers') = 'Transformere', i18n$t('Cable closets') = 'Kabelskabe'), selected = c('Transformers','Cable closets'), multiple = T, selectize = TRUE)

It throws a poorly defined error at the equal sign in the first choice/value equal sign in i18n$t('Transformers') = 'Transformere'. Is there a work around for this?

Document configuration file feature for CSV

  1. Configuration YAML file usage for CSV type of translation file must be documented.
  2. Translator should emit information instead of a warning when using default values for the configuration.

Issues : "Error in multmerge" - HELP

Good morning, I am quite new in using R and R shiny. I am trying to create an app and to give the possibility to change the language using the shiny.i18n package. I have created a csv file as mentioned in the vignette, with 2 columns (1 for english and 1 for italian) but as I run the script it gives me this error:
Warning in load_local_config(translation_csv_config) : You didn't specify config translation yaml file. Default settings are used. Error in multmerge(all_files, sep) : Key translation is not the same in all files.

Here i post all the code:

rm(list=ls())

library(ecmwfr)
library(keyring)
library(shiny)
library(shinyalert)
library(shinyFiles)
library(stringr)
library(ncdf4)
library(devtools)
library(usethis)
library(foreMast)
library(shiny.i18n)

tr <- Translator$new(translation_csvs_path = "C/Users/Seba/Progetti_gitLab/aforclimate/C4/test_pasciona/www/")
tr$set_translation_language("en")

ui <- fluidPage(
  shiny.i18n::usei18n(tr),
  div(style = "float: right;", 
      selectInput('selected_language',
                  tr$t("Change language"),
                  choices = tr$get_languages(),
                  selected = tr$get_key_translation())
  ),
  
  titlePanel(
    h1(strong(tr$t("Forecast of seed production of "), em("Fagus sylvatica L."), tr$t(" in the current year")), align = "center")
  ),
  sidebarLayout(
    sidebarPanel(
      fluidRow(
        style = "background-color:#ccffcc;",
        style = "border: 2px black;",
        h2(strong(tr$t("Climatic data download"))),
        h3(tr$t("1-Registration to the Copernicus CDS service and login")),
        p(tr$t("To access to the service it is necessary to register at the following "), 
          a(tr$t("site"), href = "https://cds.climate.copernicus.eu/user/register?destination=%2Fcdsapp%23!%2Fhome"),
          tr$t(" and login")),
        h3(tr$t("2-Creation of the query")),
        p(tr$t("To obtain the file, it is necessary to go on the download  "), 
        a(tr$t("page"), href = "https://cds.climate.copernicus.eu/cdsapp#!/dataset/reanalysis-era5-land-monthly-means?tab=form"), 
        tr$t("of the ERA 5 dataset and select the following parameters: ")),
        h4("a) ", strong("Product type")),
        p("'Monthly averaged reanalysis'", style = "color:red"),
        h4("b) ", strong("Variable")),
        p(strong("Temperature: ")), p("'2m temperature'", style = "color:red"),
        p(strong("Wind, Pressure and Precipitation: ")), p("'Total precipitation'", style = "color:red"),
        h4("c) ", strong("Year")), p(tr$t("Select all the available years"), style = "color:red"),
        h4("d) ", strong("Month")), p(tr$t("Select all the available months"), style = "color:red"),
        h4("e) ", strong("Time")), p(tr$t("Select the only available time ('00:00')"), style = "color:red"),
        h4("f) ", strong("Geograpichal area")),
        p("'Sub-region extraction'", style = "color:red"), p(tr$t("Insert the coordinates (lat, lon) of the interested location in the specific spaces. "),
        strong(tr$t("IMPORTANT")),tr$t(": insert two decimal digits, with the first one being the same as that of the opposite direction (eg. North: 43.87, East: 12.02, South: 43.86, West: 12.01) using the minus sign for sites under the equator and west to the meridian ‘0’")),
        h4("g) ", strong("Format")), p("'NetCDF (experimental)'", style = "color:red"), 
        h4(tr$t("Click on "), strong("Submit Form")),
        h3(tr$t("3-Data download")),
        p(tr$t("Once the form has been sent, you will be redirected on the "), 
          a(tr$t("page"), href = "https://cds.climate.copernicus.eu/cdsapp#!/yourrequests?tab=form"),
          tr$t(" where the product will be available clicking on the "), strong("'Download'"), 
          tr$t(" button, as soon as the queue time has been accomplished ('Status = Queued)'")),
      ),
      fluidRow(br()),
      fluidRow(
        style = "background-color:#ccffee;",
        style = "border: 2px black;",
        h2(strong(tr$t("Climatic data upload and seed production calculation"))),
        p(tr$t("Upload the "), strong(".nc"), tr$t("file and click on "), strong(tr$t("Chart")), 
          tr$t("to generate the probability chart")),
        fileInput("upfile", tr$t("Choose a file .nc"),
                  multiple = FALSE,
                  accept = c(".nc")),
        actionButton("submit", label = strong(tr$t("Chart")), 
                     style="color: white; background-color: #3385ff; position: relative; left: 41%")
      )
    ),
    mainPanel(
      plotOutput("plot")
    )
    )
  )

server <- function(input, output, session) {
  
  observeEvent(input$selected_language, {
    # This print is just for demonstration
    print(paste("Language change!", input$selected_language))
    # Here is where we update language in session
    shiny.i18n::update_lang(session, input$selected_language)
  })
  
  # upload del file .nc
  observeEvent(input$submit, {
    file <- input$upfile
    filename <- gsub("\\\\", "/", file$datapath)
    output$plot<- renderPlot({
      probPlot(mastFaSyl(fName = filename,  weighting = "standard"))
      })
    })
  }

# Run the app
shinyApp(ui, server)

I really hope that someone could give me a hint about to solve this issue. Thanks in advance!!

[Bug]:

Guidelines

  • I agree to follow this project's Contributing Guidelines.

Project Version

No response

Platform and OS Version

No response

Existing Issues

No response

What happened?

When calling: Translator <- Translator$new(translation_csvs_path = "./data", separator_csv="|")
throws warning

"Warning in load_local_config(translation_csv_config) :
You didn't specify config translation yaml file. Default settings are used."

I can find nothing in code or in your project examples regarding the yaml cfg.

Please describe a correct correct yaml config file.
Also please describe how to correctly 'specify'
Also related, there is nothing in the docs regarding the "default settings" are...

Steps to reproduce

1.run your demo project.
2.observe in console: Warning in load_local_config(translation_csv_config) :
You didn't specify config translation yaml file. Default settings are used.
...

Expected behavior

No warnings

Attachments

No response

Screenshots or Videos

No response

Additional Information

No response

Translating tooltips

Great tool! I am using the tool to do client side translations as server side translations are quite slow in my case. However, since you wrap everything in a span that needs to be translated I could not figure out a way to translate tooltips on the client side. Do you have any recommendations for that? If it is not possible can I mix client side and server side translations? So only the tooltips would be handled on the server side. Thanks!

showModal on load crashes app

Hi there,

I've been using the shiny.i19n package (v0.1.0) to translate the app into multiple languages.
However, after updating to v0.2.0 translations in a modal (that is shown once loading the app is finished) causes my app to crash.
My app needs to shows a tutorial modal once the app is loaded. Any advice?

See my minimal, reproducible example below:

Works in v0.1.0 not in v0.2.0:

library(shiny)
library(shiny.i18n)

l <- Translator$new(translation_json_path = "www/translations.json")
l$set_translation_language("de")

ui = basicPage(
	actionButton("show", "Show modal dialog")
)

server = function(input, output) {
	
	dataModal <- function() {
		showModal(modalDialog(
			textInput("dataset", 
								# "Choose data set", 
								l$t("Choose data set"),
								placeholder = 'Try "mtcars" or "abc"'
			),
			
			footer = tagList(
				modalButton("Close")
			)
		))
	}
	
	# Show modal when app is loaded
	dataModal()
	
	# Show modal when button clicked
	observeEvent(input$show, {
		dataModal()
	})
	
}
shinyApp(ui, server)

Gives error:

48: dataModal [/home/shinyuser/nccs/nccs_wp2/dev/test.R#14]
47: server [/home/shinyuser/nccs/nccs_wp2/dev/test.R#28]
Error in .getReactiveEnvironment()$currentContext() :
Operation not allowed without an active reactive context. (You tried to do something that can only be done from inside a reactive expression or observer.)

shiny.i18n appears to not handle backslash properly

I'm using shiny.i18n to create multilang PDFs with knitr and LaTeX.

Using double-backslash for markup in i18n-translated strings results in the key not being recognized anymore.

Example:
i18n$t("One \\& Two")

1: In private$raw_translate(keyword) :
  'One \& Two' translation does not exist.

translate-de.csv:

en,de
"One \\& Two","Eins \\& Zwei"

CVE-2020-11023 (Medium) detected in jquery-3.4.1.min.js - autoclosed

CVE-2020-11023 - Medium Severity Vulnerability

Vulnerable Library - jquery-3.4.1.min.js

JavaScript library for DOM operations

Library home page: https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js

Path to dependency file: /docs/reference/save_to_csv.html

Path to vulnerable library: /docs/reference/save_to_csv.html

Dependency Hierarchy:

  • jquery-3.4.1.min.js (Vulnerable Library)

Found in HEAD commit: 6b2e254700f0cad98b0de1c6391a4e02012fc98e

Found in base branch: master

Vulnerability Details

In jQuery versions greater than or equal to 1.0.3 and before 3.5.0, passing HTML containing elements from untrusted sources - even after sanitizing it - to one of jQuery's DOM manipulation methods (i.e. .html(), .append(), and others) may execute untrusted code. This problem is patched in jQuery 3.5.0.

Publish Date: 2020-04-29

URL: CVE-2020-11023

CVSS 3 Score Details (6.1)

Base Score Metrics:

  • Exploitability Metrics:
    • Attack Vector: Network
    • Attack Complexity: Low
    • Privileges Required: None
    • User Interaction: Required
    • Scope: Changed
  • Impact Metrics:
    • Confidentiality Impact: Low
    • Integrity Impact: Low
    • Availability Impact: None

For more information on CVSS3 Scores, click here.

Suggested Fix

Type: Upgrade version

Origin: https://github.com/jquery/jquery/security/advisories/GHSA-jpcq-cgw6-v4j6,https://github.com/rails/jquery-rails/blob/master/CHANGELOG.md#440

Release Date: 2020-04-29

Fix Resolution: jquery - 3.5.0;jquery-rails - 4.4.0


Step up your Open Source Security Game with Mend here

Feature request: Build .json skeleton from app.R

Hi Appsilon folks! First of all, thank you for making this awesome package. I'm currently using it and it's making my life SO much easier!

One thing that would be really convenient for larger apps would be a function that builds a .json file based on the text labels in a shiny app. I am plugging away but find myself typing a lot of {"en": "", "es": ""} by hand in translation.json.

One way to do this might be for everything wrapped in i18n$t() within the Shiny app file to be automatically exported to a .json file with the "en" (or other default language) text already populated. I'm imagining a function that takes an app.R file, the languages the user will use in the translation, and writes a .json file to which you could add the translated text.

update_lang won't work inside of a shiny module

I have tried and tried to work around this problem but I can't seem to get it figured out. The update_lang() function works in a simple app without modules, but if I put it in my large app or just simple modules, the update fails to perform. I've included a reproducible chunk below where the button label will update, but the translation won't fire. Could you have a look and see if you can find any workarounds?
Thanks,
Ty

library(shiny)
library(shiny.i18n)

i18n <- Translator$new(translation_json_path = "translation.json")
i18n$set_translation_language("fr")

languageButton_UI <- function(id, i18n) {
ns <- NS(id)
tagList( usei18n(i18n), actionButton(ns("go"), "English"), h2(i18n$t("Hello Shiny!"))
)
}

languageButton_Server <- function(id, i18n) {
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 = "Français")
        update_lang(session, "en")  # This line is not updating properly in module
      } else {
        updateActionButton(session, "go",
                           label = "English")
        update_lang(session, "fr") # This line is not updating properly in module
        }
    })
  }
)

}

ui <- fluidPage(
languageButton_UI("language_button", i18n = i18n)
)

server <- function(input, output, session) {
languageButton_Server("language_button", i18n = i18n)
}

shinyApp(ui, server)

reverseTranslation - function request

Hi,
thanks for providing the package.

I stumbled into a problem in cases where the interface defines backend behavior.
In my case I had a list of items with https://shiny.rstudio.com/articles/selectize.html
Depending on what a user selects, the backend calculation changes.
So it would be great to translate what users can select, however as the translated items end in the backend they need to be stable. (e.g. the translation key).

A solution would be to provide a reverseTranslation function:

reverseTranslation(interfaceName="FB", currentLang="en"){
  dff <- i18n$get_translations()
  
  dfff <- dff[dff[,currentLang]==interfaceName,]
  return(row.names(dfff[!is.na(dfff[,currentLang]),]))
}

version 0.1.0 is not available?

devtools::install_github("Appsilon/shiny.i18n", ref = "0.1.0")
Error: Failed to install 'unknown package' from GitHub:
HTTP error 404.
No commit found for the ref 0.1.0

Did you spell the repo owner (Appsilon) and repo name (shiny.i18n) correctly?

  • If spelling is correct, check that you have the required permissions to access the repo.

extract_key_expressions regexp appears to not being able to handle parantheses.

I use shiny.i18n to create multilang PDFs using knitr and LaTeX.

To extract the translation keys I use preproc::create_translation_file().

When looking at the generated file, strings which include parentheses ")" are cut off directly after the closing parenthesis.

My guess is that some regexp in extract_key_expressions() just checks for the first closing parenthesis it encounters, instead of balancing them.

In my case actually it would suffice to ignore parentheses inside quotation marks, since all my translations look like this i18n$t("").

[Bug]: Problem in the uiOutput and renderUI in modules

Guidelines

  • I agree to follow this project's Contributing Guidelines.

Project Version

0.2.1

Platform and OS Version

Windows 10 x64

Existing Issues

#48 #62

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

[Bug]: Items inside header and sidebar of {shinydashboard} are not translated with {shiny.i18n}

Cross-posted from StackOverflow (https://stackoverflow.com/questions/73509710/items-inside-header-and-sidebar-of-shinydashboard-are-not-translated-with-shi).

Guidelines

  • I agree to follow this project's Contributing Guidelines.

Project Version

0.2.0

Platform and OS Version

macOS 12.3.1, R 4.2.1, RStudio 2022.07.1

Existing Issues

No response

What happened?

When using {shiny.i18n} for live language translations in an {shinydashboard} app, the contents inside dashboardHeader() and dashboardSidebar() are not translated. Contents inside dashboardBody() are translated though.

Steps to reproduce

In the sample app below, the title of the Dashboard ("Basic dashboard") and the two menu items ("Dashboard Tab" and "Widgets Tab") are all wrapped in the i18n$t() function, with traditional Chinese translation (zh) provided in translation_zh.csv.

  1. Run the sample application below with shiny::runApp()
  2. Click on the "change language" dropdown list created from shiny.i18n::usei18n(i18n)
  3. Change the language from en to zh

Expected behavior

When the user changes the language from en to zh, the text of the menu items and dashboard title do not change. Meanwhile, other items inside dashboardBody() (e.g. "Number of observations:") are successfully translated.

The title (i18n$t("Basic dashboard")) and menu items (i18n$t("Dashboard Tab") and i18n$t("Widgets Tab")) will change from English to the respective traditional Chinese language word after changing the language.

Attachments

The app code is merged from the sample app of {shinydashboard} and sample app of {shiny.i18n}.

app.R

library(shiny)
library(shinydashboard)
library(shiny.i18n)

# File with translations
i18n <- Translator$new(translation_csvs_path = "data/")
i18n$set_translation_language("en") # here you select the default translation to display

ui <- dashboardPage(
  dashboardHeader(title = i18n$t("Basic dashboard")),
  dashboardSidebar(
    sidebarMenu(
      menuItem(i18n$t("Dashboard Tab"), tabName = "dashboard", icon = icon("dashboard")),
      menuItem(i18n$t("Widgets Tab"), tabName = "widgets", icon = icon("th"))
    )
  ),
  ## Body content
  dashboardBody(
    tabItems(
      # First tab content
      tabItem(tabName = "dashboard",

              shiny.i18n::usei18n(i18n),
              div(style = "float: right;",
                  selectInput('selected_language',
                              i18n$t("Change language"),
                              choices = i18n$get_languages(),
                              selected = i18n$get_key_translation())
              ),

              fluidRow(
                box(plotOutput("plot1", height = 250)),

                box(
                  title = i18n$t("Controls"),
                  sliderInput("slider", i18n$t("Number of observations:"), 1, 100, 50)
                )
              )
      ),

      # Second tab content
      tabItem(tabName = "widgets",
              h2(i18n$t("Widgets tab content"))
      )
    )
  )
)

server <- function(input, output, session) {

  observeEvent(input$selected_language, {
    # This print is just for demonstration
    print(paste("Language change!", input$selected_language))
    # Here is where we update language in session
    shiny.i18n::update_lang(session, input$selected_language)
  })

  set.seed(122)
  histdata <- rnorm(500)

  output$plot1 <- renderPlot({
    data <- histdata[seq_len(input$slider)]
    hist(data)
  })
}

shinyApp(ui, server)

data/translation_zh.csv

en,zh
Widgets tab content,內容
Change language,更換語言
Controls,控制台
Number of observations:,觀察數量
Basic dashboard,基本儀表版
Dashboard Tab,儀表版
Widgets Tab,部件

Screenshots or Videos

Default view

After selecting zh as the language

Screen recording

Additional Information

I am also not sure if this issue should be posted here or on the repo of {shinydashboard}. Feel free to close this issue if this issue is related to {shinydashboard} instead of {shiny.i18n}.

Error load_local_config function

I'm trying to call the load_local_config function to load the configuration file, but it throws an error, it can't find it. What is the correct way to call this function?
`
library(shiny)
library(shiny.i18n)
load_local_config("../../config.yaml") # Throw error, not found
ui <- shinyUI(fluidPage(
......
))
translator <- Translator$new(translation_csvs_path = "../data")

server <- shinyServer(function(input, output, session) {
......
})
`

Values reset in live language change example

I noticed today that in live_language_change example when you change the language, the slider input values reset as well. Ideally they would stay the same. Not sure how to fix it though.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.