语言转换使用文档

前言

上次开会跟师兄提了一嘴语言转换的适用性之后,这周便撰写了一篇使用文档,想着诶这篇文档也可以更新到博客上来遂更新……

shiny.i18n的使用其实最好是项目创建一开始便同步进行,这样对重复性的文本翻译工作会比较友好,如果等全部代码都写完了再补充上语言转换,那么一个个去定位翻译文本是很费精力的一件事……

安装与加载

install.packages("shiny.i18n")
library(shiny.i18n)

参考文档:https://appsilon.github.io/shiny.i18n/index.html

具体操作步骤

1.翻译文本准备

在根目录创建名为“translations.json”的json文件如图,这份文件的内容就是全部的翻译文本

image-20250517225426447

2.JSON端

使用代码编辑器打开(如VS code)

翻译文件代码格式如下:

{
    "languages": ["key", "en", "cn", "jp"],         //请不要修改key,不然会报错,其他语言代码id无所谓
    "translation": [
      {
        "key": "app_title",
        "en":  "Sample Size Calculation Tool",
        "cn":  "样本量计算工具",
        "jp":  "サンプルサイズ計算ツール"
      },
      {
        "key": "btn_calc",
        "en":  "Calculate Sample Size",
        "cn":  "计算样本量",
        "jp":  "サンプルサイズ計算"
      },
      {
        "key": "lang_en",  "en": "English",   "cn": "英文", "jp": "英語"
      },
      {
        "key": "lang_cn",  "en": "Chinese",   "cn": "中文", "jp": "中国語"
      },
      {
        "key": "lang_jp",  "en": "Japanese",  "cn": "日语", "jp": "日本語"
      },
      {
        "key": "tab_home",
        "en" : "Home",
        "cn" : "首页",
        "jp" : "ホーム"
      },
      {
        "key": "tab_guidance",
        "en" : "Guidance",
        "cn" : "向导",
        "jp" : "ガイダンス"
      }
        
      //以此类推,把全部翻译文本都填充进来就好,这部分工作可以交给ai来做更快捷轻松
        
        
        
            ]
  }

其中“key”表示的是id,“en”“cn”“jp”则是不同的语言文本

3.全局设置(即需作用于UI和Server)

在app代码之前位置添加下述代码:

i18n <- Translator$new(translation_json_path = "translations.json")
i18n$set_translation_language("en")

加载翻译文本以及确定默认语言

4.配置一个或多个语言切换器

这里展示若有多个选择器的状态下,该如何同步设置,如果只需要单个选择器就不用这么复杂,只需要单向追踪observeEvent即可

#UI
##这里配置的是在右上角设置一个下拉式语言选择框,我们叫他lang_top
tags$div(
    id    = "lang_switcher_fixed",
    style = "position: fixed; top: 10px; right: 20px; width: 130px; z-index: 3000;",
    selectInput(
      inputId  = "lang_top",
      label    = NULL,                  
      choices  = c("中文" = "cn",
                   "English" = "en",
                   "日本語" = "jp"),
      selected = "en",                   # 先给个默认值;后面 server 会同步
      width    = "100%"
    )
  )

#假如其他地方还有另外的选择框或按钮分别对应lang_en->en;lang_cn->cn;lang_jp->jp

5.替换所有的标签文本为i18n$t()

将全部标签语言都替换成对应json文件的key也就是i18n$t()即可

示例1

旧:

#这是一段长文本
tags$p("Usage: Fill in values like alpha, power, effect size or standard deviation, and choose alternative hypothesis. Click 'Calculate Sample Size'. Power curves will be displayed.")

新:

tags$p(i18n$t("Usage"))

这里的“Usage”就是json文件中每一段翻译文本对应的“key”

如果文本是在函数中或者server代码中,也可以使用这种方法替换,不过有些函数不太支持,这个得自己去摸索

示例2
output$sidebar_instructions <- renderUI({ 
    req(input$myInnerTabs) 
    
    if (input$myInnerTabs == "Home") {
      tagList(
        h4(i18n$t("sidebar_home_h4")),
        tags$p(i18n$t("sidebar_home_p1")),
        tags$p(i18n$t("sidebar_home_p2")),
          ···
          #以下省略

6.Server端(多选择框同步)

如果不需要多选择框,那么只用直接更新对应的i18n$set_translation_language即可

#server

# 确定当前语言(也就是默认语言),这也是一个统一的出口,以便不同选择框能够同步
  lang_r <- reactiveVal("en")


# 当其他地方按钮被点时 → 改 reactiveVal
  observeEvent(input$lang_en, {
    lang_r("en")
  })
  observeEvent(input$lang_cn, { lang_r("cn") })
  observeEvent(input$lang_jp, { lang_r("jp") })

# 当lang_top改变时 → 改 reactiveVal(可以用req()作为双重保险)
  observeEvent(input$lang_top, {
    req(input$lang_top)
    lang_r(input$lang_top)
  }, ignoreInit = TRUE)

# 统一出口:只要 lang_r() 变 → 更新 i18n、前端文本、以及其余选择控件
  observeEvent(lang_r(), {
    cur <- lang_r()
    i18n$set_translation_language(cur)
    update_lang(cur, session) # 即时切换所有 i18n$t()
    updateSelectInput(session, "lang_top", selected = cur)
  })#这里就同步下拉框lang_top选中项,如果还有其他的也可以继续添加

完成

完成以上步骤后,就可以快速进行语言转换了,这样子虽然会比网页机翻麻烦不少,但是翻译的效果是有保证的,并且因为加载的是本地资源,响应也是极快的。

改进

实际上理应有更方便的方法,但是目前shiny能支持的方法我只摸索出了这一个,感觉这是一个可以用脚本高效解决的问题。还是得多多学习……

我在不少博客中也看到了多语言转换的功能,用的也都是i18n,但是不知道具体在博客上该怎么去进行,是自己写完一篇文章便自动翻译并加载到本地还是得提供两份文本预加载……感觉后者对于博客更新来讲有点过于麻烦了,但是看不少博客的语言转换翻译都特别精美不像是机翻,所以感觉很厉害。

最后修改:2025 年 05 月 18 日
如果觉得我的文章对你有用,请随意赞赏
正文到此结束
本文作者: 文章标题:如何让你的R shiny app变得更加国际化
本文地址:https://david03.top/index.php/archives/241/
版权说明:若无注明,本文皆 Davidの3号基地 原创,转载请保留文章出处。