הטמעת הערות Discourse באתר אחר באמצעות Javascript

The hundreds of times I’ve been on that CSS page, and never noticed the CSS for embeddings…

לייק 1

If someone is having trouble finding how the embed page looks like here it is:

I tried to implement this today but there are some problems for me:

  • In the forum post, the URL derived (from discourseEmbedUrl?) is lowercased(), breaking case-sensitive URLs in the link following the text “This is a companion discussion topic for the original entry at …”
  • On the first page load, the embed says “Loading discussion…” and hangs. Second page load everything works.
  • Page thrashing: when the iframe is loading, it will have a default height, but if there are no comments found, the height shrinks back down to only display one line with “Start Discussion”. This makes the “loading discussion” bug worse, because it holds open large vertical height
  • It would be nice if the data scraped from embed’s parent could favor a meta tag instead of textifying the whole page, I suppose this is more generalized discourse behavior

The biggest surprise was learning that every time you visit a URL with an embed, a new topic is created. This is in OP:

The only solution I can think of is hacky, relying on short term SSR/caching to ping the embed endpoint:

so I think the logic would be:

  1. check $discourse/embed/info?embed_url=$link

  2. if the topic exists, show the embed as usual.

  3. if not, show a “start conversation” button that links to $discourse/new-topic?subject=$link.

Would that work, or is there some other linkage that needs to take place?

A new topic is created only when a page with the embed is visited for the first time. On subsequent visits it renders the existing topic associated with the URL.

If you don’t want the automatic topic creation, you can create the topics via API calls the way it bests suits you and then pass the topicID to the embed to manually control the association.

Understood, this is brutal for my case because there are tens of thousands of pages

Like this?

  1. API check to see if topic exists
  2. doesn’t exist, show button
  3. click button, API add topic
  4. successful, button container transforms into embed

…that has some issues too, like button clicks with no follow up engagement.

Is there any way to only create the topic when a user has actually commented, something like this?:

$discourse/new-topic?subject=$link.

or is the issue here that we can’t pass in topicID for deterministic coupling?

No, it’s not possible to reply to a topic that doesn’t exist in Discourse.

To address this need, we made it possible to create all embeds topics as unlisted topics that are automatically listed the first time someone replies.

I think creating the topic will require an authenticated request that’s run on the server. If you don’t want to deal with that, another approach would be to add a button to the UI that triggers code similar to this (the code that would otherwise get automatically added to the page’s head tag): discourse/public/javascripts/embed.js at 581dbca97f2b55c9bbbe40dc3b58a9df7409d77f · discourse/discourse · GitHub. It’s just creating an iframe element using this data:

<div id='discourse-comments'></div>
<meta name='discourse-username' content='DISCOURSE_USERNAME'>

<script type="text/javascript">
  DiscourseEmbed = {
    discourseUrl: 'http://127.0.0.1:4200/',
    discourseEmbedUrl: 'EMBED_URL',
    // className: 'CLASS_NAME',
  };
</script>

Edit: I had to give it a try. This is just a proof of concept: discourse-embed-iframe-test/app/routes/triggering-embed-code.tsx at main · scossar/discourse-embed-iframe-test · GitHub. I don’t think it’s a great solution for your problem.

The logic is entirely on the client, (the loader function’s just for convenience). Unfortunately there isn’t a great way for the client to know if the topic exists on Discourse. So it’s not possible to customize the UI based on whether or not the topic already exists. There are ways that could be solved, but would probably require writing something to the app’s database.

Discourse is using Window: postMessage() to pass data from the iframe to the parent document. For example, when a reply link is clicked in the embedded comments: discourse/app/assets/javascripts/discourse/scripts/embed-application.js at 581dbca97f2b55c9bbbe40dc3b58a9df7409d77f · discourse/discourse · GitHub. I wonder if a message could be sent to the parent document to indicate that a topic had been created. That would let sites do thing like set custom loading spinners, or display different UI depending on whether or not the topic was ready to receive comments.

לייק 1

I don’t think that need be the case if it were possible to assign a primary link to a new post:

$discourse/new-topic-link?link=$link

Which would presumably forward to the thread if it already exists and use the existing logic in the embed admin. Maybe with templates?

I guess another way to solve this is to search for any posts that refer to the link in question and surface any matches as part of a site-wide conversation, rendering directly in the page via SSR. This might be equivalent given that the embeds are view only anyways. The most obvious issue there would be choosing which thread to send the user to when they want to participate.

edit: if I can figure out how to search posts by link content

I’m wondering whether this feature may be used to attack a Discourse forum. Specifically, is it possible for someone falsify visiting pages under multiple URLs of a host and creates many many topics?

Hello Discourse community!

I’m excited to share a plugin I’ve developed for those using Docusaurus v3 and wanting to embed Discourse comments on their sites.

docusaurus-plugin-discourse-comments

This plugin makes it easy to integrate Discourse comments into your Docusaurus v3 site. Here are some key features:

  • Seamless integration with Docusaurus v3
  • Configurable embed routes
  • Debug mode for easy troubleshooting
  • Automatic handling of embed URLs
  • Customizable placement of comments

If you’re using Docusaurus v3 and want to add Discourse comments to your documentation or blog posts, this plugin simplifies the process significantly.

You can find the plugin on npm: docusaurus-plugin-discourse-comments

4 לייקים

נניח שיש לי מארח יחיד הניתן להטמעה, blog.example.com ורשימת היתרים עם נתיב כללי, כמו /.*.

אני רוצה להוסיף הטמעה נוספת באמצעות אותו מארח, אבל הפעם עם רשימת היתרים שונה, לדוגמה /new-release.* ועם תגית נוספת, נניח releases.

ברור שנושא “הגרסה החדשה” יכול להתאים לשילובי מארח/נתיב, אבל לאיזה מהם תהיה עדיפות? באיזה סדר מוערכים הכללים?

האם עדיין אי אפשר להטמיע נושא מפורום פרטי על מארח נפרד? מקרה השימוש שלי הוא שאנו משתמשים ב-Kajabi לאירוח המוצר ומשתמשים ב-Discourse כפלטפורמת התגובות שלנו. כל אחד דורש התחברות נפרדת, אז אני חושד שהתשובה היא עדיין “לא אפשרי” אבל זה אחד הגורמים המגבילים עבור המשתמשים שלנו וכאב ראש גדול מכיוון שיש לנו למעלה מ-750 מודולים, שלכל אחד מהם יש מרחב דיון ייעודי. אם הייתי יכול להטמיע את נושא ה-Discourse עבור כל מודול Kajabi באותו עמוד, גם בלי יכולת להגיב בעמוד, זה היה מפשט הכל ומאפשר קישור קל לנושא הרלוונטי ב-Discourse.

אז, האם יש התקדמות בנושא זה או שזו תמיד תהיה מגבלה של פורומים פרטיים?

אני רואה שלא ניתן להטמיע תגובות מפורום פרטי (באתר המשתמש בדומיין נפרד):

[“quote”=“Discourse, post:1, topic:31963”]
עבור מופעי Discourse פרטיים, אם Discourse נמצא בתת-דומיין של דומיין הבלוג, תגובות יוצגו למשתמשים המחוברים ל-Discourse. משתמשים שאינם מחוברים ל-Discourse יראו הודעה של ‘סירב להתחבר’. אם Discourse והבלוג נמצאים בדומיינים נפרדים לחלוטין, לא יוצגו תגובות לפורומים פרטיים.
[/quote]

מה שקולגה משתמש בו לתגובות באתר Ghost הוא פורום ציבורי (בדומיין שונה לחלוטין), המפרסם בעיקר פוסטים חינמיים. הוא פרסם לאחרונה את הפוסט הראשון שלו המיועד למנויים בלבד, וכאשר החלפתי את הנושא המשויך אליו ב-Discourse לקטגוריה שאינה ניתנת לצפייה על ידי “כולם” אלא לקבוצה מסוימת (המשויכת למשלמים באתר Ghost), ההטמעה מציגה כעת את ההודעה “שגיאת הטמעה”.

למרות שהכותב המקורי (OP) אמר שפורומים פרטיים (בדומיינים נפרדים) לא יאפשרו להטמעה לעבוד, זהו פורום ציבורי אך עם קטגוריה פרטית. האם הבעיה שאני רואה נובעת מכך שקטגוריה פרטית בפורום ציבורי זהה מבחינה פונקציונלית לפורום פרטי? הרי קראתי את ההערה הבאה, שנראית כתומכת בטענה זו:

[“quote”=“simon, post:448, topic:31963”]
כל עוד אינך מטמיע את הנושאים בקטגוריית Discourse פרטית, העובדה שהבלוג נמצא בדומיין שונה מ-Discourse לא אמורה לגרום לבעיה.
[/quote]

אם אכן נושאים מקטגוריות פרטיות בפורומים ציבוריים אינם ניתנים להטמעה כפי שהם, האם יש דרך לעשות זאת באמצעות התאמה כלשהי של ההטמעה (ו/או הפלטפורמה)? אין לי דחיפות גדולה ל"תקן" (בתקווה) את הבעיה הזו, מכיוון שאני בסדר יחסית עם הגדרת הקטגוריה הפרטית לציבורית באופן זמני (מכיוון ש-Discourse אינו יכול לגשת לנתוני הפוסט הפרטי של Ghost ובכך להציג בטעות את תוכנו למשתמשים שאינם משלמים ב-Discourse), אך אם ניתן לגרום לכך לעבוד, לא אכפת לי לשכור מישהו במועד מאוחר יותר כדי לתקן את ההטמעה ו/או להגיש PR לפלטפורמה.

Hi, I am using the embed functionality with my Ghost blog, however I am running into some issues in where the blog posts ends up on my forum. I have the below hosts setup:

Due to challenges with the subdomain setup (I have my domain with a different ISP to where I have my Discourse forum) I decided to go the Tag route.

The issue I run into is that all my blog posts end up in the Blog category on my Discourse forum. I am using an admin user for the post author on Discourse, all 3 categories allow admins to create new topics.

Any insight in what might be causing this?

אולי כדאי לציין את הנתיבים עבור כל אחד? לדוגמה, אם פוסטים שאמורים להיכנס לקטגוריית הבלוג נמצאים תחת /blog/<slug>, אני זוכר שאתה יכול לעשות /blog/*.

לייק 1

That doesn’t work with Ghost blog (at least not with a fairly standard installation). I am using my main domain (alphagamer.net), Ghost blog basically adds the path automatically based on the blog post title after the domain. I tried adding a path but it just removes it.

לייק 1

תהיתי אם ניתן להטמיע הערות דיון (נושא) בנושא דיון? אולי עם Iframe הכולל כפתור תגובה אך לא את שאר האתר. כלומר, ללא כותרת או כותרת תחתונה.

השתמשתי בו עם Ghost ללא בעיות מלבד היעדר אינטגרציית SSO, מה שגורם למשתמשים להתעצבן.

אני זוכר שהייתי צריך לשנות מעט את קוד הדוגמה.

I think it works fine if you have 1 embed, I think if you are trying to embed different types of blog posts in different Discourse categories it will require a bit more tweaking.

I thought I could make it work using the Tags, but tags alone doesn’t seem to do it (for my setup). I believe on Ghost I will need to make Content Collections which basically allow me to add a folder structure (like alphagamer.net/blog/ and the others that I need). I will try this over the weekend, update my “path allowlist” and post here if I am able to get this to work.

Can the allowlist be comma-separated like this?

/blog/.*,/articles/.*

Edit: it seems like that doesn’t work. This doesn’t either:

/(blog|articles)/.* 

Maybe they need to be two separate hosts?