Добавление внешнего виджета в композер

Я пытаюсь добавить виджет в редактор. Я дошёл до того, что могу вставить код из панели инструментов, но не уверен, как заставить JavaScript работать внутри него. Я предполагаю, что мне нужно добавить JavaScript внутренне — либо как плагин, либо как компонент темы, а не вызывать его с внешнего сайта, но не знаю, как это сделать. Возможно ли это в редакторе?

Можете уточнить, что именно вы пытаетесь сделать? Вы хотите добавить новую кнопку на панель инструментов, которая будет вставлять контент в текстовое поле редактора, или что-то другое?

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

<div id='PurpleAirWidget_112756_module_AQI_conversion_C0_average_10_layer_detailed'>Загрузка виджета PurpleAir...</div>
<script src='https://www.purpleair.com/pa.widget.js?key=N6HB6JJ0BP1Z05SE&module=AQI&conversion=C0&average=10&layer=detailed&container=PurpleAirWidget_112756_module_AQI_conversion_C0_average_10_layer_detailed'></script>

В идеале это должно выглядеть примерно так:

Хорошо, похоже, вы уже поняли, как добавлять контент в редактор? (Если нет, пример может помочь: GitHub - discourse/discourse-gifs · GitHub — этот компонент темы открывает модальное окно при нажатии кнопки на панели инструментов, а затем вставляет контент в редактор на основе выбора элементов в модальном окне).

Если вы пытаетесь загрузить скрипт и выполнить какие-то действия с содержимым поста, возможно, эта тема поможет вам найти правильное направление… использование loadScript и decorateCooked: Difficulties in correctly adding external JavaScript - #4 by StevenTammen

Вы, возможно, сможете использовать это каким-то образом (либо напрямую, либо в виде форка с кастомизацией): Mentionables, где вместо кнопки композера используется специальный символ.

Спасибо, что указали мне правильное направление. Я столкнулся с ещё одной проблемой: при открытии страницы темы, где должен использоваться этот скрипт, он не загружается/не отображается. Он начинает работать только после обновления страницы, но и то не всегда. Связано ли это с тем, что Discourse — это одностраничное приложение (SPA)? Я пытаюсь понять, мне не хватает знаний о Discourse или мне нужно что-то допрограммировать самостоятельно.

Вот текущий код, который я использую. Буду очень благодарен за любые указания.

let loadScript = require('discourse/lib/load-script').default;
api.decorateCooked($elem => { $elem.children('div[data-PAWidget]').ready(function() {
         $elem.children('div[data-PAWidget]').append(" <div id='PurpleAirWidget_11726_module_AQI_conversion_C0_average_0_layer_standard'>Загрузка виджета PurpleAir...</div>");
       loadScript("https://www.purpleair.com/pa.widget.js?key=21R72LUN79CXRZ50&module=AQI&conversion=C0&average=0&layer=standard&container=PurpleAirWidget_11726_module_AQI_conversion_C0_average_0_layer_standard").then(() =>{       
    })  
  })     
});

Я попробовал решить эту задачу и получил похожие результаты. Я попытался использовать decorateCookedElement, поскольку в будущем decorateCooked будет устаревшим.

 api.decorateCookedElement(
    (element) => {
      element.childNodes.forEach((node) => {
        if (node.dataset && node.dataset.pawidget) {
          node.insertAdjacentHTML(
            "beforeend",
            "<div id='PurpleAirWidget_11726_module_AQI_conversion_C0_average_0_layer_standard'>Загрузка виджета PurpleAir...</div>"
          );

          loadScript(
            `https://www.purpleair.com/pa.widget.js?key=${node.dataset.pawidget}&module=AQI&conversion=C0&average=0&layer=standard&container=PurpleAirWidget_11726_module_AQI_conversion_C0_average_0_layer_standard`
          );
        }
      });
    },
    { id: "widget-append", onlyStream: true, afterAdopt: true }
  );

Небольшое отличие здесь в том, что я передал ключ через атрибут данных:

<div data-PAWidget="21R72LUN79CXRZ50"></div>

Это работает нормально, если скрипт загружается впервые. Если я просматриваю пост со скриптом, затем возвращаюсь к списку тем и снова захожу в тему, он не работает (до тех пор, пока я не обновлю страницу). Я вижу, что decorateCookedElement вызывается каждый раз при загрузке соответствующего поста, но что-то мешает скрипту работать повторно.

Не уверен, связано ли это, но в консоли я также вижу ошибку Uncaught TypeError: i is null из файла pa.widget.js:

Screen Shot 2021-11-08 at 9.11.39 PM

Спасибо за попытку. Я заметил, что скрипт запускается примерно каждые 90 секунд — 2 минуты, если оставить страницу открытой.


Так что он всё же загружается. Есть ли какая-либо документация или посты о том, как и почему он загружается с задержкой?