Модернизация тегов inline-скриптов для шаблонов и JS API

Использование <script type='text/discourse-plugin'> или <script type='text/x-handlebars'> в темах теперь устарело. Любое использование этих тегов в темах следует обновить в соответствии с инструкциями ниже.

Обычные <script> и <script type='text/javascript'> не затронуты этим изменением.

Сроки

Это приблизительные оценки, они могут быть изменены

  • Май 2025 — включены сообщения об устаревании в консоли

  • Июль 2025 — включены предупреждающие баннеры в админ-панели

  • Конец сентября 2025 Март 2026 — удаление функциональности

Конвертация <script type='text/x-handlebars'>

Шаблоны, созданные этим способом, следует перенести в отдельные файлы .hbs или переписать в файлы gjs.

Чтобы оставить их в формате HBS, шаблоны коннекторов можно разместить в:

{theme}/javascripts/discourse/connectors/{outlet-name}/{connector-name}.hbs

а шаблоны компонентов — в:

{theme}/javascripts/discourse/components/{component-name}.hbs

:warning: С марта 2026 года файлы .hbs также считаются устаревшими. После выполнения этой конвертации перейдите к инструкциям по ссылке: Deprecating .hbs file extension in themes and plugins

Чтобы создавать коннекторы и компоненты в современном формате .gjs, ознакомьтесь с этой главой руководства для разработчиков тем:

Конвертация <script type='text/discourse-plugin'>

Код внутри этих тегов можно перенести в отдельный JavaScript-файл.

Если вы разрабатываете тему через интерфейс админ-панели, скопируйте код из тега <script> и переместите его во вкладку JS (там, где написано // your code here).

Если вы разрабатываете тему локально, создайте новый файл по пути:

{theme}/javascripts/discourse/api-initializers/init-theme.js

затем добавьте этот обёрточный код и поместите свой код в указанное место:

import { apiInitializer } from "discourse/lib/api";

export default apiInitializer((api) => {
  // Ваш код здесь
});

В тегах скриптов единственным способом импорта других JS-модулей был синтаксис require(). Хотя это всё ещё будет работать в файле .js, скоро этот способ также станет устаревшим, поэтому сейчас самое время перейти на современные импорты ES6. Например:

- const I18n = require("discourse-i18n").default;
+ import I18n from "discourse-i18n";
- const { h } = require("virtual-dom");
+ import { h } from "virtual-dom";

Дополнительная информация об инициализаторах JS:

Возможно, это очень глупый вопрос, но у меня есть очень простой компонент темы, который я разместил прямо в консоли администратора внутри тега <head>:

<script type="text/x-handlebars" data-template-name="/connectors/top-notices/whos-online-below-site-header">
{{whos-online}}
</script>

Если я правильно понимаю эту тему, значит ли это, что теперь мне нужно создать отдельную папку для компонентов темы, разместить её на GitHub и добавлять компонент только для такой простой задачи, как добавление в выходное отверстие плагина?

Я очень надеюсь, что нет, иначе это сломает большинство моих простых компонентов темы :grimacing:

Теперь есть вкладка JS, поэтому вы, вероятно, можете использовать api.renderInOutlet.

А, я не заметил, что это также можно делать с помощью коннекторов/компонентов, но в связанной статье нашёл следующее:

Возможно, это проще, чем я думал, спасибо!

Спасибо за этот пост!
Возможно, это очень простой вопрос, но я всё же хочу уточнить:
Поскольку у нас нет песочницы, мне нужно убедиться перед тем, как продолжать.
Мне нужно обновить затронутую тему, поэтому правильно ли я понимаю, что весь код, связанный с “Script” из вкладки “head”, нужно перенести во вкладку JS, как показано ниже:

Почти, но не совсем. Вам нужно удалить теги script и изменить импорты примерно так:

import { ajax } from "discourse/lib/ajax";

Затем вставьте всё это во вкладку JS, внутри:

Наш сайт на Discourse (размещенный на платформе Discourse) в настоящее время выдает следующую строку ошибки (именно это привело меня к этой теме):

Насколько мне известно, мы не вносили никаких изменений в тему «Light» самостоятельно. Просматривая страницу администратора этой темы, я не вижу ничего, что указывало бы на то, что это что-то иное, чем стандартная тема, предоставляемая системой (хотя вполне возможно, что я что-то упустил).

Для размещенного сайта, подобного нашему, вероятно ли, что ошибка исчезнет сама со временем, или же нам необходимо предпринять какие-то действия?

Спасибо,
-Брэд

Вам необходимо предпринять действия для решения этой проблемы — она не исчезнет сама по себе.

Я быстро посмотрел ваш сайт через инструменты разработчика Chrome, и похоже, что соответствующий код связан с добавлением языка ‘chapel’ в highlightjs.

Если вы откроете свою тему ‘Light’ и нажмёте «Изменить код», то сможете найти это в одной из вкладок HTML. Затем вы можете следовать инструкциям в первом сообщении этой темы, чтобы переместить код на вкладку ‘JS’.

Спасибо, @david! Я забыл, что мы делали некоторые настройки для подсветки синтаксиса Chapel, и не уверен, что сам догадался бы об этом, глядя на сообщение об ошибке. Поэтому очень благодарен за помощь и подсказки.

— Брэд

У меня есть простой файл .html:

<script type='text/x-handlebars' data-template-name='/connectors/below-site-header/oprs-top-container'>
    <div id='WW_T_D_1' class='oprs-top-leaderboard'></div>
</script>

Я немного запутался в разных способах выполнения этой миграции. Буду признателен, если кто-то объяснит, что делать. Спасибо.

Просто используйте renderInOutlet для коннектора

import { apiInitializer } from "discourse/lib/api";

export default apiInitializer((api) => {
  api.renderInOutlet("below-site-header", <template>
    <div id='WW_T_D_1' class='oprs-top-leaderboard'></div>
  </template>);
});

Спасибо. Я попробовал, но это не сработало :confused:

Вот моя структура:

below-site-header.js


export function test() {
    let test2 = document.querySelector('.test');
    console.log('test ', test2);
}

И below-siteheader-connectors.hbs

<div class="test"></div>

Я новичок в этом, поэтому любая помощь будет оценена по достоинству. Я взял этот репозиторий у предыдущего разработчика.

Привет! Не могли бы вы поделиться ссылкой на ваш репозиторий на GitHub? Спасибо!

Итак, я вставил свой крошечный скрипт «make-avatar-bigger» во вкладку JS (вне Desktop - <head>), и это работает довольно просто, но есть ли хотя бы быстрый и грязный способ заставить его применяться только в Desktop? Мои аватары на мобильных устройствах тоже стали большими, и всё это выглядит довольно глупо.

Код для справки:

import { apiInitializer } from "discourse/lib/api";

export default apiInitializer((api) => {
 api.changeWidgetSetting('post-avatar', 'size', '70');
});

Хм… может быть, отрегулировать это с помощью CSS?

Или, возможно:

import { apiInitializer } from "discourse/lib/api";

export default apiInitializer((api) => {
  const site = api.container.lookup("service:site");
  if (!site.mobileView) {
    api.changeWidgetSetting('post-avatar', 'size', '70');
  }
});

Что-то на скорую руку.

Это сработало идеально, спасибо!

Напоминание: changeWidgetSetting для post-avatar устаревший API и скоро будет удален.

Возможно, вам стоит изменить код следующим образом:

import { apiInitializer } from "discourse/lib/api";

export default apiInitializer((api) => {
  const site = api.container.lookup("service:site");
  if (!site.mobileView) {
    api.modifyClass("component:post/avatar", (SuperClass) => class extends SuperClass {
      get size() { return "70"; } 
    });
  }
});

Кажется, для этого также есть официальный компонент темы? Avatar Size and Shape

Не уверен, подходит ли он для конкретного случая, но, похоже, должен (плюс в том, что кто-то исправит его, если потребуется обновление :slight_smile:)

Я прошёл путь от «быстрого и грязного» до официально поддерживаемого решения. Спасибо всем!

Для тех, кто использует устаревшие компоненты (с раздельной обработкой для Desktop/Mobile), отмечу, что вкладка JS доступна только в разделе Common — надеюсь, это сэкономит кому-то ещё несколько поисков :slight_smile: