topic-thumbnails を使用すると、外部埋め込みのサムネイルが欠落しています

製品のフォーラムを立ち上げます。外部埋め込みは、iframeを許可した後にすでにOneBoxで機能しています。

embedへの直接リンクは、oembed endpointの結果にきれいに変換されます。
さて、私たちの懸念は、Topic List Thumbnailsがアクティブなときにサムネイルが表示されるようにしたいということです。サムネイルが取得されない理由がわかりません。

lib/onebox/engineに統合を追加する必要がありますか?

追加すると、デフォルトの動作はほとんど今日機能しますが、動的な埋め込みをサポートしていないという点を除きます。iframeの代わりにJSをロードしたいと考えています。確かにこれには別の解決策があります。つまり、JSを使用してiframeをオプションでリサイズすることですが、短期的にはoEmbedの汎用的な実装を予定していません。

Using onebox images for topic thumbnails - #20 by davidについては認識していますが、私のケースでは役に立ちませんでした。

「いいね!」 1

Discourseチームとメールで何度かやり取りした後、ここで更新します。

主な発見は、onebox になるリンクが iframe としてレンダリングされる場合、サムネイルが読み込まれないということです。

つまり、リンク:

https://app.everviz.com/embed/N0dDTJaOQ

は、ドメインからの iframe が許可されているかどうかに応じて、サムネイルをレンダリングしたりしなかったりします(allowed iframes)。これに対する解決策は、何らかの方法で投稿に iframe を挿入することです。私はそのためのプラグインを作成し、投稿に表示されるのを防ぐために display: none が画像に設定されていることを確認しました。

これを一般化できると想像しています。

  1. すべての汎用 onebox について、get_oembed.thumbnail_url が存在する場合、その横に画像をサイレントに読み込んで非表示にする。
  2. 議論の余地はあるが、より良い解決策として、get_oembed.thumbnail_url を抽出して投稿に関連付けるための一般的なサポートを追加する。これは、cooked エリア自体の一部ではない。

関連場所:

  1. https://oembed.com/
  2. discourse/lib/onebox/engine at main · discourse/discourse · GitHub
  3. discourse/lib/onebox/engine/standard_embed.rb at main · discourse/discourse · GitHub

このモーダル動作にはあまり満足していません。つまり、allowed iframes が有効になっているかどうかが問題です。Discourse が oembed エンドポイントに最初に GET リクエストを送信するときに、そこからのすべてのプロパティを抽出し、利用してくれると良いのですが。

アップデート

クライアントサイドプラグインAPIを使用して、投稿に画像を読み込むというアイデアがありました。

api.decorateCooked($elem => {
    $elem[0].querySelectorAll('.my-iframe')
    .forEach(function (iframe) {

      //作業

      iframe.insertAdjacentElement('beforebegin', thumbnail);
    });

  }, {id: 'unique_string'});

しかし、Discourseは何も認識しません。

次のいずれかの状況が発生しているようです。

  1. 遅すぎて、Discourseがすでにサムネイルの取得と生成を行ってしまっている。
  2. サムネイル生成メカニズムが見逃してしまうような、画像に必要な属性が不足している。

後者であることを願っています。ここで注目すべき点は、画像はDiscourseインスタンスにアップロードされず、単に独自のサーバーから参照されるだけということです。

これを試しましたか? 特定のoneboxを作成することで、調理済みの投稿にonebox画像を提供できるようになる可能性があります。そうすれば、サムネイルが自動的に機能するようになります。

YouTubeのoneboxは、再生ボタンをクリックするまでサイト内の静的なコンテンツであり、クリックするとiframeが表示されると思います。クリック前に表示されるコンテンツには、サムネイルとして取得される画像が含まれています。明らかにDiscourseはiframeから読み取ることができないため、この手法は良いアプローチです。

あなたの例には、ヘッダータグにog:imageが含まれており、これは完璧です。


私の提案は、ここでJavaScriptから離れてRailsで調理することです。

これの唯一の欠点は、ターゲット画像も更新されたと仮定すると、投稿を再構築するまで画像が静的になることです。したがって、動的に変化するサムネイルを表示したい場合は、さらに創造的になる必要があるかもしれません。

「いいね!」 3

ロバートさん、返信ありがとうございます!

プラグインを作成するのが最初に行ったことで、それは素晴らしく機能しました。lib/onebox/engine に配置しても、または個別のプラグインとして配置しても問題ありませんでした。ただし、ホスティングプランを利用しており、プラグインはマルチテナントプランでは許可されていないため、Rails でのクッキングは除外されます。

そのため、次の 3 つの機会のいずれかになります。

  1. 独自のインスタンスを実行する
  2. クライアントサイドで何かをハッキングする(機能する場合)
  3. メインライン Discourse に PR を送信する

ここで質問をします。そのような貢献が受け入れられるかどうか、特に画像を読み込んで非表示にするだけの場合、わかりません。どうすれば確認できますか?

「いいね!」 2

これに関して、ある種の進歩があったかもしれません。

api.composerBeforeSave を見ています。

そのコールバックは composer.js で処理されます。そこから、createPost および editPost メソッドが getCookedHtml を呼び出すことがわかります。これは、おおよそ次のような innerHTML を単純に返します。

const editorPreviewNode = document.querySelector(
  "#reply-control .d-editor-preview"
);

これは、このセレクターを変更した場合、通常の画像アップロードに相当する HTML を強制的に挿入できる可能性があることを意味します。しかし、editorPreviewNode.innerHTML を変更しても、まったく変化がないようです。

これはなぜでしょうか、または composerBeforeSave で同様のことを行うために何を修正できますか?

これは私にはほとんど理解できます。everviz.com(または同様の可視化サービス)用の onebox エンジンをコアに受け入れることは可能だと思います。ただし、cooked 投稿に画像を挿入して非表示にすることは避けたいです。より軽量なオプションがあります。Discourse の投稿プロセッサは、次の要素のアップロードを探します。

したがって、サムネイルを iframe の下にアンカーとして追加するとうまくいくかもしれませんか?表示したままにすることも、hidden のようなクラスを使用して非表示にすることもできます。

「いいね!」 5

こんにちは、Penar、返信ありがとうございます。

to_html メソッドとして以下を使用すると、次の出力が得られます。

  <div class="everviz-box">
   #{get_oembed.html}
   <a class="hidden" href="https://app.everviz.com/thumbnails/#{match[:uuid]}.png"></a>
  </div>
  <div class="...">
    <iframe
      ...
    ></iframe>
    <a class="hidden" href="https://app.everviz.com/thumbnails/[...].png" rel="nofollow ugc noopener"></a>
  </div>

画像を直接リンクすると、次のようになります。

<a href="https://app.everviz.com/thumbnails/[...].png" target="_blank" rel="noopener" class="onebox">
   <img src="//localhost:3000/uploads/default/original/1X/[...].png"
        style="aspect-ratio: 690 / 459;" loading="lazy">
</a>

これは、別の onebox エンジンのコンテキスト外で画像がリンクされている場合にのみ、image_onebox.rb エンジンが入力に対して実行されているように見えます。

この結果、提案された手法は現時点では機能せず、画像をリンクして非表示にするか、Discourse を変更する必要があります。

この場合、画像を追加して非表示にするのは受け入れられる PR ですか?それとも、もっと複雑なことをする必要がありますか?

よくわかりません。これは画像ワンボックスエンジンを通るべきではありません。

これはどうでしょうか。

<a class="hidden" href="https://app.everviz.com/thumbnails/[...].png" rel="nofollow ugc noopener"></a>

つまり、トピックの最初の投稿に、調理済みの列にこれが含まれている場合、画像は処理後にサムネイルとして認識されますか?

「いいね!」 2

混乱させて申し訳ありません。出力が画像ワンボックスエンジンに似ていました。

提案されたリンク(UUIDが正しく挿入されています)は機能しません。Googleから取得したこの画像も同様です(アンカータグとしてここに記述しています。HTMLを貼り付けることがワンボックスの出力と同じであれば、これが私たちの結果を説明することになります)。

<a href=“https://static-cse.canva.com/blob/1031184/1600w-wK95f3XNRaM.jpg
rel=“nofollow ugc noopener”

https://static-cse.canva.com/blob/1031184/1600w-wK95f3XNRaM.jpg

「いいね!」 1

ああ、私のミスです。おっしゃる通り、そのアプローチは機能しません。サムネイルを生成する際には、ダウンロードされた画像のみを使用しますが、アンカータグでリンクされた画像はダウンロードされません。

代替案としては、@merefield が推奨したものと同様のものをコアに追加し、遅延読み込みされるiframe用の汎用oneboxerとしてラップすることが考えられます。新しいサイト設定 lazy_loaded_iframes を追加し、oneboxは最初にOGタグの画像(サムネイルで取得されるはず)を出力し、クリックされると少量のJavaScriptが画像を正しいiframeに置き換える(YouTube iframeの置き換えに似ている)という方法です。

ここで注意すべき点は、使用される画像とiframeの高さを同じにする必要があることです。そうしないと、投稿のスクロール/ナビゲーション時に予期しないジャンプが発生する可能性があります。

「いいね!」 3