埋め込み投稿のテキストをカスタマイズする方法

メインサイトで様々なチュートリアルやブログを公開しており、フォーラムとしてもコメント機能としてもDiscourseを利用し、埋め込み機能を使っています。

これはほとんどの場合うまく機能していますが、メインサイトで新しいページを作成すると、コンテンツ全体がDiscourseの投稿に含まれてしまうという問題があります。一部のユーザーは、フォーラムで全文を読んでいるため、メインサイトの存在すら知りません。これは、埋め込みコードエディタのような機能がDiscourseでは動作しないため、バグのある体験となってしまいます。

理想的には、Discourseの投稿は元の投稿への短く、非常に分かりやすいリンクになるはずです。例えば、以下のようになります。

元の投稿はこちらで表示:

https://example.com

このスレッドへの返信は、元の投稿へのコメントとして表示されます!

こちらのスレッドで説明されている embed truncate 設定を無効にしようとしましたが、これは「全文を表示」ボタンを非表示にするだけで、投稿には依然としてコンテンツ全体が表示されてしまいます。

また、embed.imported_from メッセージを編集しようとしましたが、これはユーザーがすでに気づいていない可能性のある、下部にある小さなテキストを変更するだけでした。

さらに、Discourseが投稿を作成した後に手動で編集しようとしましたが、MarkdownはHTMLにレンダリングされず、プレーンテキストとして表示されてしまいます。これは、こちらの問題と似ています。

何か見落としている設定や、自動生成されたDiscourseの投稿のテキストをカスタマイズするための他のトリックはありますか?メインサイトのHTMLに何か含めることで、Discourseに正しいものを表示させるように仕向けることができるでしょうか?あるいは、Markdownレンダリングの問題を修正する方法があれば、手動で編集することも厭いません。

何かお手伝いいただけることがあれば、よろしくお願いします!

「いいね!」 1

申し訳ありませんが、どなたか試せるアイデアがあれば、本当に感謝いたします!

ケビンさん、WP Discourseプラグインを使用しているのか、それともJavaScript埋め込みを使用しているのか、確認させていただけますか?

「いいね!」 1

返信ありがとうございます!JavaScript埋め込みを使用しています。例えば、このページがあります。

この埋め込みコードが含まれています。

<script type="text/javascript">
DiscourseEmbed = { discourseUrl: location.protocol 
	+ '//forum.happycoding.io/',
	discourseEmbedUrl: location.protocol + '//happycoding.io/tutorials/javascript/react-css' };
	
(function() {
	var d = document.createElement('script'); d.type = 'text/javascript'; d.async = true;
	d.src = DiscourseEmbed.discourseUrl + 'javascripts/embed.js';
	(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(d);
})();
</script>

これにより、Discourseに次の投稿が作成されます。

https://forum.happycoding.io/t/css-in-react/1092

それをクリックすると、投稿に元のページの全文が含まれていることがわかります。

明確化ありがとうございます。

Discourse で embed truncate サイト設定を有効にしているのはなぜですか?無効にしたと述べているのに、問題は次のように述べているため、少し混乱しています。

embed truncate 設定は、まさにこの理由の一部です。これにより、ユーザーは Discourse 自体で投稿の抜粋のみを確認できます。

回避しようとしている特定のユーザー行動と、奨励しようとしている特定のユーザー行動について、もう少し詳しく説明していただけますか?

「いいね!」 1

embed truncate 設定については、これまで何度も見直してきました。もう一度確認したところ、有効にする方がわずかに良いとは思います。しかし、Discourse で元の記事の全文を表示しないようにする方法をまだ探しています。つまり、クリック操作で全文を隠すのではなく、元の記事へのリンクだけを表示したいのです。

避けたい行動は、ユーザーが Discourse で元の記事の全文を読んでしまうことです。これは問題です。なぜなら、Discourse 上の全文には(インタラクティブな JS や埋め込みコードなどによる)バグが含まれていることが多く、その結果、Discourse での閲覧をやめて「実際の」サイトにアクセスするようにというバグレポートが届くからです。

つまり、奨励したいユーザー行動は、Discourse の投稿ではなく、元のページで記事の全文を読むことです。

これは些細なことのように思えるかもしれませんが(そして、全体的に見ればそうですが)、ユーザーが Discourse にアクセスし、ページの動作がバグっていると思い込み、「実際の」サイトにある読むべきページがあることに気づく前に離脱してしまうのではないかと恐れています。

検討した可能性のあるオプションをいくつか紹介します。

  • Discourse にリンクのみを含め、元の投稿は一切含めないように指示する設定はありますか?
  • Discourse の投稿に含める(または除外する)記事の一部を示すために、元の HTML に追加できる CSS クラスやその他の属性はありますか?
  • Discourse の Show Full Post... ボタンを非表示にするために、カスタム CSS を追加できますか?

ケビンさん、説明ありがとうございます。この問題に特化した設定はありませんが、2つのアプローチが考えられます。

サイトから取得するHTMLをカスタマイズする

埋め込みは、Readability gemを使用してサイトのコンテンツをスクレイピングすることで機能します。このgemとその出力は、スクレイピングされるHTMLをフィルタリングするために次のオプションを使用します。

opts[:whitelist] = SiteSetting.allowed_embed_selectors if SiteSetting.allowed_embed_selectors.present?
opts[:blacklist] = SiteSetting.blocked_embed_selectors if SiteSetting.blocked_embed_selectors.present?
allowed_embed_classnames = SiteSetting.allowed_embed_classnames if SiteSetting.allowed_embed_classnames.present?

したがって、allowed_embed_selectorsblocked_embed_selectors、またはallowed_embed_classnamesのサイト設定を設定して、HTMLから取得されDiscourseの投稿に表示されるコンテンツを制限できます。たとえば、存在しないクラスに制限して、コンテンツが取得されないようにすることができます。

サイトからスクレイピングされたコンテンツには、次のHTMLが追加されます。

"\n<hr>\n<small>#{I18n.t('embed.imported_from', link: \"<a href='#{url}'>#{url}</a>\")}</small>\n"

したがって、ユーザーにブログでコンテンツを読むように指示するには、管理者パネルのembed.imported_fromテキストをカスタマイズするだけで済みます。たとえば、ロケールテキストの英語バージョンは次のようになります。

This is a companion discussion topic for the original entry at %{link}

「投稿全体を表示」ボタンを非表示にする

提案されたように、CSSで「投稿全体を表示」ボタンを非表示にすることでも機能するはずです。

「いいね!」 2

埋め込みテキスト全体をカスタマイズするオプションがない理由を理解するのに苦労しています。埋め込まれたURLから実際のコンテンツをスクレイピングするのではなく、単にそれにリンクし、短い説明(例:メタサマリーのみ)を表示したいのです。

現在は、自動API呼び出しでこれを行っていますが、ネイティブの埋め込み機能に切り替えたいと考えています。

Discourseが単一の要素のみをスクレイピングできるように、スクレイピングされたサイトに非表示要素を作成しようとしましたが、欠点は、リンクのoneboxが表示されないことです。

embed.imported_fromをカスタマイズすることも限界があります。常に<small>タグに強制され、実際のカスタマイズができないためです。

それは、あなたが埋め込みを望んでいないように聞こえます。埋め込みとは、本質的に、他の場所からのコンテンツの「埋め込み」です。

なぜ切り替えたいのですか?

はい、新しいブログ記事が公開されるたびに自動的にスレッドを作成したいだけです。

しかし、外部ウェブサイトのブログ記事の下にコメントを表示するために、ネイティブのJS埋め込み機能も使用したいと考えています。これは、フォーラムの埋め込み動作にも伴います。

現在使用している自動化には多少の遅延があり(リアルタイムではない)、新しい記事が公開されるたびにCMSで自動スレッド作成を実装するのは少し難しくなっています。これは、ブログCMSだけではなく、「公開」イベントも明確ではないためです。

いずれにしても、スレッドを作成しようとするJS埋め込みと私の自動化との間に競合が発生します。前者がほとんどの場合、より速いでしょう。そのため、スレッドを手動で編集する必要があるという欠点がありますが、JS埋め込み機能のみを使用するように「切り替え」たいと考えています。

ご提案をお待ちしております! :smile:

説明ありがとうございます。

もし私の理解が正しければ、以下のようになります。

  1. JS embeds のトピック作成とコメント連携機能が必要で、
  2. Discourse の最初の投稿に、短い説明付きのリンクだけが必要ということですね。

これで合っていますか? 2について、embed truncate というサイト設定はお試しになりましたか?もし試されたのであれば、何が気に入らなかったのでしょうか?最初の返信で少し触れられているかと思いますが、具体的に何に苦労されているのか説明していただけますか?望む結果(そしてその望む結果とは具体的に何なのか)を達成するのを妨げている例を挙げていただけますでしょうか。

「いいね!」 1

はい、その通りです。

問題は、埋め込みコンテンツが常にHTMLタグで囲まれているため表示されないリンクのワンボックスにあります。 :smiley:

これは些細なこと(実際、些細なことです)のように聞こえるかもしれませんが、記事ごとに手動で編集しなければならないという生活の質の低下は大きく、長年修正したいと思っていました。

(Discourseのブログ記事の例を使用して)どのように見せたいかを示します。

現在、URLと概要を具体的にスクレイピングするために、ウェブサイトの非表示要素をいじらなければなりません。それでも、問題はワンボックスが表示されないことです。より完全にカスタマイズできる唯一のことは、下部にある「ブログ記事の続きを読む…」の部分です。

私が求めているのは、JSスニペットに次のようなものを追加できる機能だと思います。

DiscourseEmbed = {
    discourseUrl: 'https://forum.example.com/',
    discourseEmbedUrl: 'https://blog.discourse.org/2024/03/a-warm-welcome-to-spiceworks',
    discourseRaw: 'https://blog.discourse.org/2024/03/a-warm-welcome-to-spiceworks\\n\\nWe are thrilled to share the move of the Spiceworks community to Discourse! The Spiceworks team has worked closely with our migration team\\n\\n<small>Read the full blog post on <a href="https://blog.discourse.org/2024/03/a-warm-welcome-to-spiceworks/">discourse.org</a>. This post has been created automatically and replies will be shown on the website.</small>'
};

discourseEmbedRaw が、通常の /posts.json へのAPIリクエストにおける raw 値と同等であること。

しかし、これはエッジケースの要件であり、ほとんどのユーザーには関係ない可能性があることを理解しています。JSスニペットがそれを試みる前に、API経由でトピックを作成することで解決しようと思います。

それはお勧めしません。

それは様々な問題を引き起こすでしょう。今はひとまず置いておきましょう。

理想的にはすべてを完全に制御したいと思っていることは理解していますが、現在のシステムで実現可能な改善点にあなたのニーズを翻訳しようと試みますので、しばらくお待ちください。これらはあくまで提案であり、Discourseチームによって承認されるかどうかは私にはコントロールできないことを念頭に置いてください。

Discourseの埋め込み投稿は、基本的に2つの要素で構成されています。

  1. 「インポート元」HTML(つまりリンク)
  2. リンクされたページのHTMLコンテンツ(全体または切り抜き)。

1. 「インポート元」HTMLの制御

現在、このHTMLはハードコードされています。

 "
\u003chr\u003e
\u003csmall\u003e#{I18n.t("embed.imported_from", link: "\u003ca href='#{url}'\u003e#{url}\u003c/a\u003e")}\u003c/small\u003e
"

これを例えばURLのみに変更して、ワンボックス化したいと考えているのですね。実現可能な改善策としては、この部分を単に「URLのみ」に切り替えるサイト設定があれば、管理者がどこかにHTMLを入力する必要がなくなります。

2. 切り抜かれたHTMLコンテンツの制御

これはすでに可能です。サイト設定のallowed embed classnamesを、サイトで使用したい抜粋をラップした要素のクラス名に設定するだけです。例:

Discourseで

以下のサイト設定を行います。

  • embed truncatefalse に設定
  • allowed embed classnames"discourse-excerpt" に設定

あなたのブログページで

<div class="discourse-excerpt">
We are thrilled to share the move of the Spiceworks community to Discourse! The Spiceworks team has worked closely with our migration team
</div>

3. 「インポート元」HTMLとHTMLコンテンツの順序の制御

もし私の理解が正しければ、「インポート元」部分(例:URLのみ)をHTMLコンテンツ(または切り抜かれたコンテンツ)の前に配置したいと考えているのですね。これも同様に、embed imported from above content のようなブール値のサイト設定が最も簡単な方法でしょう。

つまり、私の理解が正しければ、2つの新しいブール値設定と TopicEmbed クラスのいくつかの小さな調整でこれを達成できるはずです。これらの変更はすべて discourse/discourse 自体に対して行われる必要があることに注意してください。処理はそこで行われるためです。

前述したように、これらは私があなたの要望を実現する方法についての提案に過ぎません。これら、または類似の変更を実現するには、Discourseチームの承認が必要になります。

「いいね!」 1

これを書き留めてくれてありがとう!:+1:

はい、まさにそのように試しましたが、問題はコンテンツが複数のHTMLタグでラップされることで、それがoneboxがトリガーされない理由です。URLを<br>タグ(oneboxをトリガーするため)で区切ろうとしましたが、そのようなものは自動的にトリミングされるようです。

うーん、わかりました、なぜですか?:slight_smile:

もちろん、embed_url 値を設定します。

oneboxで埋め込みURLを取得することは別の問題です。allowed embed classnamesを使用して、私の例のようにテキスト抜粋を設定してください。

実際にはTopicEmbedの解析の問題を回避しようとすると車輪の再発明になってしまうからです。また、コードが予期した順序で実行されない場合(競合状態やその他の介入例外が発生する場合など)に、新たな問題が発生する可能性があります。これらの種の問題は、外部サイトのコードとWP Discourseプラグインの組み合わせで比較的よく発生します。要するに、それだけの価値はありません。

コードベースに精通しているようですね :)。実際には、このクラスに2つの簡単な変更を加える必要があります。

  1. ここでサイト設定によって制御される条件を挿入します。
  1. ここで別のサイト設定によって制御される条件を挿入します。

Discourseアプリをビルドする必要すらありません。まず2つのrspecテストを作成し、次に変更を加え、それらが機能したらPRを作成するだけです :slight_smile:

「いいね!」 1

参考までに、最終的に行ったことを以下に示します。

  1. 私のブログには、forum-excerpt という ID を持つ <div> があり、display:none で非表示になっていますが、Discourse の投稿に表示したい HTML が含まれています。(これは Jekyll / Liquid ロジックを使用して行いますが、実際には重要ではありません。)

  2. Discourse で、「埋め込みを許可する要素の CSS セレクター」を #forum-excerpt に設定しました。div は実際のページでは非表示になっていますが、コンテンツはフォーラムに表示されます。

  3. 「埋め込み投稿を切り抜く」のチェックも外しました。

  4. 「埋め込み CSS」セクションで、.button のフォントサイズを大きくしました。これは小さな変更ですが、コメントを追加するためのボタンが大きくなります。

  5. embed.continueembed.start_discussionembed.imported_from のテキストもカスタマイズしました。これにより、ウェブサイトのコメントセクションに表示される内容が変更されます。

これにより、フォーラムの投稿に表示される HTML を完全に制御できます。提供する HTML は、基本的に OneBox の同等物です。大きなサムネイルとメイン投稿へのリンクになります。

これは私にとってはほぼ完璧に機能します。手遅れになりましたが、助けてくれてありがとう!

「いいね!」 2

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.