コンポーザーに外部ウィジェットを追加する

コンポーザーにウィジェットを追加しようとしています。ツールバーからコードを挿入するところまでは進めましたが、その中で JavaScript を動作させる方法がわかりません。外部サイトから呼び出すのではなく、プラグインまたはテーマコンポーネントとして内部に JavaScript を追加する必要があると考えていますが、その方法が確信が持てません。これはコンポーザー内で実現可能でしょうか?

もう少し具体的に、何をしようとしているのか教えていただけますか?編集エリアにコンテンツを追加する新しいツールバーボタンを追加しようとしているのでしょうか?それとも別のことでしょうか?

私が目指しているのは、ユーザーがコンポーザーから独自のウィジェットを挿入できるようにし、ユーザーがする必要があるのは数字を入力するだけで、ツールバーがそれを囲むようにすることです。例えば、112756 と入力すると、以下のコードがその数字を囲むように挿入されます。

<div id='PurpleAirWidget_112756_module_AQI_conversion_C0_average_10_layer_detailed'>Loading PurpleAir Widget...</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>

理想的には、以下のように表示されることを期待しています。

「いいね!」 2

はい、コンポーザーへのコンテンツ追加方法をすでに把握されているようですね?(もしそうでなければ、この例が参考になるかもしれません:https://github.com/discourse/discourse-gifs。このテーマコンポーネントは、ツールバーのボタンがクリックされたときにモーダルを表示し、モーダル内のコンテンツをクリックすることでコンポーザーにコンテンツを挿入します)。

もしスクリプトをロードして投稿コンテンツに何らかの操作を加えたいのであれば、以下の投稿が方向性を示してくれるかもしれません。loadScriptdecorateCooked を使用する方法について:Difficulties in correctly adding external JavaScript - #4 by StevenTammen

「いいね!」 1

これを何らかの形で活用できるかもしれません(直接利用するか、フォークしてカスタマイズするか)。これは、作曲ボタンに代わって特殊文字を使用するものです: Mentionables

「いいね!」 1

ご指摘の方向に進めさせていただきありがとうございます。別の問題に直面しているようです。スクリプトを使用するトピックページを開いたときに読み込み/レンダリングされません。ページをリフレッシュした後にのみ正しく読み込まれますが、毎回ではありません。これは Discourse がシングルページアプリケーションであるためでしょうか?私の 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'>Loading PurpleAir Widget...</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(() => {       
    })  
  })     
  });

試してみましたが、同様の結果になりました。最終的には decorateCooked を非推奨にする予定なので decorateCookedElement を使用しようとしました。

 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'>Loading PurpleAir Widget...</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 が実行されていることはわかりますが、スクリプトが再度機能するのを妨げている何かがあります。

関連しているかどうかわかりませんが、pa.widget.js からコンソールに Uncaught TypeError: i is null というエラーも表示されます。

Screen Shot 2021-11-08 at 9.11.39 PM

「いいね!」 1

試してくれてありがとう。ページを開いたままにしておくと、スクリプトが約90秒から2分ごとに呼び出されることに気づきました。

それで、最終的には読み込まれます。それが後で読み込まれる方法/理由に関するドキュメント/投稿はありますか?