Добавить локализуемые строки в темы и компоненты тем

Для тех, кто хочет добавить пользовательские языки и переводы в тему или компонент темы Discourse, теперь можно включать локализованные строки, которые становятся доступны для использования в компонентах интерфейса. Переводы хранятся в том же формате, что и переводы ядра/плагинов, и могут использоваться практически аналогичным образом.

Темы могут предоставлять файлы переводов в формате /locales/{locale}.yml. Эти файлы должны быть валидным YAML, с единственным ключом верхнего уровня, равным определяемому локали. Их можно определить с помощью CLI 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. Механизм возврата (fallback) работает так же, как и в ядре, поэтому допустимы неполные переводы для языков, отличных от английского: в таких случаях будут использоваться английские ключи.

В фоновом режиме эти переводы хранятся вместе с переводом ядра в пространстве имён, специфичном для темы. Например:

theme_translation.{theme_id}.sidebar.welcome

Никогда не hardcode-те 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>

Для полного примера использования переводов в теме ознакомьтесь с темой Fakebook от @awesomerobot: 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]". Кроме того, на странице настроек темы отсутствует раздел “Переводы темы”, который есть в конструкторе тем.

Я уже не знаю, где ещё искать эту ошибку. Не мог бы кто-нибудь дать мне подсказку?

[Редактирование]
Я использую Discourse 2.6.7 ( [f73cdbbd2f ] ) в среде Docker.

Можете ли вы обновить Discourse?

Вы используете старую версию.

Да, я пытаюсь это сделать. Это ещё одна проблема, с которой мне нужна помощь, но я не хочу писать об этом здесь — это отдельная тема.

В любом случае, я думал, что это не должно быть проблемой, так как функция перевода была включена в версию 2.2.0.beta9, см. коммит.

Привет, заранее извините за вопрос новичка.
Я создал шапку, используя только HTML и CSS

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

Теперь я хочу перевести слово “Download”.
Я создал файл перевода на английский

en: 
  top-navbar: 
    download: "Yeah"

Затем я изменил HTML-код, следуя примеру 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>

Это переводит и выводит “Yeah”, но ломает мою верстку. Думаю, это потому, что я использую “/connectors/discovery-below/sidebar”. Я просто хочу применить свой перевод, не ломая никакие шаблоны, но не понимаю, как применить перевод непосредственно в строке.

Не могли бы вы привести простой пример того, как использовать перевод в пользовательском HTML темы?

Спасибо!

Здравствуйте,

Проблема в том, что data-template-name должен быть уникальным именем. Developing Discourse Themes & Theme Components. Вот так: data-template-name="/connectors/PLUGIN-OUTLET-NAME/UNIQUE-NAME". В вашем примере используется имя sidebar, которое, как я полагаю, перезаписывает шаблон боковой панели Fakebook.

Например, это должно сработать :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 на случайное уникальное имя, но результат был тем же — или мой баннер вообще не отображался, если я придумывал название 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:

Хороший способ визуально увидеть точки вставки плагинов — использовать компонент темы Plugin Outlet Locations.

2 лайка

Привет, @Don,

Я привёл пример с Facebook, потому что:

Спасибо ещё раз!

Как быть с единственным и множественным числом? Как переводить текст с помощью {{theme-i18n}}, если предусмотрены варианты для одного и нескольких объектов? Например, «Результат» и «Результаты».

2 лайка

В исходном коде Discourse есть несколько примеров того, как мы это делаем: обычно у нас есть две строки, и выбор зависит от целого числа:

Screenshot 2022-12-15 at 5.42.58 PM

Это также должно работать в теме. В целом, JS-код будет выглядеть примерно так:

I18n.t(themePrefix("confirm_remove_tags"), {
  count: exampleCountValue,
});
1 лайк

А как насчет hbs? Можно ли это сделать в шаблонах hbs?

1 лайк

Да, это возможно:

{{theme-i18n "confirm_remove_tags" count=this.exampleCountValue}}
4 лайка

Когда я делаю это в шаблоне компонента .gjs внутри темы, получаю:

Ошибка: Попытка разрешить хелпер в шаблоне с режимом strict, но это значение не было в области видимости: theme-prefix

Поэтому я пытаюсь импортировать его:

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

Но получаю сообщение:

Идентификатор "themePrefix" уже объявлен

(Я искал пример на хаб, но, похоже, его там нет)

1 лайк

Обновление: вам нужно использовать {{i18n (themePrefix "

4 лайка