Adicionar strings localizáveis a temas e componentes de temas

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 curtidas

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 curtida

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 curtidas

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.

Olá, desculpe antecipadamente por uma pergunta de novato.
Criei um cabeçalho apenas com HTML e CSS

        <div class="top-navbar">
         <span class="j_menu_item" ><a href="https://www.example.com/download">Download</a></span>     
        </div>

E então quero traduzir a palavra “Download”
Criei o arquivo de tradução em inglês

en: 
  top-navbar: 
    download: "Yeah"

Então mudei o código HTML como no exemplo do Facebook


    <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>

Isso traduz e imprime “Yeah”, mas quebra meu layout, acho que é porque estou usando “/connectors/discovery-below/sidebar”. Eu só quero aplicar minha tradução sem mexer em nenhum template, mas não entendo como aplicar a tradução inline.

Você poderia fornecer um exemplo simples de como usar apenas uma tradução no HTML personalizado de um tema?

Obrigado!

Olá,

O problema é que o data-template-name deve ser um nome exclusivo. Developing Discourse Themes & Theme Components. Como isto: data-template-name=\"/connectors/PLUGIN-OUTLET-NAME/UNIQUE-NAME\" Agora você usa o nome sidebar no seu exemplo, que eu acho que substitui o template da barra lateral do Facebook.

Por exemplo, isto deve funcionar :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>{{i18n (theme-prefix "top-navbar.download")}}</a></span>     
  </div>
</script>
2 curtidas

Obrigado @Don

Esqueci de mencionar que o plugin não está instalado e que já tentei alterar o data-template-name para um UNIQUE-NAME aleatório com o mesmo resultado ou sem exibir meu banner, se eu inventei o PLUGIN-OUTLET-NAME.
Você provavelmente já pode dizer, não estou familiarizado com handlebars/ember :slight_smile:
Minha compreensão é que estou personalizando um template que tem seu lugar pré-definido no html e tem como resultado que o html personalizado não está mais em /html/body/section main, mas bem no fundo, resultando em herança de CSS que eu não tinha antes.
O que tenho dificuldade em entender é por que preciso personalizar qualquer template para usar uma tradução…
Consegui identificar o template para personalizar usando o Ember inspector conforme recomendado aqui
E graças à sua resposta e link sobre o plugin-outlet, encontrei o data-template-name correto = “/connectors/above-site-header/my-navbar”
Obrigado novamente pela sua ajuda

1 curtida

Entendo… Pensei que você estivesse usando o tema Fakebook e quisesse colocar seu código abaixo da seção da barra lateral. :slightly_smiling_face:

Uma boa maneira de ver os plugin outlets visualmente é usar o componente de tema Plugin Outlet Locations.

2 curtidas

Olá @Don ,

O motivo pelo qual usei esse exemplo do Facebook é por causa de:

Obrigado novamente!

E quanto a singular e plural, como traduzir texto usando {{theme-i18n}} se ele tiver uma e muitas traduções? Por exemplo, “Resultado” e “Resultados”.

2 curtidas

Existem alguns exemplos de como fazemos isso no código-fonte do Discourse, normalmente temos duas strings e alternamos com base em um inteiro:

Screenshot 2022-12-15 at 5.42.58 PM

Isso deve funcionar em um tema também, geralmente o JS seria algo como:

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

e quanto ao hbs, pode ser feito em templates hbs?

1 curtida

Sim, pode:

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

quando eu faço isso em um template de Componente .gjs dentro de um Tema, eu recebo:

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

Então eu tento importá-lo:

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

Mas ele reclama:

Identifier 'themePrefix' has already been declared

(Eu procurei por um exemplo no 'hub, mas parece não haver nenhum)

1 curtida

Atualização: você precisa usar {{i18n (themePrefix "

4 curtidas