Ajouter des chaînes localisables aux thèmes et composants de thèmes

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 « J'aime »

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 « J'aime »

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 « J'aime »

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.

Bonjour, désolé d’avance pour la question de débutant.
J’ai créé un en-tête avec juste du HTML et du CSS

        <div class="top-navbar">
         <span class="j_menu_item" ><a>Download</a></span>     
        </div>

Et ensuite je veux traduire le mot “Download”
J’ai créé le fichier de traduction anglais

en: 
  top-navbar: 
    download: "Yeah"

Ensuite j’ai modifié le code HTML comme pour l’exemple de Facebook


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

Cela traduit et affiche “Yeah” mais casse ma mise en page, je suppose que c’est parce que j’utilise “/connectors/discovery-below/sidebar”. Je veux juste appliquer ma traduction sans toucher à aucun modèle, mais je ne comprends pas comment appliquer la traduction en ligne.

Pourriez-vous s’il vous plaît fournir un exemple simple sur la façon d’utiliser une traduction dans le HTML personnalisé d’un thème ?

Merci !

Bonjour,

Le problème est que data-template-name doit être un nom unique. Developing Discourse Themes & Theme Components. Comme ceci : data-template-name=\"/connectors/PLUGIN-OUTLET-NAME/UNIQUE-NAME\" Maintenant, vous utilisez le nom sidebar dans votre exemple, ce qui, je pense, remplace le modèle de barre latérale de Facebook.

Par exemple, ceci devrait fonctionner :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 « J'aime »

Merci @Don

J’ai oublié de mentionner que le plugin n’est pas installé et que j’ai déjà essayé de changer le data-template-name en un NOM UNIQUE aléatoire avec le même résultat ou de ne pas afficher ma bannière du tout si j’inventais le PLUGIN-OUTLET-NAME.
Vous pouvez probablement le dire maintenant, je ne suis pas du tout familier avec handlebars/ember :slight_smile:
Ma compréhension est que je personnalise un modèle qui a sa place prédéfinie dans le HTML et que le résultat est que le HTML personnalisé n’est plus sur /html/body/section main mais profondément à l’intérieur, ce qui entraîne un héritage CSS que je n’avais pas auparavant.
Ce que j’ai du mal à comprendre, c’est pourquoi je dois personnaliser un modèle pour utiliser une traduction…
J’ai réussi à identifier le modèle à personnaliser en utilisant Ember inspector comme conseillé ici
Et grâce à votre réponse et au lien sur le plugin-outlet, j’ai trouvé le bon data-template-name = “/connectors/above-site-header/my-navbar”
Merci encore pour votre aide

1 « J'aime »

Je vois… Je pensais que vous utilisiez le thème Fakebook et que vous vouliez placer votre code sous la section de la barre latérale. :slightly_smiling_face:

Une bonne façon de visualiser les points de sortie des plugins est d’utiliser le composant de thème Plugin Outlet Locations.

2 « J'aime »

Salut @Don ,

La raison pour laquelle j’ai utilisé cet exemple de Facebook est à cause de :

Merci encore !

Qu’en est-il du singulier et du pluriel, comment traduire du texte à l’aide de {{theme-i18n}} s’il a une et plusieurs traductions ? Par exemple, « Result » et « Results »

2 « J'aime »

Il existe quelques exemples de la façon dont nous procédons dans le code source de Discourse, généralement nous avons deux chaînes et nous basons le choix sur un entier :

Screenshot 2022-12-15 at 5.42.58 PM

Cela devrait également fonctionner dans un thème, généralement le JS ressemblerait à ceci :

I18n.t(themePrefix("confirm_remove_tags"), {
  count: exampleCountValue,
});
1 « J'aime »

et qu’en est-il de hbs, peut-il être fait dans les modèles hbs ?

1 « J'aime »

Oui, c’est possible :

{{theme-i18n "confirm_remove_tags" count=this.exampleCountValue}}
4 « J'aime »

quand je fais ça dans un template de composant .gjs au sein d’un thème, j’obtiens :
Error: Attempted to resolve a helper in a strict mode template, but that value was not in scope: theme-prefix

Alors je tente de l’importer :
import themePrefix from "discourse/helpers/theme-prefix";

Mais ça râle :
Identifier 'themePrefix' has already been declared

(J’ai cherché un exemple sur le 'hub mais il ne semble pas y en avoir)

1 « J'aime »

Mise à jour : vous devez utiliser {{i18n (themePrefix "

4 « J'aime »