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

For those looking to add custom languages and translations to a Discourse theme or theme component, they can now include localised strings, which are made available for use in UI components. Translations are stored in the same format as core/plugin translations, and can be used in almost the same way.

Themes can supply translation files in a format like /locales/{locale}.yml. These files should be valid YAML, with a single top level key equal to the locale being defined. These can be defined using the discourse_theme CLI, importing a .tar.gz, installing from a GIT repository, or via the editor on theme-creator.discourse.org.

An example locale file might look like

en:
  theme_metadata:
    description: "This is a description for my theme"
    settings:
      theme_setting_name: "This is a description for the setting `theme_setting_name`"
      another_theme_setting_name:
        description: "This is a description for the setting `another_theme_setting_name`"
  sidebar:
    welcome: "Welcome"
    back: "back,"
    welcome_subhead: "We're glad you're here!"
    likes_header: "Share the Love"
    badges_header: "Your Top Badges"
    full_profile: "View your full profile"

Administrators can override individual keys on a per-theme basis in the /admin/customize/themes user interface. Fallback is handled in the same way as core, so it is ok to have incomplete translations for non-english languages will make use of the english keys.

In the background, these translations are stored alongside the core translations, under a theme-specific namespace. For example:

theme_translation.{theme_id}.sidebar.welcome

You should never hardcode the theme_id in your theme code, so there are a few ways to help you access the translations.

In .hbs files, you can use the dedicated helper

{{theme-i18n "my_translation_key"}}

Or, if you need to pass the translation key into another component, you can use the theme-prefix helper:

<DButton @label={{theme-prefix "my_translation_key"}} />

In Javascript, or in .gjs files, you can use the themePrefix function. This is automatically injected, and does not need to be imported:

const result = I18n.t(themePrefix("my_translation_key"));

<template>{{i18n (themePrefix "blah")}}</template>

For a complete example of using translations in a theme, check out @awesomerobot’s Fakebook theme: GitHub - discourse/Fakebook


This document is version controlled - suggest changes on github.

31 个赞

Howto use theme translations in CSS ? I know we can use theme parameters but I need theme translations.

You can’t, they’re only available in templates and javascript. That’s the same as core/plugin translations.

Ideally, refactor things so that the string is set in a template. But if you really need a customisable string in a css file, you could use theme settings: Developer’s guide to Discourse Themes

1 个赞

And if I use theme setting, is it possible to translate it ?

No, not in to multiple languages, but it would allow admins to customize it for their site.

2 个赞

Hello everyone.
I’m redefining the template upload-selector.hbs
I want to add a translatable phrase.
I created a new variable upload_selector.upload_images
For example

Please tell me what to do next?

Hello,

when i try this technic in the discourse theme creator (see here) everything works fine and as explained here in the post.

However if I import the very same theme on my own server only " [en.theme_translations.12.blog]" appears. Also in the theme settings page there is no “Theme Translations” section like on the theme creator.

I really don’t know where to search for this error anymore. Has anybody a hint for me?

[Edit]
I’m using discourse 2.6.7 ( [f73cdbbd2f ] ) in an docker environment.

can you update discourse ?

you are using an old version

Yeah i’m trying that, that is another thing i need help with but, I don’t want to post it here, that’s another topic.

Anyway I thought that shouldn’t be problem as the translation feature was included in version 2.2.0.beta9, see commit.

你好,提前为我的新手问题道歉。
我用纯 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 个赞