为主题和主题组件添加可本地化字符串

对于希望为 Discourse 主题或主题组件添加自定义语言和翻译的用户,现在可以包含本地化字符串,这些字符串可供 UI 组件使用。翻译文件的存储格式与核心/插件翻译相同,使用方法也几乎一致。

主题可以提供格式如 /locales/{locale}.yml 的翻译文件。这些文件必须是有效的 YAML 格式,且顶层键名应等于所定义的本地化语言代码。这些文件可以通过 discourse_theme 命令行工具定义,也可以从 .tar.gz 文件导入、从 GIT 仓库安装,或通过 theme-creator.discourse.org 上的编辑器进行配置。

一个示例本地化文件可能如下所示:

en:
  theme_metadata:
    description: "这是我对主题的说明"
    settings:
      theme_setting_name: "这是对设置 `theme_setting_name` 的说明"
      another_theme_setting_name:
        description: "这是对设置 `another_theme_setting_name` 的说明"
  sidebar:
    welcome: "欢迎"
    back: "返回"
    welcome_subhead: "我们很高兴您来到这里!"
    likes_header: "分享喜爱"
    badges_header: "您的顶级徽章"
    full_profile: "查看您的完整个人资料"

管理员可以在 /admin/customize/themes 用户界面中按主题单独覆盖各个键。回退机制与核心翻译处理方式相同,因此非英语语言即使翻译不完整也可以正常使用,系统将自动回退到英语键值。

在后台,这些翻译与核心翻译一起存储,位于特定于主题的命名空间下。例如:

theme_translation.{theme_id}.sidebar.welcome

您不应在主题代码中硬编码 theme_id。要动态构建翻译键,请使用 themePrefix 辅助函数:

import { i18n } from "discourse-i18n";
import { themePrefix } from "virtual:theme";

// 在 JS 代码中:
const result = i18n(themePrefix("my_translation_key"));
console.log("来自 JavaScript", result);

// 在模板标签中:
<template>{{i18n (themePrefix "blah")}}</template>

有关在主题中使用翻译的完整示例,请查看 @awesomerobot 的 Fakebook 主题:GitHub - discourse/Fakebook · GitHub


本文档已进行版本控制,如有修改建议,请在 GitHub 上提交

32 个赞

如何在 CSS 中使用主题翻译?我知道可以使用主题参数,但我需要主题翻译。

不行,它们仅在模板和 JavaScript 中可用。这与核心/插件翻译相同。

理想情况下,请重构代码,将字符串设置在模板中。但如果你确实需要在 CSS 文件中自定义字符串,可以使用主题设置:Developing Discourse Themes & Theme Components

1 个赞

如果我使用主题设置,可以翻译它吗?

不,不是翻译成多种语言,而是允许管理员为他们的网站进行自定义。

2 个赞

大家好。
我正在重新定义模板 upload-selector.hbs
我想添加一个可翻译的短语。
我创建了一个新变量 upload_selector.upload_images
例如

请告诉我接下来该怎么做?

你好,

当我在 Discourse 主题创建器中尝试此技术时(参见此处),一切运行正常,与帖子中的说明一致。

然而,如果我将完全相同的主题导入到自己的服务器上,仅显示“[en.theme_translations.12.blog]”。此外,在主题设置页面中也没有像主题创建器中那样的“主题翻译”部分。

我真的不知道该去哪里查找这个错误了。有人能给我一些提示吗?

[编辑]
我正在 Docker 环境中使用 Discourse 2.6.7 ( [f73cdbbd2f] )。

你能更新 Discourse 吗?

你使用的是旧版本。

是的,我正在尝试这样做。这也是我需要帮助的另一件事,但我不想在这里发布,那将是另一个话题。

无论如何,我以为这不应该是个问题,因为翻译功能已包含在版本 2.2.0.beta9 中,请参阅 提交记录

你好,提前为我的新手问题道歉。
我用纯 HTML 和 CSS 创建了一个标题

        <div>
         <span><a href="https://www.example.com/download">Download</a></span>     
        </div>

然后我想翻译“Download”这个词
我创建了英文翻译文件

en: 
  top-navbar: 
    download: "Yeah"

然后我像 Facebook 示例一样更改了 HTML 代码


    <script type="text/x-handlebars" data-template-name="/connectors/discovery-below/sidebar">
        <div class="top-navbar">
         <span class="j_menu_item" ><a href="https://www.example.com/download">{{i18n (theme-prefix "top-navbar.download")}}</a></span>     
        </div>
    </script>

这会翻译并打印“Yeah”,但会破坏我的布局,我猜是因为我使用了“/connectors/discovery-below/sidebar”。我只想应用我的翻译而不修改任何模板,但我不知道如何仅内联应用翻译。

你能否提供一个简单的示例来说明如何在主题的自定义 HTML 中仅使用翻译?

谢谢!

你好,

问题是 data-template-name 应该是一个唯一的名称。Developing Discourse Themes & Theme Components sidebar 这个名称,我认为这会覆盖 Facebook 的侧边栏模板。

例如,这应该可以工作 :slightly_smiling_face:

<script type="text/x-handlebars" data-template-name="/connectors/discovery-below/downloadlink">
  <div class="top-navbar">
    <span class="j_menu_item" ><a href="https://www.example.com/download">{{i18n (theme-prefix "top-navbar.download")}}</a></span>     
  </div>
</script>
2 个赞

感谢 @Don

我忘了提插件没有安装,并且我已经尝试将 data-template-name 更改为随机的 UNIQUE-NAME,结果相同,或者如果我编造了 PLUGIN-OUTLET-NAME,我的横幅根本不显示。
你现在可能已经看出来了,我对 handlebars/ember 完全不熟悉 :slight_smile:
我的理解是,我正在自定义一个在 html 中有预定义位置的模板,结果是自定义的 html 不再位于 /html/body/section main,而是深埋在里面,导致了我以前没有的 CSS 继承。
我不明白为什么我需要自定义任何模板来使用翻译……
我设法使用 Ember inspector 识别了要自定义的模板,正如这里建议的那样。
感谢你的回答和关于 plugin-outlet 的链接,我找到了正确的 data-template-name=“/connectors/above-site-header/my-navbar”
再次感谢你的帮助

1 个赞

哦,我明白了……我以为你在使用 Fakebook 主题,想把你的代码放在侧边栏的下面。:slightly_smiling_face:

要直观地查看插件出口,一个好方法是使用 插件出口位置 主题组件。

2 个赞

你好 @Don

我之所以使用那个 Facebook 示例,是因为:

再次感谢!

关于单数和复数,如何使用 {{theme-i18n}} 翻译具有一个和多个翻译的文本?例如,“Result”和“Results”。

2 个赞

在 Discourse 的源代码中,我们通常有两个字符串,并根据整数进行切换:

Screenshot 2022-12-15 at 5.42.58 PM

这在主题中也应该有效,通常 JavaScript 会是这样的:

I18n.t(themePrefix("confirm_remove_tags"), {
  count: exampleCountValue,
});
1 个赞

关于 hbs,它可以在 hbs 模板中完成吗?

1 个赞

是的,它可以:

{{theme-i18n "confirm_remove_tags" count=this.exampleCountValue}}
4 个赞

当我在主题中的 .gjs 组件模板中这样做时,我会得到:

Error: Attempted to resolve a helper in a strict mode template, but that value was not in scope: theme-prefix

所以我尝试导入它:

import themePrefix from "discourse/helpers/theme-prefix";

但是它抱怨:

Identifier 'themePrefix' has already been declared

(我在“hub”上找了一个例子,但似乎没有)

1 个赞

更新:您需要使用 {{i18n (themePrefix "

4 个赞